my application Horizon EDA uses spinbuttons in the scale tool, among other things. The interaction goes like this:
In the scale tool, the user can open the non-modal window shown below. Adjusting the spinbutton (value-changed signal) will immediately update the scale of the objects in the background. Pressing enter (activate signal) confirms the entered scale and closes the window. This gets us these behaviors:
User changes spinbutton value using mouse wheel or up/down keys until they’re at the correct value and press enter to confirm. Okay.
User types in new scale, presses enter, dialog goes away without a way to make further changes. Not okay.
I’m now looking for a way to tell apart pressing enter in the second case where it causes user input to be parsed from the first case so I can get this behaviour:
User types in value, presses enter, spinbutton parses value, emits value-changed, objects update, user is happy with the outcome, presses enter again to confirm.
I had look at the sequence of the activate, changed and value-changed signals, but the sequence is the same in both cases.
I hope that my explanations weren’t too confusing.
There are variations on the theme, of course, but I can think of two ways:
connect two signal handlers to the activate signal: one using signal_activate().connect(handler_a, false /* connect-normal */), the other using signal_activate().connect(handler_b, true /* connect-after */). Then the first handler should read the spin button value and store that value in a class member variable. The second handler (which is run after the spin button has updated) re-reads the spin button value and tests wether it equals the value stored in the member variable.
Probably simpler: connect to signal_activate setting the after argument to false: sp->signal_activate().connect(handler, false /* connect-normal */). Then write your handler to:
get the spin button value
call sp->update()
get the spin button value again
if the value before and after are the same, close the window (i.e. emit_event(ToolDataWindow::Event::OK))
Wait, looks like SignalProxy<>::connect defaults the after argument to true! I did not expect that, TBH. So in gtkmm connect() defaults to connect after. Good to know.