Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Number formatting #288

Merged
merged 34 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e3a5704
implement general NumberFormat() function
justinlaughlin Jul 9, 2024
76eb7a7
add option to show sign (showpos)
justinlaughlin Jul 9, 2024
1573db5
begin implementing F2 to change number format
justinlaughlin Jul 9, 2024
b1bd9d1
remove h option
justinlaughlin Jul 9, 2024
359cc45
swap order of args in NumberFormat()
justinlaughlin Jul 9, 2024
30b5f81
add prompt() function and also reverting F2 changes
justinlaughlin Jul 9, 2024
458114a
seems to be working
justinlaughlin Jul 10, 2024
8cb2e0f
added ability to specify a default using prompt()
justinlaughlin Jul 10, 2024
9f881b4
add printf style option to FormatNumber
justinlaughlin Jul 16, 2024
92687d9
make number formatter lazy so its easier to pass around
justinlaughlin Jul 17, 2024
73b4bb6
change vsdata to use updated NumberFormatter
justinlaughlin Jul 17, 2024
84cdf08
forgot semicolon
justinlaughlin Jul 17, 2024
00cd71d
fix few more bugs
justinlaughlin Jul 17, 2024
dd9c4d4
add default formatter
justinlaughlin Jul 17, 2024
039c978
stream is working for axis number format
justinlaughlin Jul 17, 2024
23d49ca
stream is working for axis and colorbar now
justinlaughlin Jul 17, 2024
fc96c64
add in hooks to glvis script
justinlaughlin Jul 17, 2024
f1e28f5
update readme and HelpStrings
justinlaughlin Jul 17, 2024
b3d4d16
add reminder to press <space> to trigger script steps :)
justinlaughlin Jul 17, 2024
f91f3e4
added sanitization check on snprintf format string
justinlaughlin Jul 18, 2024
a2f809d
added missing apostrophes
justinlaughlin Jul 18, 2024
9a3b909
update changelog
justinlaughlin Jul 19, 2024
f31f481
Merge branch 'master' into number-formatting
justinlaughlin Jul 19, 2024
b8479b0
updated test/data
tzanio Jul 18, 2024
3d8f761
update regex
justinlaughlin Jul 19, 2024
8b5af59
minor
tzanio Jul 19, 2024
3686dd0
Merged in master, conflict in CHANGELOG
tzanio Jul 19, 2024
abc6f59
Styling
tzanio Jul 19, 2024
8d4b682
conform to style and add message to prompt()
justinlaughlin Jul 22, 2024
72d38fb
Reworked and simplified a bit the handling of the key events in the
v-dobrev Jul 22, 2024
da9d2bc
Fix SdlWindow::signalKeyDown for the updated key events handling.
v-dobrev Jul 22, 2024
ed6db97
Merge pull request #294 from GLVis/number-formatting-keys-fix
justinlaughlin Jul 23, 2024
d1920e3
Testing new baseline.
v-dobrev Jul 23, 2024
f50907d
update data submodule to master
justinlaughlin Jul 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ Version 4.2.1 (development)

- Added a compilation parameter for the default font size.

- 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'".

- Added visualization of quadrature data (QuadratureFunction in MFEM). Both
loading from file, with the new command line argument '-q', or from a socket
stream, with the keyword 'quadrature', are supported. Three visualization
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ Key commands
- <kbd>.</kbd> – Start/stop `z`-spinning (speed/direction can be controlled with <kbd>0</kbd> / <kbd>Enter</kbd>)
- <kbd>←</kbd>, <kbd>→</kbd>, <kbd>↑</kbd>, <kbd>↓</kbd> – Manual rotation
- <kbd>1</kbd>, <kbd>2</kbd>, <kbd>3</kbd>, <kbd>4</kbd>, <kbd>5</kbd>, <kbd>6</kbd>, <kbd>7</kbd>, <kbd>8</kbd>, <kbd>9</kbd> – Manual rotation along coordinate axes
- <kbd>Alt</kbd> + <kbd>a</kbd> – Set axes number format
- <kbd>Alt</kbd> + <kbd>c</kbd> – Set colorbar number format
Comment on lines +168 to +169
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does Alt mean on Mac? Is it option or command -- it will be good to clarify it here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For what's it worth, we do use Alt already in https://github.com/glvis/glvis/?tab=readme-ov-file#advanced

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not able to test but I did see other places that used Alt like Tzanio mentioned. It'd probably be good to mention it somewhere at the top.

- <kbd>Ctrl</kbd> + <kbd>←</kbd>, <kbd>→</kbd>, <kbd>↑</kbd>, <kbd>↓</kbd> – Translate the viewpoint
- <kbd>Ctrl</kbd> + <kbd>o</kbd> – Toggle an element ordering curve
- <kbd>n</kbd> / <kbd>N</kbd> – Cycle through numberings. The options are:
Expand Down
24 changes: 24 additions & 0 deletions glvis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,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;
Expand Down Expand Up @@ -1489,6 +1511,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 <space> to execute the script steps." << endl;
PlayScript(scr);
return 0;
}
Expand Down
55 changes: 55 additions & 0 deletions lib/aux_vis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <fstream>
#include <cmath>
#include <chrono>
#include <regex>

#include "mfem.hpp"
#include "sdl.hpp"
Expand Down Expand Up @@ -1783,3 +1784,57 @@ void SetFont(const std::string& fn)
<< "', height = " << font_size << endl;
#endif
}

function<string(double)> 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();
};
}

function<string(double)> NumberFormatter(string formatting)
{
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);
}
47 changes: 47 additions & 0 deletions lib/aux_vis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,52 @@ bool SetFont(const vector<std::string>& patterns, int height);
void SetFont(const std::string& fn);

void SetUseHiDPI(bool status);
function<string(double)> NumberFormatter(int precision=4, char format='d', bool showsign=false);
function<string(double)> 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
// 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 <typename T>
T prompt(const string question,
const T* default_value = nullptr,
function<bool(T)> validator = [](T) { return true; })
{
T input;
string strInput;

while (true)
{
cout << question << " ";
getline(cin, strInput);
stringstream buf(strInput);

if (strInput.empty() && default_value != nullptr)
{
cout << "Input empty. Using default value: " << *default_value << endl;
return *default_value;
}

if (buf >> input)
{
if (validator(input))
{
return input;
}
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
129 changes: 61 additions & 68 deletions lib/sdl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,51 +267,34 @@ 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)
{
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;
// 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)
{
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
{
Expand All @@ -321,25 +304,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 += "]";
}
}
}

Expand Down Expand Up @@ -403,17 +382,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);
Expand Down Expand Up @@ -630,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()
Expand Down
7 changes: 3 additions & 4 deletions lib/sdl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ class SdlWindow
TouchDelegate onTouchPinch{nullptr};
TouchDelegate onTouchRotate{nullptr};

bool ctrlDown{false};

#ifdef __EMSCRIPTEN__
std::string canvas_id_;
#endif
Expand All @@ -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};
Expand Down
Loading
Loading