From e3a5704ea90511057a061d41919760d0fd14b07b Mon Sep 17 00:00:00 2001 From: Justin Laughlin Date: Tue, 9 Jul 2024 14:18:31 -0700 Subject: [PATCH 01/35] implement general NumberFormat() function --- lib/aux_vis.cpp | 26 ++++++++++++++++++++++++++ lib/aux_vis.hpp | 1 + lib/vsdata.cpp | 27 ++++++++++++++------------- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 3660bafd..39d31ebe 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -1783,3 +1783,29 @@ void SetFont(const std::string& fn) << "', height = " << font_size << endl; #endif } + +string FormatNumber(double x, char format, int precision) { + ostringstream oss; + switch (format) { + case 'f': + oss << fixed; + break; + case 's': + oss << scientific; + break; + case 'h': + oss << hexfloat; + break; + case 'd': + oss << defaultfloat; + break; + default: + MFEM_WARNING("Unknown formatting type. Using default. " + << "Valid options include: ['f', 's', 'h', 'd']" << endl); + oss << defaultfloat; + break; + }; + oss << setprecision(precision) << x; + return oss.str(); +} + diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index 97d03ccf..efe89a2f 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -136,5 +136,6 @@ bool SetFont(const vector& patterns, int height); void SetFont(const std::string& fn); void SetUseHiDPI(bool status); +std::string FormatNumber(double x, char format='d', int precision=4); #endif diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index 1934414f..ffced31a 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -496,9 +496,8 @@ void VisualizationSceneScalarData::PrepareColorBar (double minval, val = ULogVal(i / 4.0); - ostringstream buf; - buf << setprecision(4) << val; - color_bar.addText(text_x,Y,posz, buf.str()); + string valstr = FormatNumber(val); + color_bar.addText(text_x,Y,posz, valstr); } } else @@ -508,9 +507,8 @@ void VisualizationSceneScalarData::PrepareColorBar (double minval, val = (*mesh_level)[i]; Y = miny + (maxy - miny) * LogUVal(val); - ostringstream buf; - buf << setprecision(4) << val; - color_bar.addText(text_x,Y,posz, buf.str()); + string valstr = FormatNumber(val); + color_bar.addText(text_x,Y,posz, valstr); } } @@ -521,9 +519,8 @@ void VisualizationSceneScalarData::PrepareColorBar (double minval, val = (*lsurf_levels)[i]; Y = miny + (maxy - miny) * LogUVal(val); - ostringstream buf; - buf << setprecision(4) << val; - color_bar.addText(text_x,Y,posz, buf.str()); + string valstr = FormatNumber(val); + color_bar.addText(text_x,Y,posz, valstr); } } updated_bufs.emplace_back(&color_bar); @@ -1513,13 +1510,17 @@ void VisualizationSceneScalarData::PrepareAxes() int ox = -desc/2; int oy = -3*desc/2; ostringstream buf; - buf << setprecision(4) - << "(" << bb.x[0] << "," << bb.y[0] << "," << bb.z[0] << ")" ; + buf << "(" + << FormatNumber(bb.x[0]) << "," + << FormatNumber(bb.y[0]) << "," + << FormatNumber(bb.z[0]) << ")"; axes_buf.addText(bb.x[0], bb.y[0], bb.z[0], ox, oy, buf.str()); ostringstream buf1; - buf1 << setprecision(4) - << "(" << bb.x[1] << "," << bb.y[1] << "," << bb.z[1] << ")" ; + buf1 << "(" + << FormatNumber(bb.x[1]) << "," + << FormatNumber(bb.y[1]) << "," + << FormatNumber(bb.z[1]) << ")"; axes_buf.addText(bb.x[1], bb.y[1], bb.z[1], ox, oy, buf1.str()); } updated_bufs.emplace_back(&axes_buf); From 76eb7a7d83a885c2bb4b2a4e51ef792d13f7be96 Mon Sep 17 00:00:00 2001 From: Justin Laughlin Date: Tue, 9 Jul 2024 14:29:12 -0700 Subject: [PATCH 02/35] add option to show sign (showpos) --- lib/aux_vis.cpp | 5 ++++- lib/aux_vis.hpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 39d31ebe..763853a5 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -1784,7 +1784,7 @@ void SetFont(const std::string& fn) #endif } -string FormatNumber(double x, char format, int precision) { +string FormatNumber(double x, char format, int precision, bool showsign) { ostringstream oss; switch (format) { case 'f': @@ -1805,6 +1805,9 @@ string FormatNumber(double x, char format, int precision) { oss << defaultfloat; break; }; + if (showsign){ + oss << showpos; + } oss << setprecision(precision) << x; return oss.str(); } diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index efe89a2f..c540aba2 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -136,6 +136,6 @@ bool SetFont(const vector& patterns, int height); void SetFont(const std::string& fn); void SetUseHiDPI(bool status); -std::string FormatNumber(double x, char format='d', int precision=4); +std::string FormatNumber(double x, char format='d', int precision=4, bool showsign=false); #endif From 1573db5337af7a77281b88495ae3988402342ff8 Mon Sep 17 00:00:00 2001 From: Justin Laughlin Date: Tue, 9 Jul 2024 14:36:22 -0700 Subject: [PATCH 03/35] begin implementing F2 to change number format --- lib/aux_vis.cpp | 6 ++++++ lib/vsdata.cpp | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 763853a5..000137f4 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -219,6 +219,9 @@ void SendKeySequence(const char *seq) case 'd': // down arrow wnd->signalKeyDown(SDLK_DOWN); break; + case '2': // F2 + wnd->signalKeyDown(SDLK_F2); + break; case '3': // F3 wnd->signalKeyDown(SDLK_F3); break; @@ -278,6 +281,9 @@ void CallKeySequence(const char *seq) case 'd': // down arrow wnd->callKeyDown(SDLK_DOWN); break; + case '2': // F2 + wnd->callKeyDown(SDLK_F2); + break; case '3': // F3 wnd->callKeyDown(SDLK_F3); break; diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index ffced31a..b513ec1e 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -651,6 +651,19 @@ void KeyPPressed() SendExposeEvent(); } +static void KeyF2Pressed() +{ + char location; + char format; + int precision; + bool showsign; + + cout << "Setting number format..."; + cout << "Where to set ['a'=axes, 'c'=colorbar] : "; + cout << "Enter precision : "; + cout << "Enter format ['d'=default, 'f'=fixed, 's'=scientific]: "; +} + static void KeyF5Pressed() { int n; @@ -1302,6 +1315,7 @@ void VisualizationSceneScalarData::Init() wnd->setOnKeyDown('h', KeyHPressed); wnd->setOnKeyDown('H', KeyHPressed); + wnd->setOnKeyDown(SDLK_F2, KeyF2Pressed); wnd->setOnKeyDown(SDLK_F5, KeyF5Pressed); wnd->setOnKeyDown(SDLK_F6, KeyF6Pressed); wnd->setOnKeyDown(SDLK_F7, KeyF7Pressed); From b1bd9d1ddc4a717ddbc3fdb41ad9ca85066fed7a Mon Sep 17 00:00:00 2001 From: Justin Laughlin Date: Tue, 9 Jul 2024 14:36:43 -0700 Subject: [PATCH 04/35] remove h option --- lib/aux_vis.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 000137f4..95d32e02 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -1799,15 +1799,12 @@ string FormatNumber(double x, char format, int precision, bool showsign) { case 's': oss << scientific; break; - case 'h': - oss << hexfloat; - break; case 'd': oss << defaultfloat; break; default: MFEM_WARNING("Unknown formatting type. Using default. " - << "Valid options include: ['f', 's', 'h', 'd']" << endl); + << "Valid options include: ['f', 's', 'd']" << endl); oss << defaultfloat; break; }; From 359cc4534537dcf5e9850d59437644507464101a Mon Sep 17 00:00:00 2001 From: Justin Laughlin Date: Tue, 9 Jul 2024 14:37:14 -0700 Subject: [PATCH 05/35] swap order of args in NumberFormat() --- lib/aux_vis.cpp | 2 +- lib/aux_vis.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 95d32e02..6ef56a2f 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -1790,7 +1790,7 @@ void SetFont(const std::string& fn) #endif } -string FormatNumber(double x, char format, int precision, bool showsign) { +string FormatNumber(double x, int precision, char format, bool showsign) { ostringstream oss; switch (format) { case 'f': diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index c540aba2..89b5e757 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -136,6 +136,6 @@ bool SetFont(const vector& patterns, int height); void SetFont(const std::string& fn); void SetUseHiDPI(bool status); -std::string FormatNumber(double x, char format='d', int precision=4, bool showsign=false); +std::string FormatNumber(double x, int precision=4, char format='d', bool showsign=false); #endif From 30b5f812ea52fc2ee2fd6a4b13ada294febf9733 Mon Sep 17 00:00:00 2001 From: Justin Laughlin Date: Tue, 9 Jul 2024 15:23:10 -0700 Subject: [PATCH 06/35] add prompt() function and also reverting F2 changes --- lib/aux_vis.cpp | 34 ++++++++++++++++++++++++++++------ lib/aux_vis.hpp | 3 +++ lib/vsdata.cpp | 29 +++++++++++++++++------------ 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 6ef56a2f..2e9d9886 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -219,9 +219,6 @@ void SendKeySequence(const char *seq) case 'd': // down arrow wnd->signalKeyDown(SDLK_DOWN); break; - case '2': // F2 - wnd->signalKeyDown(SDLK_F2); - break; case '3': // F3 wnd->signalKeyDown(SDLK_F3); break; @@ -281,9 +278,6 @@ void CallKeySequence(const char *seq) case 'd': // down arrow wnd->callKeyDown(SDLK_DOWN); break; - case '2': // F2 - wnd->callKeyDown(SDLK_F2); - break; case '3': // F3 wnd->callKeyDown(SDLK_F3); break; @@ -1815,3 +1809,31 @@ string FormatNumber(double x, int precision, char format, bool showsign) { return oss.str(); } +// This is a helper function for prompting the user for inputs. The benefit +// over using just `cin >> input` is that you can specify a type and optionally +// a validator lambda. The a validator if not specified, it defaults to the +// True function. If the input cannot be type casted to the expected type, or +// if it fails the validation, the user is asked again for a new input. +template +T prompt(const string question, function validator){ + T input; + string strInput; + + while (true) { + cout << question << endl; + getline(cin, strInput); + stringstream buf(strInput); + + if (buf >> input) { + if (validator(input)) { + break; + } else { + cout << "Input is not valid. Please try again." << endl; + } + } else { + cout << "Input can not be casted to expected type. Please try again." << endl; + } + } + return input; +} + diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index 89b5e757..5952facf 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -138,4 +138,7 @@ void SetFont(const std::string& fn); void SetUseHiDPI(bool status); std::string FormatNumber(double x, int precision=4, char format='d', bool showsign=false); +template +T prompt(const string question, function validator=[](T) { return true; }); + #endif diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index b513ec1e..502ff648 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -651,18 +651,24 @@ void KeyPPressed() SendExposeEvent(); } -static void KeyF2Pressed() -{ - char location; - char format; - int precision; - bool showsign; - cout << "Setting number format..."; - cout << "Where to set ['a'=axes, 'c'=colorbar] : "; - cout << "Enter precision : "; - cout << "Enter format ['d'=default, 'f'=fixed, 's'=scientific]: "; -} +// static void KeyF2Pressed() +// { +// char location; +// int precision; +// char format; +// bool showsign; + +// cout << "Setting number format..."; +// cout << "Where to set ['a'=axes, 'c'=colorbar] : " << flush; +// cin >> location; +// cout << "Enter precision : " << flush; +// cin >> precision; +// cout << "Enter format ['d'=default, 'f'=fixed, 's'=scientific] : " << flush; +// cin >> format; +// cout << "Show + sign? [1=true, 0=false] : << flush"; +// cin >> showsign; +// } static void KeyF5Pressed() { @@ -1315,7 +1321,6 @@ void VisualizationSceneScalarData::Init() wnd->setOnKeyDown('h', KeyHPressed); wnd->setOnKeyDown('H', KeyHPressed); - wnd->setOnKeyDown(SDLK_F2, KeyF2Pressed); wnd->setOnKeyDown(SDLK_F5, KeyF5Pressed); wnd->setOnKeyDown(SDLK_F6, KeyF6Pressed); wnd->setOnKeyDown(SDLK_F7, KeyF7Pressed); From 458114a4c1679c6a5bc3c750d6786a719d24f302 Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Wed, 10 Jul 2024 13:59:59 -0700 Subject: [PATCH 07/35] seems to be working --- lib/aux_vis.cpp | 28 ------------- lib/aux_vis.hpp | 27 ++++++++++++- lib/vsdata.cpp | 102 ++++++++++++++++++++++++++++++++---------------- lib/vsdata.hpp | 12 ++++++ 4 files changed, 106 insertions(+), 63 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 2e9d9886..62503b09 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -1809,31 +1809,3 @@ string FormatNumber(double x, int precision, char format, bool showsign) { return oss.str(); } -// This is a helper function for prompting the user for inputs. The benefit -// over using just `cin >> input` is that you can specify a type and optionally -// a validator lambda. The a validator if not specified, it defaults to the -// True function. If the input cannot be type casted to the expected type, or -// if it fails the validation, the user is asked again for a new input. -template -T prompt(const string question, function validator){ - T input; - string strInput; - - while (true) { - cout << question << endl; - getline(cin, strInput); - stringstream buf(strInput); - - if (buf >> input) { - if (validator(input)) { - break; - } else { - cout << "Input is not valid. Please try again." << endl; - } - } else { - cout << "Input can not be casted to expected type. Please try again." << endl; - } - } - return input; -} - diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index 5952facf..c6fd2f6d 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -138,7 +138,32 @@ void SetFont(const std::string& fn); void SetUseHiDPI(bool status); std::string FormatNumber(double x, int precision=4, char format='d', bool showsign=false); +// This is a helper function for prompting the user for inputs. The benefit +// over using just `cin >> input` is that you can specify a type and optionally +// a validator lambda. The a validator if not specified, it defaults to the +// True function. If the input cannot be type casted to the expected type, or +// if it fails the validation, the user is asked again for a new input. template -T prompt(const string question, function validator=[](T) { return true; }); +T prompt(const string question, function validator=[](T) { return true; }) { + T input; + string strInput; + + while (true) { + cout << question << endl; + getline(cin, strInput); + stringstream buf(strInput); + + if (buf >> input) { + if (validator(input)) { + break; + } else { + cout << "Input is not valid. Please try again." << endl; + } + } else { + cout << "Input can not be casted to expected type. Please try again." << endl; + } + } + return input; +} #endif diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index 502ff648..b524a689 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -414,6 +414,17 @@ void VisualizationSceneScalarData::Arrow(gl3::GlDrawable& buf, } } +void VisualizationSceneScalarData::SetColorbarNumberFormat(int precision, + char format, + bool showsign) +{ + colorbar_precision = precision; + colorbar_format = format; + colorbar_showsign = showsign; + // The first two arguments are required but I don't think they are used? + PrepareColorBar(0,0); +} + void VisualizationSceneScalarData::PrepareColorBar (double minval, double maxval, Array *mesh_level, @@ -496,8 +507,11 @@ void VisualizationSceneScalarData::PrepareColorBar (double minval, val = ULogVal(i / 4.0); - string valstr = FormatNumber(val); - color_bar.addText(text_x,Y,posz, valstr); + string valstr = FormatNumber(val, + colorbar_precision, + colorbar_format, + colorbar_showsign); + color_bar.addText(text_x,Y,posz,valstr); } } else @@ -507,8 +521,11 @@ void VisualizationSceneScalarData::PrepareColorBar (double minval, val = (*mesh_level)[i]; Y = miny + (maxy - miny) * LogUVal(val); - string valstr = FormatNumber(val); - color_bar.addText(text_x,Y,posz, valstr); + string valstr = FormatNumber(val, + colorbar_precision, + colorbar_format, + colorbar_showsign); + color_bar.addText(text_x,Y,posz,valstr); } } @@ -519,8 +536,11 @@ void VisualizationSceneScalarData::PrepareColorBar (double minval, val = (*lsurf_levels)[i]; Y = miny + (maxy - miny) * LogUVal(val); - string valstr = FormatNumber(val); - color_bar.addText(text_x,Y,posz, valstr); + string valstr = FormatNumber(val, + colorbar_precision, + colorbar_format, + colorbar_showsign); + color_bar.addText(text_x,Y,posz,valstr); } } updated_bufs.emplace_back(&color_bar); @@ -547,10 +567,23 @@ void VisualizationSceneScalarData::PrepareCaption() thread_local VisualizationSceneScalarData * vsdata; extern thread_local VisualizationScene * locscene; -void KeycPressed() +void KeycPressed(GLenum state) { - vsdata->ToggleDrawColorbar(); - SendExposeEvent(); + if (state & KMOD_ALT) + { + cout << "Setting colorbar number formatting..." << endl; + int precision = prompt("Enter precision : "); + char format = prompt("Enter format ['d'=default, 'f'=fixed, 's'=scientific] : ", + [](char c){ return c=='d' || c=='f' || c=='s'; }); + bool showsign = prompt("Show sign? [1=true, 0=false] : "); + vsdata->SetColorbarNumberFormat(precision, format, showsign); + SendExposeEvent(); + } + else + { + vsdata->ToggleDrawColorbar(); + SendExposeEvent(); + } } void KeyCPressed() @@ -585,6 +618,16 @@ void Key_Mod_a_Pressed(GLenum state) cout << autoscale_modes[autoscale] << endl; SendExposeEvent(); } + else if (state & KMOD_ALT) + { + cout << "Setting axes number formatting..." << endl; + int precision = prompt("Enter precision : "); + char format = prompt("Enter format ['d'=default, 'f'=fixed, 's'=scientific] : ", + [](char c){ return c=='d' || c=='f' || c=='s'; }); + bool showsign = prompt("Show sign? [1=true, 0=false] : "); + vsdata->SetAxisNumberFormat(precision, format, showsign); + SendExposeEvent(); + } else { vsdata->ToggleDrawAxes(); @@ -651,25 +694,6 @@ void KeyPPressed() SendExposeEvent(); } - -// static void KeyF2Pressed() -// { -// char location; -// int precision; -// char format; -// bool showsign; - -// cout << "Setting number format..."; -// cout << "Where to set ['a'=axes, 'c'=colorbar] : " << flush; -// cin >> location; -// cout << "Enter precision : " << flush; -// cin >> precision; -// cout << "Enter format ['d'=default, 'f'=fixed, 's'=scientific] : " << flush; -// cin >> format; -// cout << "Show + sign? [1=true, 0=false] : << flush"; -// cin >> showsign; -// } - static void KeyF5Pressed() { int n; @@ -1441,6 +1465,16 @@ void VisualizationSceneScalarData::SetAxisLabels(const char * a_x, PrepareAxes(); } +void VisualizationSceneScalarData::SetAxisNumberFormat(int precision, + char format, + bool showsign) +{ + axes_precision = precision; + axes_format = format; + axes_showsign = showsign; + PrepareAxes(); +} + void VisualizationSceneScalarData::PrepareAxes() { // std::array blk = GetLineColor(); @@ -1530,16 +1564,16 @@ void VisualizationSceneScalarData::PrepareAxes() int oy = -3*desc/2; ostringstream buf; buf << "(" - << FormatNumber(bb.x[0]) << "," - << FormatNumber(bb.y[0]) << "," - << FormatNumber(bb.z[0]) << ")"; + << FormatNumber(bb.x[0], axes_precision, axes_format, axes_showsign) << "," + << FormatNumber(bb.y[0], axes_precision, axes_format, axes_showsign) << "," + << FormatNumber(bb.z[0], axes_precision, axes_format, axes_showsign) << ")"; axes_buf.addText(bb.x[0], bb.y[0], bb.z[0], ox, oy, buf.str()); ostringstream buf1; buf1 << "(" - << FormatNumber(bb.x[1]) << "," - << FormatNumber(bb.y[1]) << "," - << FormatNumber(bb.z[1]) << ")"; + << FormatNumber(bb.x[1], axes_precision, axes_format, axes_showsign) << "," + << FormatNumber(bb.y[1], axes_precision, axes_format, axes_showsign) << "," + << FormatNumber(bb.z[1], axes_precision, axes_format, axes_showsign) << ")"; axes_buf.addText(bb.x[1], bb.y[1], bb.z[1], ox, oy, buf1.str()); } updated_bufs.emplace_back(&axes_buf); diff --git a/lib/vsdata.hpp b/lib/vsdata.hpp index d08fedd6..b1acacd3 100644 --- a/lib/vsdata.hpp +++ b/lib/vsdata.hpp @@ -65,6 +65,14 @@ class VisualizationSceneScalarData : public VisualizationScene int scaling, colorbar, drawaxes; int auto_ref_max, auto_ref_max_surf_elem; + // Formatting for axes & colorbar numbers + int axes_precision = 4; + int colorbar_precision = 4; + char axes_format = 'd'; + char colorbar_format = 'd'; + bool axes_showsign = false; + bool colorbar_showsign = false; + vector updated_bufs; gl3::GlDrawable axes_buf; gl3::GlDrawable coord_cross_buf; @@ -253,12 +261,16 @@ class VisualizationSceneScalarData : public VisualizationScene // Turn on or off the caption void PrepareCaption(); + void SetColorbarNumberFormat(int precision, char format, bool showsign); + void PrepareColorBar(double minval, double maxval, Array * level = NULL, Array * levels = NULL); void SetAxisLabels(const char * a_x, const char * a_y, const char * a_z); + void SetAxisNumberFormat(int precision, char format, bool showsign); + void PrepareAxes(); void ToggleDrawAxes() { From 8cb2e0fc3b0712c9edbba1192215232293141ce4 Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Wed, 10 Jul 2024 15:15:28 -0700 Subject: [PATCH 08/35] added ability to specify a default using prompt() --- lib/aux_vis.hpp | 13 ++++++++++--- lib/vsdata.cpp | 28 ++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index c6fd2f6d..582b3da5 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -144,18 +144,25 @@ std::string FormatNumber(double x, int precision=4, char format='d', bool showsi // True function. If the input cannot be type casted to the expected type, or // if it fails the validation, the user is asked again for a new input. template -T prompt(const string question, function validator=[](T) { return true; }) { +T prompt(const string question, + const T* default_value = nullptr, + function validator = [](T) { return true; }) +{ T input; string strInput; while (true) { - cout << question << endl; + cout << question << " "; getline(cin, strInput); stringstream buf(strInput); + if (strInput.empty() && default_value != nullptr) { + return *default_value; + } + if (buf >> input) { if (validator(input)) { - break; + return input; } else { cout << "Input is not valid. Please try again." << endl; } diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index b524a689..656df21a 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -572,10 +572,18 @@ void KeycPressed(GLenum state) if (state & KMOD_ALT) { cout << "Setting colorbar number formatting..." << endl; - int precision = prompt("Enter precision : "); - char format = prompt("Enter format ['d'=default, 'f'=fixed, 's'=scientific] : ", + int default_precision = 4; + char default_format = 'd'; + bool default_showsign = false; + + int precision = prompt("Enter precision (4): ", + &default_precision, + [](int p){ return p>=0; }); + char format = prompt("Enter format [(d)efault, (f)ixed, (s)cientific] (d): ", + &default_format, [](char c){ return c=='d' || c=='f' || c=='s'; }); - bool showsign = prompt("Show sign? [1=true, 0=false] : "); + bool showsign = prompt("Show sign? [(1)true, (0)false] (0): ", + &default_showsign); vsdata->SetColorbarNumberFormat(precision, format, showsign); SendExposeEvent(); } @@ -621,10 +629,18 @@ void Key_Mod_a_Pressed(GLenum state) else if (state & KMOD_ALT) { cout << "Setting axes number formatting..." << endl; - int precision = prompt("Enter precision : "); - char format = prompt("Enter format ['d'=default, 'f'=fixed, 's'=scientific] : ", + int default_precision = 4; + char default_format = 'd'; + bool default_showsign = false; + + int precision = prompt("Enter precision (4): ", + &default_precision, + [](int p){ return p>=0; }); + char format = prompt("Enter format [(d)efault, (f)ixed, (s)cientific] (d): ", + &default_format, [](char c){ return c=='d' || c=='f' || c=='s'; }); - bool showsign = prompt("Show sign? [1=true, 0=false] : "); + bool showsign = prompt("Show sign? [(1)true, (0)false] (0): ", + &default_showsign); vsdata->SetAxisNumberFormat(precision, format, showsign); SendExposeEvent(); } From 9f881b4e567e87bfa4522b8eed852344206488c8 Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Tue, 16 Jul 2024 16:23:20 -0700 Subject: [PATCH 09/35] add printf style option to FormatNumber --- lib/aux_vis.cpp | 5 +++++ lib/aux_vis.hpp | 1 + 2 files changed, 6 insertions(+) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 62503b09..b68d2900 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -1809,3 +1809,8 @@ string FormatNumber(double x, int precision, char format, bool showsign) { return oss.str(); } +string FormatNumber(double x, string formatting) { + char buf[64]; + snprintf(buf, sizeof(buf), formatting, x); + return string(buf); +} diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index 582b3da5..0e7e4ed7 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -137,6 +137,7 @@ void SetFont(const std::string& fn); void SetUseHiDPI(bool status); std::string FormatNumber(double x, int precision=4, char format='d', bool showsign=false); +std::string FormatNumber(double x, string formatting); // This is a helper function for prompting the user for inputs. The benefit // over using just `cin >> input` is that you can specify a type and optionally From 92687d92e889f860b1112fa019cecf0a0bb119ae Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Tue, 16 Jul 2024 17:02:09 -0700 Subject: [PATCH 10/35] make number formatter lazy so its easier to pass around --- lib/aux_vis.cpp | 54 ++++++++++++++++++++++++++----------------------- lib/aux_vis.hpp | 4 ++-- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index b68d2900..fafbc6d0 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -1784,33 +1784,37 @@ void SetFont(const std::string& fn) #endif } -string FormatNumber(double x, int precision, char format, bool showsign) { - ostringstream oss; - switch (format) { - case 'f': - oss << fixed; - break; - case 's': - oss << scientific; - break; - case 'd': - oss << defaultfloat; - break; - default: +function NumberFormatter(int precision, char format, bool showsign) { + return [precision, format, showsign](double x) -> string { + ostringstream oss; + switch (format) { + case 'f': + oss << fixed; + break; + case 's': + oss << scientific; + break; + case 'd': + oss << defaultfloat; + break; + default: MFEM_WARNING("Unknown formatting type. Using default. " << "Valid options include: ['f', 's', 'd']" << endl); oss << defaultfloat; break; - }; - if (showsign){ - oss << showpos; - } - oss << setprecision(precision) << x; - return oss.str(); -} - -string FormatNumber(double x, string formatting) { - char buf[64]; - snprintf(buf, sizeof(buf), formatting, x); - return string(buf); + }; + if (showsign){ + oss << showpos; + } + oss << setprecision(precision) << x; + return oss.str(); + }; +} + +function NumberFormatter(string formatting) { + return [formatting](double x) -> string { + char buf[64]; + snprintf(buf, sizeof(buf), formatting, x); + return string(buf); + } } diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index 0e7e4ed7..b2b65f4b 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -136,8 +136,8 @@ bool SetFont(const vector& patterns, int height); void SetFont(const std::string& fn); void SetUseHiDPI(bool status); -std::string FormatNumber(double x, int precision=4, char format='d', bool showsign=false); -std::string FormatNumber(double x, string formatting); +function NumberFormatter(int precision=4, char format='d', bool showsign=false); +function NumberFormatter(string formatting); // This is a helper function for prompting the user for inputs. The benefit // over using just `cin >> input` is that you can specify a type and optionally From 73b4bb69f3e5283241358b5275d7bd477fa98a5a Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Tue, 16 Jul 2024 17:15:21 -0700 Subject: [PATCH 11/35] change vsdata to use updated NumberFormatter --- lib/vsdata.cpp | 50 +++++++++++++++++++++++--------------------------- lib/vsdata.hpp | 12 +++++------- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index 656df21a..99ab3947 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -418,9 +418,13 @@ void VisualizationSceneScalarData::SetColorbarNumberFormat(int precision, char format, bool showsign) { - colorbar_precision = precision; - colorbar_format = format; - colorbar_showsign = showsign; + colorbar_formatter = NumberFormatter(precision, format, showsign) + // The first two arguments are required but I don't think they are used? + PrepareColorBar(0,0); +} +void VisualizationSceneScalarData::SetColorbarNumberFormat(string formatting) +{ + colorbar_formatter = NumberFormatter(formatting) // The first two arguments are required but I don't think they are used? PrepareColorBar(0,0); } @@ -507,11 +511,7 @@ void VisualizationSceneScalarData::PrepareColorBar (double minval, val = ULogVal(i / 4.0); - string valstr = FormatNumber(val, - colorbar_precision, - colorbar_format, - colorbar_showsign); - color_bar.addText(text_x,Y,posz,valstr); + color_bar.addText(text_x,Y,posz,colorbar_formatter(val)); } } else @@ -521,11 +521,7 @@ void VisualizationSceneScalarData::PrepareColorBar (double minval, val = (*mesh_level)[i]; Y = miny + (maxy - miny) * LogUVal(val); - string valstr = FormatNumber(val, - colorbar_precision, - colorbar_format, - colorbar_showsign); - color_bar.addText(text_x,Y,posz,valstr); + color_bar.addText(text_x,Y,posz,colorbar_formatter(val)); } } @@ -536,11 +532,7 @@ void VisualizationSceneScalarData::PrepareColorBar (double minval, val = (*lsurf_levels)[i]; Y = miny + (maxy - miny) * LogUVal(val); - string valstr = FormatNumber(val, - colorbar_precision, - colorbar_format, - colorbar_showsign); - color_bar.addText(text_x,Y,posz,valstr); + color_bar.addText(text_x,Y,posz,colorbar_formatter(val)); } } updated_bufs.emplace_back(&color_bar); @@ -1485,9 +1477,13 @@ void VisualizationSceneScalarData::SetAxisNumberFormat(int precision, char format, bool showsign) { - axes_precision = precision; - axes_format = format; - axes_showsign = showsign; + axis_formatter = NumberFormatter(precision, format, showsign) + PrepareAxes(); +} + +void VisualizationSceneScalarData::SetAxisNumberFormat(string formatting) +{ + axis_formatter = NumberFormatter(formatting) PrepareAxes(); } @@ -1580,16 +1576,16 @@ void VisualizationSceneScalarData::PrepareAxes() int oy = -3*desc/2; ostringstream buf; buf << "(" - << FormatNumber(bb.x[0], axes_precision, axes_format, axes_showsign) << "," - << FormatNumber(bb.y[0], axes_precision, axes_format, axes_showsign) << "," - << FormatNumber(bb.z[0], axes_precision, axes_format, axes_showsign) << ")"; + << axis_formatter(bb.x[0]) << "," + << axis_formatter(bb.y[0]) << "," + << axis_formatter(bb.z[0]) << ")"; axes_buf.addText(bb.x[0], bb.y[0], bb.z[0], ox, oy, buf.str()); ostringstream buf1; buf1 << "(" - << FormatNumber(bb.x[1], axes_precision, axes_format, axes_showsign) << "," - << FormatNumber(bb.y[1], axes_precision, axes_format, axes_showsign) << "," - << FormatNumber(bb.z[1], axes_precision, axes_format, axes_showsign) << ")"; + << axis_formatter(bb.x[1]) << "," + << axis_formatter(bb.y[1]) << "," + << axis_formatter(bb.z[1]) << ")"; axes_buf.addText(bb.x[1], bb.y[1], bb.z[1], ox, oy, buf1.str()); } updated_bufs.emplace_back(&axes_buf); diff --git a/lib/vsdata.hpp b/lib/vsdata.hpp index b1acacd3..aed2ed3e 100644 --- a/lib/vsdata.hpp +++ b/lib/vsdata.hpp @@ -65,13 +65,9 @@ class VisualizationSceneScalarData : public VisualizationScene int scaling, colorbar, drawaxes; int auto_ref_max, auto_ref_max_surf_elem; - // Formatting for axes & colorbar numbers - int axes_precision = 4; - int colorbar_precision = 4; - char axes_format = 'd'; - char colorbar_format = 'd'; - bool axes_showsign = false; - bool colorbar_showsign = false; + // Formatter for axes & colorbar numbers + function axis_formatter; + function colorbar_formatter; vector updated_bufs; gl3::GlDrawable axes_buf; @@ -262,6 +258,7 @@ class VisualizationSceneScalarData : public VisualizationScene void PrepareCaption(); void SetColorbarNumberFormat(int precision, char format, bool showsign); + void SetColorbarNumberFormat(string formatting); void PrepareColorBar(double minval, double maxval, Array * level = NULL, @@ -270,6 +267,7 @@ class VisualizationSceneScalarData : public VisualizationScene void SetAxisLabels(const char * a_x, const char * a_y, const char * a_z); void SetAxisNumberFormat(int precision, char format, bool showsign); + void SetAxisNumberFormat(string formatting); void PrepareAxes(); void ToggleDrawAxes() From 84cdf08ad3e8378890bdefe2a74ac1ab539bb64d Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Tue, 16 Jul 2024 17:16:11 -0700 Subject: [PATCH 12/35] forgot semicolon --- lib/aux_vis.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index fafbc6d0..fbe8377d 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -1816,5 +1816,5 @@ function NumberFormatter(string formatting) { char buf[64]; snprintf(buf, sizeof(buf), formatting, x); return string(buf); - } + }; } From 00cd71da6dbf2922ba2a6c9f437833e70a043aee Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Tue, 16 Jul 2024 17:18:11 -0700 Subject: [PATCH 13/35] fix few more bugs --- lib/aux_vis.cpp | 2 +- lib/vsdata.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index fbe8377d..dbf20a3e 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -1814,7 +1814,7 @@ function NumberFormatter(int precision, char format, bool showsi function NumberFormatter(string formatting) { return [formatting](double x) -> string { char buf[64]; - snprintf(buf, sizeof(buf), formatting, x); + snprintf(buf, sizeof(buf), formatting.c_str(), x); return string(buf); }; } diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index 99ab3947..77251264 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -418,13 +418,13 @@ void VisualizationSceneScalarData::SetColorbarNumberFormat(int precision, char format, bool showsign) { - colorbar_formatter = NumberFormatter(precision, format, showsign) + colorbar_formatter = NumberFormatter(precision, format, showsign); // The first two arguments are required but I don't think they are used? PrepareColorBar(0,0); } void VisualizationSceneScalarData::SetColorbarNumberFormat(string formatting) { - colorbar_formatter = NumberFormatter(formatting) + colorbar_formatter = NumberFormatter(formatting); // The first two arguments are required but I don't think they are used? PrepareColorBar(0,0); } @@ -1477,13 +1477,13 @@ void VisualizationSceneScalarData::SetAxisNumberFormat(int precision, char format, bool showsign) { - axis_formatter = NumberFormatter(precision, format, showsign) + axis_formatter = NumberFormatter(precision, format, showsign); PrepareAxes(); } void VisualizationSceneScalarData::SetAxisNumberFormat(string formatting) { - axis_formatter = NumberFormatter(formatting) + axis_formatter = NumberFormatter(formatting); PrepareAxes(); } From dd9c4d4f7a50f61265649b4dd99609a7d1b1d396 Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Tue, 16 Jul 2024 17:30:29 -0700 Subject: [PATCH 14/35] add default formatter --- lib/vsdata.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/vsdata.hpp b/lib/vsdata.hpp index aed2ed3e..8a2f65c9 100644 --- a/lib/vsdata.hpp +++ b/lib/vsdata.hpp @@ -16,6 +16,7 @@ #include "mfem.hpp" #include "openglvis.hpp" +#include "aux_vis.hpp" using namespace mfem; @@ -65,9 +66,9 @@ class VisualizationSceneScalarData : public VisualizationScene int scaling, colorbar, drawaxes; int auto_ref_max, auto_ref_max_surf_elem; - // Formatter for axes & colorbar numbers - function axis_formatter; - function colorbar_formatter; + // Formatter for axes & colorbar numbers. Set defaults. + function axis_formatter = NumberFormatter(4, 'd', false); + function colorbar_formatter = NumberFormatter(4, 'd', false); vector updated_bufs; gl3::GlDrawable axes_buf; From 039c97803035d80d4edf7b4d6196281b139daea4 Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Tue, 16 Jul 2024 17:40:04 -0700 Subject: [PATCH 15/35] stream is working for axis number format --- lib/threads.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ lib/threads.hpp | 8 +++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/lib/threads.cpp b/lib/threads.cpp index bf3c128c..934b8494 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -207,6 +207,22 @@ int GLVisCommand::AxisLabels(const char *a_x, const char *a_y, const char *a_z) return 0; } +int GLVisCommand::AxisNumberFormat(string formatting) +{ + if (lock() < 0) + { + return -1; + } + command = AXIS_NUMBERFORMAT; + axis_formatting = formatting; + if (signal() < 0) + { + return -2; + } + return 0; +} + + int GLVisCommand::Pause() { if (lock() < 0) @@ -511,6 +527,14 @@ int GLVisCommand::Execute() break; } + case AXIS_NUMBERFORMAT: + { + cout << "Command: axis_numberformat: '" << axis_formatting << endl; + (*vs)->SetAxisNumberFormat(axis_formatting); + MyExpose(); + break; + } + case PAUSE: { cout << "Command: pause: "; @@ -1111,6 +1135,29 @@ void communication_thread::execute() goto comm_terminate; } } + else if (ident == "axis_numberformat") + { + char c; + string formatting; + + *is[0] >> ws >> c; // read the opening char + getline(*is[0], formatting, c); // read formatting string + *is[0] >> ws >> c; // use the opening char as termination as well + + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'axis_numberformat' + *is[i] >> ws >> c; + getline(*is[i], ident, c); + *is[i] >> ws >> c; + } + + if (glvis_command->AxisNumberFormat(formatting)) + { + goto comm_terminate; + } + } else if (ident == "shading") { string shd; diff --git a/lib/threads.hpp b/lib/threads.hpp index 804ef7e8..06273ff3 100644 --- a/lib/threads.hpp +++ b/lib/threads.hpp @@ -57,7 +57,9 @@ class GLVisCommand PLOT_CAPTION = 18, AXIS_LABELS = 19, PALETTE_REPEAT = 20, - LEVELLINES = 21 + LEVELLINES = 21, + AXIS_NUMBERFORMAT = 22, + COLORBAR_NUMBERFORMAT = 23 }; std::atomic command_ready{false}; @@ -88,6 +90,8 @@ class GLVisCommand int lvl_num; double camera[9]; std::string autopause_mode; + std::string axis_formatting; + std::string colorbar_formatting; // internal variables int autopause; @@ -126,6 +130,8 @@ class GLVisCommand int Palette(int pal); int PaletteRepeat(int n); int Levellines(double minv, double maxv, int number); + int AxisNumberFormat(string formatting); + int ColorbarNumberFormat(string formatting); int Camera(const double cam[]); int Autopause(const char *mode); From 23d49ca37b00b0e6e6267bf683ad1ed18e3582b7 Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Tue, 16 Jul 2024 17:58:34 -0700 Subject: [PATCH 16/35] stream is working for axis and colorbar now --- lib/threads.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/lib/threads.cpp b/lib/threads.cpp index 934b8494..ef94b588 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -222,6 +222,20 @@ int GLVisCommand::AxisNumberFormat(string formatting) return 0; } +int GLVisCommand::ColorbarNumberFormat(string formatting) +{ + if (lock() < 0) + { + return -1; + } + command = COLORBAR_NUMBERFORMAT; + colorbar_formatting = formatting; + if (signal() < 0) + { + return -2; + } + return 0; +} int GLVisCommand::Pause() { @@ -535,6 +549,14 @@ int GLVisCommand::Execute() break; } + case COLORBAR_NUMBERFORMAT: + { + cout << "Command: colorbar_numberformat: '" << colorbar_formatting << endl; + (*vs)->SetColorbarNumberFormat(colorbar_formatting); + MyExpose(); + break; + } + case PAUSE: { cout << "Command: pause: "; @@ -1141,8 +1163,7 @@ void communication_thread::execute() string formatting; *is[0] >> ws >> c; // read the opening char - getline(*is[0], formatting, c); // read formatting string - *is[0] >> ws >> c; // use the opening char as termination as well + getline(*is[0], formatting, c); // read formatting string & use c for termination // all processors sent the command for (size_t i = 1; i < is.size(); i++) @@ -1150,7 +1171,6 @@ void communication_thread::execute() *is[i] >> ws >> ident; // 'axis_numberformat' *is[i] >> ws >> c; getline(*is[i], ident, c); - *is[i] >> ws >> c; } if (glvis_command->AxisNumberFormat(formatting)) @@ -1158,6 +1178,27 @@ void communication_thread::execute() goto comm_terminate; } } + else if (ident == "colorbar_numberformat") + { + char c; + string formatting; + + *is[0] >> ws >> c; // read the opening char + getline(*is[0], formatting, c); // read formatting string & use c for termination + + // all processors sent the command + for (size_t i = 1; i < is.size(); i++) + { + *is[i] >> ws >> ident; // 'colorbar_numberformat' + *is[i] >> ws >> c; + getline(*is[i], ident, c); + } + + if (glvis_command->ColorbarNumberFormat(formatting)) + { + goto comm_terminate; + } + } else if (ident == "shading") { string shd; From fc96c6470f22939faa0a4a71204f111320b757c7 Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Tue, 16 Jul 2024 18:40:23 -0700 Subject: [PATCH 17/35] add in hooks to glvis script --- glvis.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/glvis.cpp b/glvis.cpp index c8c97d8e..f02a32c3 100644 --- a/glvis.cpp +++ b/glvis.cpp @@ -645,6 +645,28 @@ void ExecuteScriptCommand() cout << min << ' ' << max << ' ' << num << endl; MyExpose(); } + else if (word == "axis_numberformat") + { + char delim; + string axis_formatting; + scr >> ws >> delim; + getline(scr, axis_formatting, delim); + cout << "Script: axis_numberformat: " << flush; + vs->SetAxisNumberFormat(axis_formatting); + cout << axis_formatting << endl; + MyExpose(); + } + else if (word == "colorbar_numberformat") + { + char delim; + string colorbar_formatting; + scr >> ws >> delim; + getline(scr, colorbar_formatting, delim); + cout << "Script: colorbar_numberformat: " << flush; + vs->SetColorbarNumberFormat(colorbar_formatting); + cout << colorbar_formatting << endl; + MyExpose(); + } else if (word == "window") { scr >> window_x >> window_y >> window_w >> window_h; From f1e28f5a4cfa419ee59c29d24af3dd1c1953b060 Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Tue, 16 Jul 2024 18:52:16 -0700 Subject: [PATCH 18/35] update readme and HelpStrings --- README.md | 2 ++ lib/vssolution.cpp | 2 ++ lib/vssolution3d.cpp | 2 ++ lib/vsvector.cpp | 2 ++ lib/vsvector3d.cpp | 2 ++ 5 files changed, 10 insertions(+) diff --git a/README.md b/README.md index f194ebcf..3c902329 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,8 @@ Key commands - . – Start/stop `z`-spinning (speed/direction can be controlled with 0 / Enter) - , , , – Manual rotation - 1, 2, 3, 4, 5, 6, 7, 8, 9 – Manual rotation along coordinate axes +- Alt + a – Set axes number format +- Alt + c – Set colorbar number format - Ctrl + , , , – Translate the viewpoint - Ctrl + o – Toggle an element ordering curve - n / N – Cycle through numberings. The options are: diff --git a/lib/vssolution.cpp b/lib/vssolution.cpp index 0fc416a4..07b4a9f2 100644 --- a/lib/vssolution.cpp +++ b/lib/vssolution.cpp @@ -84,6 +84,8 @@ std::string VisualizationSceneSolution::GetHelpString() const << "| y/Y Rotate the cutting plane |" << endl << "| z/Z Move the cutting plane |" << endl << "| \\ - Set light source position |" << endl + << "| Alt+a - Axes number format |" << endl + << "| Alt+c - Colorbar number format |" << endl << "| Ctrl+o - Element ordering curve |" << endl << "| Ctrl+p - Print to a PDF file |" << endl << "+------------------------------------+" << endl diff --git a/lib/vssolution3d.cpp b/lib/vssolution3d.cpp index 47c543ec..6be4b552 100644 --- a/lib/vssolution3d.cpp +++ b/lib/vssolution3d.cpp @@ -76,6 +76,8 @@ std::string VisualizationSceneSolution3d::GetHelpString() const << "| y/Y Rotate cutting plane (theta) |" << endl << "| z/Z Translate cutting plane |" << endl << "| \\ - Set light source position |" << endl + << "| Alt+a - Axes number format |" << endl + << "| Alt+c - Colorbar number format |" << endl << "| Ctrl+o - Element ordering curve |" << endl << "| Ctrl+p - Print to a PDF file |" << endl << "+------------------------------------+" << endl diff --git a/lib/vsvector.cpp b/lib/vsvector.cpp index db133da9..417c91cf 100644 --- a/lib/vsvector.cpp +++ b/lib/vsvector.cpp @@ -61,6 +61,8 @@ std::string VisualizationSceneVector::GetHelpString() const << "| v - Cycle through vector fields |" << endl << "| V - Change the arrows scaling |" << endl << "| \\ - Set light source position |" << endl + << "| Alt+a - Axes number format |" << endl + << "| Alt+c - Colorbar number format |" << endl << "| Ctrl+p - Print to a PDF file |" << endl << "+------------------------------------+" << endl << "| Function keys |" << endl diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index 2a41b299..1dae53d3 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -73,6 +73,8 @@ std::string VisualizationSceneVector3d::GetHelpString() const << "| y/Y Rotate cutting plane (theta) |" << endl << "| z/Z Translate cutting plane |" << endl << "| \\ - Set light source position |" << endl + << "| Alt+a - Axes number format |" << endl + << "| Alt+c - Colorbar number format |" << endl << "| Ctrl+p - Print to a PDF file |" << endl << "+------------------------------------+" << endl << "| Function keys |" << endl From b3d4d164ae5b66fa0525ce5a3cb9abcf84eb3c89 Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Tue, 16 Jul 2024 18:58:47 -0700 Subject: [PATCH 19/35] add reminder to press to trigger script steps :) --- glvis.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/glvis.cpp b/glvis.cpp index f02a32c3..30e406ab 100644 --- a/glvis.cpp +++ b/glvis.cpp @@ -1358,6 +1358,8 @@ int main (int argc, char *argv[]) cout << "Can not open script: " << script_file << endl; return 1; } + cout << "Running script from file: " << script_file << endl; + cout << "You may need to press to execute the script steps." << endl; PlayScript(scr); return 0; } From f91f3e47217ee5700d3ce833767d9e22b27ef9a0 Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Thu, 18 Jul 2024 16:26:51 -0700 Subject: [PATCH 20/35] added sanitization check on snprintf format string --- lib/aux_vis.cpp | 22 +++++++++++++++++----- lib/aux_vis.hpp | 1 + 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index dbf20a3e..6d05ace4 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "mfem.hpp" #include "sdl.hpp" @@ -1812,9 +1813,20 @@ function NumberFormatter(int precision, char format, bool showsi } function NumberFormatter(string formatting) { - return [formatting](double x) -> string { - char buf[64]; - snprintf(buf, sizeof(buf), formatting.c_str(), x); - return string(buf); - }; + if (!isValidNumberFormatting(formatting)) { + MFEM_WARNING("Invalid formatting string. Using default. " << endl); + return NumberFormatter(); + } + else { + return [formatting](double x) -> string { + char buf[64]; + snprintf(buf, sizeof(buf), formatting.c_str(), x); + return string(buf); + }; + } } + +bool isValidNumberFormatting(const string& formatting) { + regex rgx = regex(R"(%['\-+#0\s]?[0-9]{0,3}\.?[0-9]{0,3}[FfEeGg])"); + return regex_match(formatting, rgx); +} \ No newline at end of file diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index b2b65f4b..c70773f2 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -138,6 +138,7 @@ void SetFont(const std::string& fn); void SetUseHiDPI(bool status); function NumberFormatter(int precision=4, char format='d', bool showsign=false); function NumberFormatter(string formatting); +bool isValidNumberFormatting(const string& formatting); // This is a helper function for prompting the user for inputs. The benefit // over using just `cin >> input` is that you can specify a type and optionally From a2f809d5da65c53f5c588deadd819abf4fc13cb2 Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Thu, 18 Jul 2024 16:30:10 -0700 Subject: [PATCH 21/35] added missing apostrophes --- lib/threads.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/threads.cpp b/lib/threads.cpp index ef94b588..d77f5c34 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -543,7 +543,8 @@ int GLVisCommand::Execute() case AXIS_NUMBERFORMAT: { - cout << "Command: axis_numberformat: '" << axis_formatting << endl; + cout << "Command: axis_numberformat: '" + << axis_formatting << "'" << endl; (*vs)->SetAxisNumberFormat(axis_formatting); MyExpose(); break; @@ -551,7 +552,8 @@ int GLVisCommand::Execute() case COLORBAR_NUMBERFORMAT: { - cout << "Command: colorbar_numberformat: '" << colorbar_formatting << endl; + cout << "Command: colorbar_numberformat: '" + << colorbar_formatting << "'" << endl; (*vs)->SetColorbarNumberFormat(colorbar_formatting); MyExpose(); break; From 9a3b909a965f8c2e3d91f64ce14fe3e3bc55b5d0 Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Thu, 18 Jul 2024 17:09:30 -0700 Subject: [PATCH 22/35] update changelog --- CHANGELOG | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 60cedb5f..5fe2cdf3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -21,6 +21,12 @@ Version 4.2.1 (development) - Added a compilation parameter for the default font size. +- Added option to specify number formatting for axes and colorbar. Number + formatting is specified while in GLVis via `Alt+a` (axes) or `Alt+c` + (colorbar). Formatting can also be specified via socket stream or glvis + script using the keywords `axis_numberformat` or `colorbar_numberformat`, + followed by a formatting string, e.g. `colorbar_numberformat '%+06.1f'`. + Version 4.2 released on May 23, 2022 ==================================== From b8479b0e8dd8349ac35abc92b714bdc1f5b5d199 Mon Sep 17 00:00:00 2001 From: Tzanio Kolev Date: Thu, 18 Jul 2024 09:59:11 -0700 Subject: [PATCH 23/35] updated test/data --- tests/data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/data b/tests/data index 53fbee22..81de802a 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit 53fbee222cceb0581122cb72518bfc1b85766b4e +Subproject commit 81de802ad63ba41cd1fcd3825fbb3d2471538ace From 3d8f76115c4e3744d40562e2716b0fb672aff72f Mon Sep 17 00:00:00 2001 From: justinlaughlin Date: Thu, 18 Jul 2024 19:43:23 -0700 Subject: [PATCH 24/35] update regex --- lib/aux_vis.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 6d05ace4..acd187b1 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -1827,6 +1827,6 @@ function NumberFormatter(string formatting) { } bool isValidNumberFormatting(const string& formatting) { - regex rgx = regex(R"(%['\-+#0\s]?[0-9]{0,3}\.?[0-9]{0,3}[FfEeGg])"); + regex rgx = regex(R"(%[\-+#0\s]?[0-9]{0,3}\.?[0-9]{0,3}[FfEeGg])"); return regex_match(formatting, rgx); } \ No newline at end of file From 8b5af590e01d3931811dba69282fed2b68a09e5c Mon Sep 17 00:00:00 2001 From: Tzanio Kolev Date: Fri, 19 Jul 2024 13:21:08 -0700 Subject: [PATCH 25/35] minor --- CHANGELOG | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 00004b3d..b85e8aa5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -25,11 +25,11 @@ Version 4.2.1 (development) - Added a compilation parameter for the default font size. -- Added option to specify number formatting for axes and colorbar. Number - formatting is specified while in GLVis via `Alt+a` (axes) or `Alt+c` - (colorbar). Formatting can also be specified via socket stream or glvis - script using the keywords `axis_numberformat` or `colorbar_numberformat`, - followed by a formatting string, e.g. `colorbar_numberformat '%+06.1f'`. +- Added option to specify the floating point number formatting in GLVis axes and + colorbar. Use 'Alt+a' for the axes and 'Alt+c' for the colorbar. Formatting + can also be specified in socket stream or glvis script with axis_numberformat + or colorbar_numberformat, followed by a C-like formatting string, for example + "colorbar_numberformat '%+06.1f'". Version 4.2 released on May 23, 2022 From abc6f59f4d108229f65507e31a38139e23be4e4f Mon Sep 17 00:00:00 2001 From: Tzanio Kolev Date: Fri, 19 Jul 2024 16:36:23 -0700 Subject: [PATCH 26/35] Styling --- lib/aux_vis.cpp | 20 +++++++++++++------- lib/vsdata.cpp | 1 + lib/vssolution.cpp | 4 ++-- lib/vssolution3d.cpp | 4 ++-- lib/vsvector.cpp | 4 ++-- lib/vsvector3d.cpp | 4 ++-- 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index acd187b1..65599eae 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -1785,7 +1785,8 @@ void SetFont(const std::string& fn) #endif } -function NumberFormatter(int precision, char format, bool showsign) { +function NumberFormatter(int precision, char format, bool showsign) +{ return [precision, format, showsign](double x) -> string { ostringstream oss; switch (format) { @@ -1804,7 +1805,8 @@ function NumberFormatter(int precision, char format, bool showsi oss << defaultfloat; break; }; - if (showsign){ + if (showsign) + { oss << showpos; } oss << setprecision(precision) << x; @@ -1812,12 +1814,15 @@ function NumberFormatter(int precision, char format, bool showsi }; } -function NumberFormatter(string formatting) { - if (!isValidNumberFormatting(formatting)) { +function NumberFormatter(string formatting) +{ + if (!isValidNumberFormatting(formatting)) + { MFEM_WARNING("Invalid formatting string. Using default. " << endl); return NumberFormatter(); } - else { + else + { return [formatting](double x) -> string { char buf[64]; snprintf(buf, sizeof(buf), formatting.c_str(), x); @@ -1826,7 +1831,8 @@ function NumberFormatter(string formatting) { } } -bool isValidNumberFormatting(const string& formatting) { +bool isValidNumberFormatting(const string& formatting) +{ regex rgx = regex(R"(%[\-+#0\s]?[0-9]{0,3}\.?[0-9]{0,3}[FfEeGg])"); return regex_match(formatting, rgx); -} \ No newline at end of file +} diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index 2de42fb9..5b94e113 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -422,6 +422,7 @@ void VisualizationSceneScalarData::SetColorbarNumberFormat(int precision, // The first two arguments are required but I don't think they are used? PrepareColorBar(0,0); } + void VisualizationSceneScalarData::SetColorbarNumberFormat(string formatting) { colorbar_formatter = NumberFormatter(formatting); diff --git a/lib/vssolution.cpp b/lib/vssolution.cpp index bb9c8b7f..2270fc68 100644 --- a/lib/vssolution.cpp +++ b/lib/vssolution.cpp @@ -85,8 +85,8 @@ std::string VisualizationSceneSolution::GetHelpString() const << "| y/Y Rotate the cutting plane |" << endl << "| z/Z Move the cutting plane |" << endl << "| \\ - Set light source position |" << endl - << "| Alt+a - Axes number format |" << endl - << "| Alt+c - Colorbar number format |" << endl + << "| Alt+a - Axes number format |" << endl + << "| Alt+c - Colorbar number format |" << endl << "| Ctrl+o - Element ordering curve |" << endl << "| Ctrl+p - Print to a PDF file |" << endl << "+------------------------------------+" << endl diff --git a/lib/vssolution3d.cpp b/lib/vssolution3d.cpp index e17c060d..4d253b2b 100644 --- a/lib/vssolution3d.cpp +++ b/lib/vssolution3d.cpp @@ -77,8 +77,8 @@ std::string VisualizationSceneSolution3d::GetHelpString() const << "| y/Y Rotate cutting plane (theta) |" << endl << "| z/Z Translate cutting plane |" << endl << "| \\ - Set light source position |" << endl - << "| Alt+a - Axes number format |" << endl - << "| Alt+c - Colorbar number format |" << endl + << "| Alt+a - Axes number format |" << endl + << "| Alt+c - Colorbar number format |" << endl << "| Ctrl+o - Element ordering curve |" << endl << "| Ctrl+p - Print to a PDF file |" << endl << "+------------------------------------+" << endl diff --git a/lib/vsvector.cpp b/lib/vsvector.cpp index a2bc30eb..479f70e8 100644 --- a/lib/vsvector.cpp +++ b/lib/vsvector.cpp @@ -62,8 +62,8 @@ std::string VisualizationSceneVector::GetHelpString() const << "| v - Cycle through vector fields |" << endl << "| V - Change the arrows scaling |" << endl << "| \\ - Set light source position |" << endl - << "| Alt+a - Axes number format |" << endl - << "| Alt+c - Colorbar number format |" << endl + << "| Alt+a - Axes number format |" << endl + << "| Alt+c - Colorbar number format |" << endl << "| Ctrl+p - Print to a PDF file |" << endl << "+------------------------------------+" << endl << "| Function keys |" << endl diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index dc1d635c..ac239344 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -74,8 +74,8 @@ std::string VisualizationSceneVector3d::GetHelpString() const << "| y/Y Rotate cutting plane (theta) |" << endl << "| z/Z Translate cutting plane |" << endl << "| \\ - Set light source position |" << endl - << "| Alt+a - Axes number format |" << endl - << "| Alt+c - Colorbar number format |" << endl + << "| Alt+a - Axes number format |" << endl + << "| Alt+c - Colorbar number format |" << endl << "| Ctrl+p - Print to a PDF file |" << endl << "+------------------------------------+" << endl << "| Function keys |" << endl From 8d4b682f36953e4eac39e908864757b15c617da7 Mon Sep 17 00:00:00 2001 From: Justin Laughlin Date: Mon, 22 Jul 2024 11:45:44 -0700 Subject: [PATCH 27/35] conform to style and add message to prompt() --- lib/aux_vis.cpp | 6 ++++-- lib/aux_vis.hpp | 21 +++++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index 65599eae..7c92d0f0 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -1787,7 +1787,8 @@ void SetFont(const std::string& fn) function NumberFormatter(int precision, char format, bool showsign) { - return [precision, format, showsign](double x) -> string { + return [precision, format, showsign](double x) -> string + { ostringstream oss; switch (format) { case 'f': @@ -1823,7 +1824,8 @@ function NumberFormatter(string formatting) } else { - return [formatting](double x) -> string { + return [formatting](double x) -> string + { char buf[64]; snprintf(buf, sizeof(buf), formatting.c_str(), x); return string(buf); diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index c70773f2..3361a153 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -153,22 +153,31 @@ T prompt(const string question, T input; string strInput; - while (true) { + while (true) + { cout << question << " "; getline(cin, strInput); stringstream buf(strInput); - if (strInput.empty() && default_value != nullptr) { + if (strInput.empty() && default_value != nullptr) + { + cout << "Input empty. Using default value: " << *default_value << endl; return *default_value; } - if (buf >> input) { - if (validator(input)) { + if (buf >> input) + { + if (validator(input)) + { return input; - } else { + } + else + { cout << "Input is not valid. Please try again." << endl; } - } else { + } + else + { cout << "Input can not be casted to expected type. Please try again." << endl; } } From 72d38fb1e64d29f53c1986ee260c6c44985cc7b0 Mon Sep 17 00:00:00 2001 From: Veselin Dobrev Date: Mon, 22 Jul 2024 13:59:31 -0700 Subject: [PATCH 28/35] Reworked and simplified a bit the handling of the key events in the SDL event loop. Added some comments to clarify behavior. --- lib/sdl.cpp | 107 ++++++++++++++++++++++++---------------------------- lib/sdl.hpp | 7 ++-- 2 files changed, 52 insertions(+), 62 deletions(-) diff --git a/lib/sdl.cpp b/lib/sdl.cpp index a4262be8..eb0a7f42 100644 --- a/lib/sdl.cpp +++ b/lib/sdl.cpp @@ -267,51 +267,33 @@ void SdlWindow::mouseEventUp(SDL_MouseButtonEvent& eb) } } -void SdlWindow::keyEvent(SDL_Keysym& ks) +void SdlWindow::keyDownEvent(SDL_Keysym& ks) { - bool handled = false; - if (ks.sym >= 128 || ks.sym < 32) + // Some keyDown events will be followed by a textInput event which will + // handle key translation due to Shift or CapsLock, so we leave such events + // to be processed there. + if ((ks.sym >= 32 && ks.sym < 127) && + (ks.mod & ~(KMOD_SHIFT | KMOD_CAPS)) == 0) { - if (onKeyDown[ks.sym]) - { - onKeyDown[ks.sym](ks.mod); - handled = true; - } - } - else if (ks.sym < 256 && std::isdigit(ks.sym)) - { - if (!(SDL_GetModState() & KMOD_SHIFT)) - { - // handle number key event here - onKeyDown[ks.sym](ks.mod); - handled = true; - } - } - else if (ctrlDown) - { - if (onKeyDown[ks.sym]) - { - onKeyDown[ks.sym](ks.mod); - handled = true; - } - } - if (ks.sym == SDLK_RCTRL || ks.sym == SDLK_LCTRL) - { - ctrlDown = true; + lastKeyDownProcessed = false; + return; } - if (handled) + // If any 'mod' key other than KMOD_SHIFT or KMOD_CAPS is pressed, or the key + // is not in the range [32,127) then we processed the event here. + lastKeyDownProcessed = true; + if (onKeyDown[ks.sym]) { + onKeyDown[ks.sym](ks.mod); + + // Record the key in 'saved_keys': bool isAlt = ks.mod & (KMOD_ALT); bool isCtrl = ks.mod & (KMOD_CTRL); saved_keys += "["; if (isCtrl) { saved_keys += "C-"; } if (isAlt) { saved_keys += "Alt-"; } - if (ks.sym < 256 && std::isalpha(ks.sym)) + if (ks.sym >= 32 && ks.sym < 127) { - // key with corresponding text output - char c = ks.sym; - if (!(ks.mod & KMOD_SHIFT)) { c = std::tolower(c); } - saved_keys += c; + saved_keys += (char)(ks.sym); } else { @@ -321,25 +303,21 @@ void SdlWindow::keyEvent(SDL_Keysym& ks) } } -void SdlWindow::keyEvent(char c) +void SdlWindow::textInputEvent(const SDL_TextInputEvent &tie) { - if (!std::isdigit(c) && onKeyDown[c]) - { - SDL_Keymod mods = SDL_GetModState(); - bool isAlt = mods & (KMOD_ALT); - bool isCtrl = mods & (KMOD_CTRL); + // This event follows a keyDown event where we've recorded if the event was + // processed in keyDownEvent(). If it was not processed, we do it here. + if (lastKeyDownProcessed) { return; } + const char c = tie.text[0]; + if (onKeyDown[c]) + { + // Keys with 'mods' (other than Shift and CapsLock) are processed in + // keyDownEvent(). + const int mods = 0; onKeyDown[c](mods); - if (isAlt || isCtrl) - { - saved_keys += "["; - if (isCtrl) { saved_keys += "C-"; } - if (isAlt) { saved_keys += "Alt-"; } - } + + // Record the key in 'saved_keys': saved_keys += c; - if (isAlt || isCtrl) - { - saved_keys += "]"; - } } } @@ -403,17 +381,30 @@ void SdlWindow::mainIter() keep_going = true; break; case SDL_KEYDOWN: - keyEvent(e.key.keysym); +// For debugging: uncomment the next line to track key events. +// #define TRACK_KEY_EVENTS +#ifdef TRACK_KEY_EVENTS + cout << "Event: SDL_KEYDOWN sym=" << e.key.keysym.sym + << " mod=" << e.key.keysym.mod << endl; +#endif + keyDownEvent(e.key.keysym); break; case SDL_KEYUP: - if (e.key.keysym.sym == SDLK_LCTRL - || e.key.keysym.sym == SDLK_RCTRL) - { - ctrlDown = false; - } +#ifdef TRACK_KEY_EVENTS + cout << "Event: SDL_KEYUP sym=" << e.key.keysym.sym + << " mod=" << e.key.keysym.mod << endl; +#endif break; case SDL_TEXTINPUT: - keyEvent(e.text.text[0]); +#ifdef TRACK_KEY_EVENTS + cout << "Event: SDL_TEXTINPUT text[0..3]=" + << (int)(unsigned char)(e.text.text[0]) + << ' ' << (int)(unsigned char)(e.text.text[1]) + << ' ' << (int)(unsigned char)(e.text.text[2]) + << ' ' << (int)(unsigned char)(e.text.text[3]) + << " (as codes 0-255)" << endl; +#endif + textInputEvent(e.text); break; case SDL_MOUSEMOTION: motionEvent(e.motion); diff --git a/lib/sdl.hpp b/lib/sdl.hpp index 6d157328..df5fb987 100644 --- a/lib/sdl.hpp +++ b/lib/sdl.hpp @@ -103,8 +103,6 @@ class SdlWindow TouchDelegate onTouchPinch{nullptr}; TouchDelegate onTouchRotate{nullptr}; - bool ctrlDown{false}; - #ifdef __EMSCRIPTEN__ std::string canvas_id_; #endif @@ -127,14 +125,15 @@ class SdlWindow bool takeScreenshot{false}; std::string screenshot_file; bool screenshot_convert; + bool lastKeyDownProcessed; // internal event handlers void windowEvent(SDL_WindowEvent& ew); void motionEvent(SDL_MouseMotionEvent& em); void mouseEventDown(SDL_MouseButtonEvent& eb); void mouseEventUp(SDL_MouseButtonEvent& eb); - void keyEvent(SDL_Keysym& ks); - void keyEvent(char c); + void keyDownEvent(SDL_Keysym& ks); + void textInputEvent(const SDL_TextInputEvent &e); void multiGestureEvent(SDL_MultiGestureEvent & e); bool is_multithreaded{true}; From da9d2bc4b54dfdfb18baa8532101dd4bd56148bf Mon Sep 17 00:00:00 2001 From: Veselin Dobrev Date: Mon, 22 Jul 2024 16:41:27 -0700 Subject: [PATCH 29/35] Fix SdlWindow::signalKeyDown for the updated key events handling. --- lib/sdl.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/sdl.cpp b/lib/sdl.cpp index eb0a7f42..9b932a6c 100644 --- a/lib/sdl.cpp +++ b/lib/sdl.cpp @@ -272,6 +272,7 @@ void SdlWindow::keyDownEvent(SDL_Keysym& ks) // Some keyDown events will be followed by a textInput event which will // handle key translation due to Shift or CapsLock, so we leave such events // to be processed there. + // Note: the same condition has to be used in signalKeyDown(). if ((ks.sym >= 32 && ks.sym < 127) && (ks.mod & ~(KMOD_SHIFT | KMOD_CAPS)) == 0) { @@ -621,20 +622,21 @@ void SdlWindow::setWindowPos(int x, int y) void SdlWindow::signalKeyDown(SDL_Keycode k, SDL_Keymod m) { SDL_Event event; - if (k >= 32 && k < 128) + + event.type = SDL_KEYDOWN; + event.key.windowID = window_id; + event.key.keysym.sym = k; + event.key.keysym.mod = m; + queueEvents({ event }); + + // The same condition as in keyDownEvent(). + if ((k >= 32 && k < 127) && (m & ~(KMOD_SHIFT | KMOD_CAPS)) == 0) { event.type = SDL_TEXTINPUT; event.text.windowID = window_id; event.text.text[0] = k; + queueEvents({ event }); } - else - { - event.type = SDL_KEYDOWN; - event.key.windowID = window_id; - event.key.keysym.sym = k; - event.key.keysym.mod = m; - } - queueEvents({ event }); } void SdlWindow::swapBuffer() From d1920e330a855bf1bea7f094102bf55cf02a0c41 Mon Sep 17 00:00:00 2001 From: Veselin Dobrev Date: Mon, 22 Jul 2024 18:57:27 -0700 Subject: [PATCH 30/35] Testing new baseline. --- tests/data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/data b/tests/data index 81de802a..c69d3914 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit 81de802ad63ba41cd1fcd3825fbb3d2471538ace +Subproject commit c69d39148eab1ff434f71222b8769aaf1807231b From f50907dc252acb796291a2a91bd3496f38d90c16 Mon Sep 17 00:00:00 2001 From: Justin Laughlin Date: Tue, 23 Jul 2024 12:47:07 -0700 Subject: [PATCH 31/35] update data submodule to master --- tests/data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/data b/tests/data index c69d3914..7457c82e 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit c69d39148eab1ff434f71222b8769aaf1807231b +Subproject commit 7457c82e272a521c7877ad54b1ac4e0533945377 From 240742d1b6b2a827644d7b128411d16b07e4d27a Mon Sep 17 00:00:00 2001 From: Justin Laughlin Date: Tue, 23 Jul 2024 14:32:22 -0700 Subject: [PATCH 32/35] refactor to use f-strings --- tests/glvis_driver.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/glvis_driver.py b/tests/glvis_driver.py index 34556929..af3fb2d2 100644 --- a/tests/glvis_driver.py +++ b/tests/glvis_driver.py @@ -72,31 +72,31 @@ def compare_images(baseline_file, output_file, expect_fail=False): print("[FAIL] Differences were not detected in the control case.") else: print("[PASS] Images match.") - print(" actual ssim = {}, cutoff = {}".format(ssim, cutoff_ssim)) + print(f" actual ssim = {ssim}, cutoff = {cutoff_ssim}") return ssim >= cutoff_ssim if not expect_fail else ssim < cutoff_ssim # Function to test a given glvis command with a variety of key-based commands. # Not currently in use. def test_case(exec_path, exec_args, baseline, t_group, t_name, cmd): - print("Testing {0}:{1}...".format(t_group, t_name)) + print(f"Testing {t_group0}:{t_name1}...")) full_screenshot_cmd = cmd + screenshot_keys - cmd = "{0} {1} -k \"{2}\"".format(exec_path, exec_args, full_screenshot_cmd) - print("Exec: {}".format(cmd)) + cmd = f"{exec_path0} {exec_args} -k \"{full_screenshot_cmd2}\"" + print(f"Exec: {cmd}") ret = os.system(cmd + " > /dev/null 2>&1") if ret != 0: - print("[FAIL] GLVis exited with error code {}.".format(ret)) + print(f"[FAIL] GLVis exited with error code {ret}.") return False if not os.path.exists(t_group): os.mkdir(t_group) - output_name = "{0}/{1}.png".format(t_group, t_name) + output_name = f"{t_group0}/{t_name1}.png" - ret = os.system("mv {0} {1}".format(screenshot_file, output_name)) + ret = os.system(f"mv {screenshot_file0} {output_name}") if ret != 0: - print("[FAIL] Could not move output image: exit code {}.".format(ret)) + print(f"[FAIL] Could not move output image: exit code {ret}.") return False if baseline: - baseline_name = "{0}/test.{1}.png".format(baseline, test_name) + baseline_name = f"{baseline0}/test.{test_name1}.png" return compare_images(baseline_name, output_name) else: print("[IGNORE] No baseline exists to compare against.") @@ -106,35 +106,35 @@ def test_stream(exec_path, exec_args, save_file, baseline): if exec_args is None: exec_args = "" test_name = os.path.basename(save_file) - print("Testing {}...".format(save_file)) + print(f"Testing {save_file}...") # Create new stream file with command to screenshot and close stream_data = None with open(save_file) as in_f: stream_data = in_f.read() - output_name = "test.{}.png".format(test_name) - output_name_fail = "test.fail.{}.png".format(test_name) + output_name = f"test.{test_name}.png" + output_name_fail = f"test.fail.{test_name}.png" tmp_file = "test.saved" with open(tmp_file, 'w') as out_f: out_f.write(stream_data) out_f.write("\nwindow_size 800 600") - out_f.write("\nscreenshot {}".format(output_name)) + out_f.write(f"\nscreenshot {output_name}") # Zooming in should create some difference in the images out_f.write("\nkeys *") - out_f.write("\nscreenshot {}".format(output_name_fail)) + out_f.write(f"\nscreenshot {output_name_fail}") out_f.write("\nkeys q") # Run GLVis with modified stream file - cmd = "{0} {1} -saved {2}".format(exec_path, exec_args, tmp_file) - print("Exec: {}".format(cmd)) + cmd = f"{exec_path} {exec_args} -saved {tmp_file2}" + print(f"Exec: {cmd}") ret = os.system(cmd) if ret != 0: - print("[FAIL] GLVis exited with error code {}.".format(ret)) + print(f"[FAIL] GLVis exited with error code {ret}.") return False if baseline: - baseline_name = "{0}/test.{1}.png".format(baseline, test_name) + baseline_name = f"{baseline0}/test.{test_name1}.png") test_baseline = compare_images(baseline_name, output_name) test_control = compare_images(baseline_name, output_name_fail, expect_fail=True) From 247824dce5e7281ec163e4a2c9819e8543b5cc90 Mon Sep 17 00:00:00 2001 From: Justin Laughlin Date: Tue, 23 Jul 2024 14:34:40 -0700 Subject: [PATCH 33/35] add requirements.txt --- tests/requirements.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/requirements.txt diff --git a/tests/requirements.txt b/tests/requirements.txt new file mode 100644 index 00000000..48389795 --- /dev/null +++ b/tests/requirements.txt @@ -0,0 +1,3 @@ +scikit-image +plotly +numpy >= 1.20.0, < 2.0.0 From fa88cbb8ae6e868108a8b0b23e17a618702ee5c2 Mon Sep 17 00:00:00 2001 From: Justin Laughlin Date: Tue, 23 Jul 2024 14:36:33 -0700 Subject: [PATCH 34/35] add fail-fast: false to strategy so that tests always complete --- .github/workflows/builds.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index faa48a8d..2682cf42 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -31,6 +31,7 @@ env: jobs: builds-and-tests: strategy: + fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] target: [dbg, opt] From 6ed8e9f26ea14b5230d100f72a1d63906de86971 Mon Sep 17 00:00:00 2001 From: Justin Laughlin Date: Tue, 23 Jul 2024 14:38:39 -0700 Subject: [PATCH 35/35] update workflow to use requirements.txt --- .github/workflows/builds.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 2682cf42..433022ee 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -231,7 +231,7 @@ jobs: if: matrix.build-system == 'cmake' run: | python -m pip install --upgrade pip - pip install scikit-image + python -m pip install -r glvis/tests/requirements.txt - name: setup Linux testing dependencies if: matrix.build-system == 'cmake' && matrix.os == 'ubuntu-latest'