nonmodal.h

Go to the documentation of this file.
00001 /*
00002  Copyright (C) 2001-2006, William Joseph.
00003  All Rights Reserved.
00004 
00005  This file is part of GtkRadiant.
00006 
00007  GtkRadiant is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU General Public License as published by
00009  the Free Software Foundation; either version 2 of the License, or
00010  (at your option) any later version.
00011 
00012  GtkRadiant is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU General Public License for more details.
00016 
00017  You should have received a copy of the GNU General Public License
00018  along with GtkRadiant; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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

Generated by  doxygen 1.6.2