3bfa1fcaddbb323d9f59792bce24ceb1f75dc5cc
[xonotic/netradiant.git] / libs / gtkutil / widget.h
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #if !defined(INCLUDED_GTKUTIL_WIDGET_H)
23 #define INCLUDED_GTKUTIL_WIDGET_H
24
25 #include <list>
26 #include <gtk/gtkwidget.h>
27 #include "generic/callback.h"
28 #include "warnings.h"
29
30 inline void widget_set_visible(GtkWidget* widget, bool shown)
31 {
32   if(shown)
33   {
34     gtk_widget_show(widget);
35   }
36   else
37   {
38     gtk_widget_hide(widget);
39   }
40 }
41
42 inline bool widget_is_visible(GtkWidget* widget)
43 {
44   return GTK_WIDGET_VISIBLE(widget) != FALSE;
45 }
46
47 inline void widget_toggle_visible(GtkWidget* widget)
48 {
49   widget_set_visible(widget, !widget_is_visible(widget));
50 }
51
52 class ToggleItem
53 {
54   BoolExportCallback m_exportCallback;
55   typedef std::list<BoolImportCallback> ImportCallbacks;
56   ImportCallbacks m_importCallbacks;
57 public:
58   ToggleItem(const BoolExportCallback& exportCallback) : m_exportCallback(exportCallback)
59   {
60   }
61
62   void update()
63   {
64     for(ImportCallbacks::iterator i = m_importCallbacks.begin(); i != m_importCallbacks.end(); ++i)
65     {
66       m_exportCallback(*i);
67     }
68   }
69
70   void addCallback(const BoolImportCallback& callback)
71   {
72     m_importCallbacks.push_back(callback);
73     m_exportCallback(callback);
74   }
75   typedef MemberCaller1<ToggleItem, const BoolImportCallback&, &ToggleItem::addCallback> AddCallbackCaller;
76 };
77
78 class ToggleShown
79 {
80   bool m_shownDeferred;
81
82   ToggleShown(const ToggleShown& other); // NOT COPYABLE
83   ToggleShown& operator=(const ToggleShown& other); // NOT ASSIGNABLE
84
85   static gboolean notify_visible(GtkWidget* widget, gpointer dummy, ToggleShown* self)
86   {
87     self->update();
88     return FALSE;
89   }
90   static gboolean destroy(GtkWidget* widget, ToggleShown* self)
91   {
92     self->m_shownDeferred = GTK_WIDGET_VISIBLE(self->m_widget) != FALSE;
93     self->m_widget = 0;
94     return FALSE;
95   }
96 public:
97   GtkWidget* m_widget;
98   ToggleItem m_item;
99
100   ToggleShown(bool shown)
101     : m_shownDeferred(shown), m_widget(0), m_item(ActiveCaller(*this))
102   {
103   }
104   void update()
105   {
106     m_item.update();
107   }
108   bool active() const
109   {
110     if(m_widget == 0)
111     {
112       return m_shownDeferred;
113     }
114     else
115     {
116       return GTK_WIDGET_VISIBLE(m_widget) != FALSE;
117     }
118   }
119   void exportActive(const BoolImportCallback& importCallback)
120   {
121     importCallback(active());
122   }
123   typedef MemberCaller1<ToggleShown, const BoolImportCallback&, &ToggleShown::exportActive> ActiveCaller;
124   void set(bool shown)
125   {
126     if(m_widget == 0)
127     {
128       m_shownDeferred = shown;
129     }
130     else
131     {
132       widget_set_visible(m_widget, shown);
133     }
134   }
135   void toggle()
136   {
137     widget_toggle_visible(m_widget);
138   }
139   typedef MemberCaller<ToggleShown, &ToggleShown::toggle> ToggleCaller;
140   void connect(GtkWidget* widget)
141   {
142     m_widget = widget;
143     widget_set_visible(m_widget, m_shownDeferred);
144     g_signal_connect(G_OBJECT(m_widget), "notify::visible", G_CALLBACK(notify_visible), this);
145     g_signal_connect(G_OBJECT(m_widget), "destroy", G_CALLBACK(destroy), this);
146     update();
147   }
148 };
149
150
151 inline void widget_queue_draw(GtkWidget& widget)
152 {
153   gtk_widget_queue_draw(&widget);
154 }
155 typedef ReferenceCaller<GtkWidget, widget_queue_draw> WidgetQueueDrawCaller;
156
157
158 inline void widget_make_default(GtkWidget* widget)
159 {
160   GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_DEFAULT);
161   gtk_widget_grab_default(widget);
162 }
163
164
165 #endif