SpinButton activation after user entry

Hi There,

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:


  1. User changes spinbutton value using mouse wheel or up/down keys until they’re at the correct value and press enter to confirm. Okay.
  2. 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.

Best Regards,

EDIT: Why does a bot(?) think this spam?

I guess you want gtk_entry_set_activates_default().

gtk_entry_set_activates_default (GTK_ENTRY (spin_button), FALSE);

Doesn’t do anything useful in my case since the window isn’t a GtkDialog. Closing the window is done in the signal handler for activate. https://www.github.com/horizon-eda/horizon/blob/master/src/dialogs/enter_datum_scale_window.cpp#L24

Oh, sorry, didn’t get this.

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.

I have now corrected the post above.

Thanks a lot! Here’s how I implemented it: https://github.com/horizon-eda/horizon/commit/bdc84fb8ce0a6f2cfe9a5bfc7291ca2dbd3a38e3#diff-7ae29061904f45094a750205f599b443b272b7ec49e85d1b482840de15460939R357

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.