00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if !defined(INCLUDED_GTKUTIL_NONMODAL_H)
00023 #define INCLUDED_GTKUTIL_NONMODAL_H
00024
00025 #include <gtk/gtk.h>
00026 #include <gdk/gdkkeysyms.h>
00027
00028 #include "generic/callback.h"
00029
00030 #include "pointer.h"
00031 #include "button.h"
00032
00033 typedef struct _GtkEntry GtkEntry;
00034
00035 inline gboolean escape_clear_focus_widget (GtkWidget* widget, GdkEventKey* event, gpointer data)
00036 {
00037 if (event->keyval == GDK_Escape) {
00038 gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(widget))), NULL);
00039 return TRUE;
00040 }
00041 return FALSE;
00042 }
00043
00044 inline void widget_connect_escape_clear_focus_widget (GtkWidget* widget)
00045 {
00046 g_signal_connect(G_OBJECT(widget), "key_press_event", G_CALLBACK(escape_clear_focus_widget), 0);
00047 }
00048
00049 class NonModalEntry
00050 {
00051 bool m_editing;
00052 Callback m_apply;
00053 Callback m_cancel;
00054
00055 static gboolean focus_in (GtkEntry* entry, GdkEventFocus *event, NonModalEntry* self)
00056 {
00057 self->m_editing = false;
00058 return FALSE;
00059 }
00060
00061 static gboolean focus_out (GtkEntry* entry, GdkEventFocus *event, NonModalEntry* self)
00062 {
00063 if (self->m_editing && GTK_WIDGET_VISIBLE(entry)) {
00064 self->m_apply();
00065 }
00066 self->m_editing = false;
00067 return FALSE;
00068 }
00069
00070 static gboolean changed (GtkEntry* entry, NonModalEntry* self)
00071 {
00072 self->m_editing = true;
00073 return FALSE;
00074 }
00075
00076 static gboolean enter (GtkEntry* entry, GdkEventKey* event, NonModalEntry* self)
00077 {
00078 if (event->keyval == GDK_Return) {
00079 self->m_apply();
00080 self->m_editing = false;
00081 gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(entry))), NULL);
00082 return TRUE;
00083 }
00084 return FALSE;
00085 }
00086
00087 static gboolean escape (GtkEntry* entry, GdkEventKey* event, NonModalEntry* self)
00088 {
00089 if (event->keyval == GDK_Escape) {
00090 self->m_cancel();
00091 self->m_editing = false;
00092 gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(entry))), NULL);
00093 return TRUE;
00094 }
00095 return FALSE;
00096 }
00097
00098 public:
00099 NonModalEntry (const Callback& apply, const Callback& cancel) :
00100 m_editing(false), m_apply(apply), m_cancel(cancel)
00101 {
00102 }
00103 void connect (GtkEntry* entry)
00104 {
00105 g_signal_connect(G_OBJECT(entry), "focus_in_event", G_CALLBACK(focus_in), this);
00106 g_signal_connect(G_OBJECT(entry), "focus_out_event", G_CALLBACK(focus_out), this);
00107 g_signal_connect(G_OBJECT(entry), "key_press_event", G_CALLBACK(enter), this);
00108 g_signal_connect(G_OBJECT(entry), "key_press_event", G_CALLBACK(escape), this);
00109 g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(changed), this);
00110 }
00111 };
00112
00113 class NonModalSpinner
00114 {
00115 Callback m_apply;
00116 Callback m_cancel;
00117
00118 static gboolean changed (GtkSpinButton* spin, NonModalSpinner* self)
00119 {
00120 self->m_apply();
00121 return FALSE;
00122 }
00123
00124 static gboolean enter (GtkSpinButton* spin, GdkEventKey* event, NonModalSpinner* self)
00125 {
00126 if (event->keyval == GDK_Return) {
00127 gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(spin))), NULL);
00128 return TRUE;
00129 }
00130 return FALSE;
00131 }
00132
00133 static gboolean escape (GtkSpinButton* spin, GdkEventKey* event, NonModalSpinner* self)
00134 {
00135 if (event->keyval == GDK_Escape) {
00136 self->m_cancel();
00137 gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(spin))), NULL);
00138 return TRUE;
00139 }
00140 return FALSE;
00141 }
00142
00143 public:
00144 NonModalSpinner (const Callback& apply, const Callback& cancel) :
00145 m_apply(apply), m_cancel(cancel)
00146 {
00147 }
00148 void connect (GtkSpinButton* spin)
00149 {
00150 guint
00151 handler =
00152 g_signal_connect(G_OBJECT(gtk_spin_button_get_adjustment(spin)), "value_changed", G_CALLBACK(changed), this);
00153 g_object_set_data(G_OBJECT(spin), "handler", gint_to_pointer(handler));
00154 g_signal_connect(G_OBJECT(spin), "key_press_event", G_CALLBACK(enter), this);
00155 g_signal_connect(G_OBJECT(spin), "key_press_event", G_CALLBACK(escape), this);
00156 }
00157 };
00158
00159 class NonModalRadio
00160 {
00161 Callback m_changed;
00162
00163 public:
00164 NonModalRadio (const Callback& changed) :
00165 m_changed(changed)
00166 {
00167 }
00168 void connect (GtkRadioButton* radio)
00169 {
00170 GSList* group = gtk_radio_button_group(radio);
00171 for (; group != 0; group = g_slist_next(group)) {
00172 toggle_button_connect_callback(GTK_TOGGLE_BUTTON(group->data), m_changed);
00173 }
00174 }
00175 };
00176
00177 #endif