97c4bce299ceeb2fe60d94de17f8d04490450c4e
[xonotic/netradiant.git] / libs / gtkutil / nonmodal.cpp
1 #include "nonmodal.h"
2
3 #include <gtk/gtk.h>
4 #include <gdk/gdkkeysyms.h>
5
6 gboolean escape_clear_focus_widget(ui::Widget widget, GdkEventKey *event, gpointer data)
7 {
8     if (event->keyval == GDK_KEY_Escape) {
9         gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(widget))), NULL);
10         return TRUE;
11     }
12     return FALSE;
13 }
14
15 void widget_connect_escape_clear_focus_widget(ui::Widget widget)
16 {
17     widget.connect("key_press_event", G_CALLBACK(escape_clear_focus_widget), 0);
18 }
19
20 gboolean NonModalEntry::focus_in(ui::Entry entry, GdkEventFocus *event, NonModalEntry *self)
21 {
22     self->m_editing = false;
23     return FALSE;
24 }
25
26 gboolean NonModalEntry::focus_out(ui::Entry entry, GdkEventFocus *event, NonModalEntry *self)
27 {
28     if (self->m_editing && gtk_widget_get_visible(GTK_WIDGET(entry))) {
29         self->m_apply();
30     }
31     self->m_editing = false;
32     return FALSE;
33 }
34
35 gboolean NonModalEntry::changed(ui::Entry entry, NonModalEntry *self)
36 {
37     self->m_editing = true;
38     return FALSE;
39 }
40
41 gboolean NonModalEntry::enter(ui::Entry entry, GdkEventKey *event, NonModalEntry *self)
42 {
43     if (event->keyval == GDK_KEY_Return) {
44         self->m_apply();
45         self->m_editing = false;
46         gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(entry))), NULL);
47         return TRUE;
48     }
49     return FALSE;
50 }
51
52 gboolean NonModalEntry::escape(ui::Entry entry, GdkEventKey *event, NonModalEntry *self)
53 {
54     if (event->keyval == GDK_KEY_Escape) {
55         self->m_cancel();
56         self->m_editing = false;
57         gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(entry))), NULL);
58         return TRUE;
59     }
60     return FALSE;
61 }
62
63 void NonModalEntry::connect(ui::Entry entry)
64 {
65     entry.connect("focus_in_event", G_CALLBACK(focus_in), this);
66     entry.connect("focus_out_event", G_CALLBACK(focus_out), this);
67     entry.connect("key_press_event", G_CALLBACK(enter), this);
68     entry.connect("key_press_event", G_CALLBACK(escape), this);
69     entry.connect("changed", G_CALLBACK(changed), this);
70 }
71
72 gboolean NonModalSpinner::changed(ui::SpinButton spin, NonModalSpinner *self)
73 {
74     self->m_apply();
75     return FALSE;
76 }
77
78 gboolean NonModalSpinner::enter(ui::SpinButton spin, GdkEventKey *event, NonModalSpinner *self)
79 {
80     if (event->keyval == GDK_KEY_Return) {
81         gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(spin))), NULL);
82         return TRUE;
83     }
84     return FALSE;
85 }
86
87 gboolean NonModalSpinner::escape(ui::SpinButton spin, GdkEventKey *event, NonModalSpinner *self)
88 {
89     if (event->keyval == GDK_KEY_Escape) {
90         self->m_cancel();
91         gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(spin))), NULL);
92         return TRUE;
93     }
94     return FALSE;
95 }
96
97 void NonModalSpinner::connect(ui::SpinButton spin)
98 {
99     auto adj = ui::Adjustment(gtk_spin_button_get_adjustment(spin));
100     guint handler = adj.connect("value_changed", G_CALLBACK(changed), this);
101     g_object_set_data(G_OBJECT(spin), "handler", gint_to_pointer(handler));
102     spin.connect("key_press_event", G_CALLBACK(enter), this);
103     spin.connect("key_press_event", G_CALLBACK(escape), this);
104 }
105
106 void NonModalRadio::connect(ui::RadioButton radio)
107 {
108     GSList *group = gtk_radio_button_get_group(radio);
109     for (; group != 0; group = g_slist_next(group)) {
110         toggle_button_connect_callback(ui::ToggleButton(GTK_TOGGLE_BUTTON(group->data)), m_changed);
111     }
112 }