1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        src/gtk/private.cpp
3 // Purpose:     implementation of wxGTK private functions
4 // Author:      Marcin Malich
5 // Modified by:
6 // Created:     28.06.2008
7 // Copyright:   (c) 2008 Marcin Malich <me@malcom.pl>
8 // Licence:     wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 // ============================================================================
12 // declarations
13 // ============================================================================
14 
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18 
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21 
22 
23 #ifndef WX_PRECOMP
24     #include "wx/module.h"
25 #endif
26 
27 #include "wx/gtk/private.h"
28 
29 // ----------------------------------------------------------------------------
30 // wxGTKPrivate functions implementation
31 // ----------------------------------------------------------------------------
32 
33 namespace wxGTKPrivate
34 {
35 
36 static GtkWidget *gs_container = NULL;
37 
GetContainer()38 static GtkContainer* GetContainer()
39 {
40     if ( gs_container == NULL )
41     {
42         GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP);
43         gs_container = gtk_fixed_new();
44         gtk_container_add(GTK_CONTAINER(window), gs_container);
45     }
46     return GTK_CONTAINER(gs_container);
47 }
48 
GetButtonWidget()49 GtkWidget *GetButtonWidget()
50 {
51     static GtkWidget *s_button = NULL;
52 
53     if ( !s_button )
54     {
55         s_button = gtk_button_new();
56         g_object_add_weak_pointer(G_OBJECT(s_button), (void**)&s_button);
57         gtk_container_add(GetContainer(), s_button);
58         gtk_widget_realize(s_button);
59     }
60 
61     return s_button;
62 }
63 
GetNotebookWidget()64 GtkWidget *GetNotebookWidget()
65 {
66     static GtkWidget *s_notebook = NULL;
67 
68     if ( !s_notebook )
69     {
70         s_notebook = gtk_notebook_new();
71         g_object_add_weak_pointer(G_OBJECT(s_notebook), (void**)&s_notebook);
72         gtk_container_add(GetContainer(), s_notebook);
73         gtk_widget_realize(s_notebook);
74     }
75 
76     return s_notebook;
77 }
78 
GetCheckButtonWidget()79 GtkWidget *GetCheckButtonWidget()
80 {
81     static GtkWidget *s_button = NULL;
82 
83     if ( !s_button )
84     {
85         s_button = gtk_check_button_new();
86         g_object_add_weak_pointer(G_OBJECT(s_button), (void**)&s_button);
87         gtk_container_add(GetContainer(), s_button);
88         gtk_widget_realize(s_button);
89     }
90 
91     return s_button;
92 }
93 
GetComboBoxWidget()94 GtkWidget * GetComboBoxWidget()
95 {
96     static GtkWidget *s_button = NULL;
97 
98     if ( !s_button )
99     {
100         s_button = gtk_combo_box_new();
101         g_object_add_weak_pointer(G_OBJECT(s_button), (void**)&s_button);
102         gtk_container_add(GetContainer(), s_button);
103         gtk_widget_realize( s_button );
104     }
105 
106     return s_button;
107 }
108 
109 
GetEntryWidget()110 GtkWidget *GetEntryWidget()
111 {
112     static GtkWidget *s_entry = NULL;
113 
114     if ( !s_entry )
115     {
116         s_entry = gtk_entry_new();
117         g_object_add_weak_pointer(G_OBJECT(s_entry), (void**)&s_entry);
118         gtk_container_add(GetContainer(), s_entry);
119         gtk_widget_realize(s_entry);
120     }
121 
122     return s_entry;
123 }
124 
125 // This one just gets the button used by the column header. Although it's
126 // still a gtk_button the themes will typically differentiate and draw them
127 // differently if the button is in a treeview.
128 static GtkWidget *s_first_button = NULL;
129 static GtkWidget *s_other_button = NULL;
130 static GtkWidget *s_last_button = NULL;
131 
CreateHeaderButtons()132 static void CreateHeaderButtons()
133 {
134         // Get the dummy tree widget, give it a column, and then use the
135         // widget in the column header for the rendering code.
136         GtkWidget* treewidget = GetTreeWidget();
137 
138         GtkTreeViewColumn *column = gtk_tree_view_column_new();
139         gtk_tree_view_append_column(GTK_TREE_VIEW(treewidget), column);
140 #ifdef __WXGTK3__
141         s_first_button = gtk_tree_view_column_get_button(column);
142 #else
143         s_first_button = column->button;
144 #endif
145         wxASSERT(s_first_button);
146         g_object_add_weak_pointer(G_OBJECT(s_first_button), (void**)&s_first_button);
147 
148         column = gtk_tree_view_column_new();
149         gtk_tree_view_append_column(GTK_TREE_VIEW(treewidget), column);
150 #ifdef __WXGTK3__
151         s_other_button = gtk_tree_view_column_get_button(column);
152 #else
153         s_other_button = column->button;
154 #endif
155         g_object_add_weak_pointer(G_OBJECT(s_other_button), (void**)&s_other_button);
156 
157         column = gtk_tree_view_column_new();
158         gtk_tree_view_append_column(GTK_TREE_VIEW(treewidget), column);
159 #ifdef __WXGTK3__
160         s_last_button = gtk_tree_view_column_get_button(column);
161 #else
162         s_last_button = column->button;
163 #endif
164         g_object_add_weak_pointer(G_OBJECT(s_last_button), (void**)&s_last_button);
165 }
166 
GetHeaderButtonWidgetFirst()167 GtkWidget *GetHeaderButtonWidgetFirst()
168 {
169     if (!s_first_button)
170       CreateHeaderButtons();
171 
172     return s_first_button;
173 }
174 
GetHeaderButtonWidgetLast()175 GtkWidget *GetHeaderButtonWidgetLast()
176 {
177     if (!s_last_button)
178       CreateHeaderButtons();
179 
180     return s_last_button;
181 }
182 
GetHeaderButtonWidget()183 GtkWidget *GetHeaderButtonWidget()
184 {
185     if (!s_other_button)
186       CreateHeaderButtons();
187 
188     return s_other_button;
189 }
190 
GetRadioButtonWidget()191 GtkWidget * GetRadioButtonWidget()
192 {
193     static GtkWidget *s_button = NULL;
194 
195     if ( !s_button )
196     {
197         s_button = gtk_radio_button_new(NULL);
198         g_object_add_weak_pointer(G_OBJECT(s_button), (void**)&s_button);
199         gtk_container_add(GetContainer(), s_button);
200         gtk_widget_realize( s_button );
201     }
202 
203     return s_button;
204 }
205 
GetSplitterWidget(wxOrientation orient)206 GtkWidget* GetSplitterWidget(wxOrientation orient)
207 {
208     static GtkWidget* widgets[2];
209     const GtkOrientation gtkOrient =
210         orient == wxHORIZONTAL ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL;
211     GtkWidget*& widget = widgets[gtkOrient];
212     if (widget == NULL)
213     {
214 #ifdef __WXGTK3__
215         widget = gtk_paned_new(gtkOrient);
216 #else
217         if (orient == wxHORIZONTAL)
218             widget = gtk_hpaned_new();
219         else
220             widget = gtk_vpaned_new();
221 #endif
222         g_object_add_weak_pointer(G_OBJECT(widget), (void**)&widgets[gtkOrient]);
223         gtk_container_add(GetContainer(), widget);
224         gtk_widget_realize(widget);
225     }
226 
227     return widget;
228 }
229 
GetTextEntryWidget()230 GtkWidget * GetTextEntryWidget()
231 {
232     static GtkWidget *s_button = NULL;
233 
234     if ( !s_button )
235     {
236         s_button = gtk_entry_new();
237         g_object_add_weak_pointer(G_OBJECT(s_button), (void**)&s_button);
238         gtk_container_add(GetContainer(), s_button);
239         gtk_widget_realize( s_button );
240     }
241 
242     return s_button;
243 }
244 
GetTreeWidget()245 GtkWidget *GetTreeWidget()
246 {
247     static GtkWidget *s_tree = NULL;
248 
249     if ( !s_tree )
250     {
251         s_tree = gtk_tree_view_new();
252         g_object_add_weak_pointer(G_OBJECT(s_tree), (void**)&s_tree);
253         gtk_container_add(GetContainer(), s_tree);
254         gtk_widget_realize(s_tree);
255     }
256 
257     return s_tree;
258 }
259 
260 // Module for destroying created widgets
261 class WidgetsCleanupModule : public wxModule
262 {
263 public:
OnInit()264     virtual bool OnInit() wxOVERRIDE
265     {
266         return true;
267     }
268 
OnExit()269     virtual void OnExit() wxOVERRIDE
270     {
271         if ( gs_container )
272         {
273             GtkWidget* parent = gtk_widget_get_parent(gs_container);
274             gtk_widget_destroy(parent);
275             gs_container = NULL;
276         }
277     }
278 
279     wxDECLARE_DYNAMIC_CLASS(WidgetsCleanupModule);
280 };
281 
282 wxIMPLEMENT_DYNAMIC_CLASS(WidgetsCleanupModule, wxModule);
283 
284 } // wxGTKPrivate namespace
285