+gboolean NonModalEntry::focus_out(ui::Entry entry, GdkEventFocus *event, NonModalEntry *self)
+{
+ if (self->m_editing && gtk_widget_get_visible(entry)) {
+ self->m_apply();
+ }
+ self->m_editing = false;
+ return FALSE;
+}
+
+gboolean NonModalEntry::changed(ui::Entry entry, NonModalEntry *self)
+{
+ self->m_editing = true;
+ return FALSE;
+}
+
+gboolean NonModalEntry::enter(ui::Entry entry, GdkEventKey *event, NonModalEntry *self)
+{
+ if (event->keyval == GDK_KEY_Return) {
+ self->m_apply();
+ self->m_editing = false;
+ gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(entry)), NULL);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean NonModalEntry::escape(ui::Entry entry, GdkEventKey *event, NonModalEntry *self)
+{
+ if (event->keyval == GDK_KEY_Escape) {
+ self->m_cancel();
+ self->m_editing = false;
+ gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(entry)), NULL);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void NonModalEntry::connect(ui::Entry entry)
+{
+ entry.connect("focus_in_event", G_CALLBACK(focus_in), this);
+ entry.connect("focus_out_event", G_CALLBACK(focus_out), this);
+ entry.connect("key_press_event", G_CALLBACK(enter), this);
+ entry.connect("key_press_event", G_CALLBACK(escape), this);
+ entry.connect("changed", G_CALLBACK(changed), this);
+}
+
+gboolean NonModalSpinner::changed(ui::SpinButton spin, NonModalSpinner *self)
+{
+ self->m_apply();
+ return FALSE;
+}
+
+gboolean NonModalSpinner::enter(ui::SpinButton spin, GdkEventKey *event, NonModalSpinner *self)
+{
+ if (event->keyval == GDK_KEY_Return) {
+ gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(spin)), NULL);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean NonModalSpinner::escape(ui::SpinButton spin, GdkEventKey *event, NonModalSpinner *self)
+{
+ if (event->keyval == GDK_KEY_Escape) {
+ self->m_cancel();
+ gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(spin)), NULL);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void NonModalSpinner::connect(ui::SpinButton spin)
+{
+ auto adj = ui::Adjustment(gtk_spin_button_get_adjustment(spin));
+ guint handler = adj.connect("value_changed", G_CALLBACK(changed), this);
+ g_object_set_data(G_OBJECT(spin), "handler", gint_to_pointer(handler));
+ spin.connect("key_press_event", G_CALLBACK(enter), this);
+ spin.connect("key_press_event", G_CALLBACK(escape), this);
+}