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 
widget_set_visible(GtkWidget * widget,bool shown)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 
widget_is_visible(GtkWidget * widget)42 inline bool widget_is_visible(GtkWidget* widget)
43 {
44   return GTK_WIDGET_VISIBLE(widget) != FALSE;
45 }
46 
widget_toggle_visible(GtkWidget * widget)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:
ToggleItem(const BoolExportCallback & exportCallback)58   ToggleItem(const BoolExportCallback& exportCallback) : m_exportCallback(exportCallback)
59   {
60   }
61 
update()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 
addCallback(const BoolImportCallback & callback)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 
notify_visible(GtkWidget * widget,gpointer dummy,ToggleShown * self)85   static gboolean notify_visible(GtkWidget* widget, gpointer dummy, ToggleShown* self)
86   {
87     self->update();
88     return FALSE;
89   }
destroy(GtkWidget * widget,ToggleShown * self)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 
ToggleShown(bool shown)100   ToggleShown(bool shown)
101     : m_shownDeferred(shown), m_widget(0), m_item(ActiveCaller(*this))
102   {
103   }
update()104   void update()
105   {
106     m_item.update();
107   }
active()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   }
exportActive(const BoolImportCallback & importCallback)119   void exportActive(const BoolImportCallback& importCallback)
120   {
121     importCallback(active());
122   }
123   typedef MemberCaller1<ToggleShown, const BoolImportCallback&, &ToggleShown::exportActive> ActiveCaller;
set(bool shown)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   }
toggle()135   void toggle()
136   {
137     widget_toggle_visible(m_widget);
138   }
139   typedef MemberCaller<ToggleShown, &ToggleShown::toggle> ToggleCaller;
connect(GtkWidget * widget)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 
widget_queue_draw(GtkWidget & widget)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 
widget_make_default(GtkWidget * widget)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
166