]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/frame.cpp
No changes, just minor wxMSW code cleanup: use WinStruct<>.
[wxWidgets.git] / src / gtk / frame.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/gtk/frame.cpp
3// Purpose:
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
13#include "wx/frame.h"
14
15#ifndef WX_PRECOMP
16 #include "wx/menu.h"
17 #include "wx/toolbar.h"
18 #include "wx/statusbr.h"
19#endif // WX_PRECOMP
20
21#include <gtk/gtk.h>
22
23#if wxUSE_LIBHILDON
24 #include <hildon-widgets/hildon-window.h>
25#endif // wxUSE_LIBHILDON
26
27#if wxUSE_LIBHILDON2
28 #include <hildon/hildon.h>
29#endif // wxUSE_LIBHILDON2
30
31// ----------------------------------------------------------------------------
32// event tables
33// ----------------------------------------------------------------------------
34
35// ============================================================================
36// implementation
37// ============================================================================
38
39// ----------------------------------------------------------------------------
40// wxFrame creation
41// ----------------------------------------------------------------------------
42
43void wxFrame::Init()
44{
45 m_fsSaveFlag = 0;
46}
47
48bool wxFrame::Create( wxWindow *parent,
49 wxWindowID id,
50 const wxString& title,
51 const wxPoint& pos,
52 const wxSize& sizeOrig,
53 long style,
54 const wxString &name )
55{
56 return wxFrameBase::Create(parent, id, title, pos, sizeOrig, style, name);
57}
58
59wxFrame::~wxFrame()
60{
61 SendDestroyEvent();
62
63 DeleteAllBars();
64}
65
66// ----------------------------------------------------------------------------
67// overridden wxWindow methods
68// ----------------------------------------------------------------------------
69
70void wxFrame::DoGetClientSize( int *width, int *height ) const
71{
72 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
73
74 wxFrameBase::DoGetClientSize(width, height);
75
76 if (height)
77 {
78#if wxUSE_MENUS_NATIVE
79 // menu bar
80 if (m_frameMenuBar && m_frameMenuBar->IsShown())
81 {
82 GtkRequisition req;
83 gtk_widget_size_request(m_frameMenuBar->m_widget, &req);
84#if !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
85 *height -= req.height;
86#endif
87 }
88#endif // wxUSE_MENUS_NATIVE
89
90#if wxUSE_STATUSBAR
91 // status bar
92 if (m_frameStatusBar && m_frameStatusBar->IsShown())
93 *height -= m_frameStatusBar->m_height;
94#endif // wxUSE_STATUSBAR
95 }
96
97#if wxUSE_TOOLBAR
98 // tool bar
99 if (m_frameToolBar && m_frameToolBar->IsShown())
100 {
101 GtkRequisition req;
102 gtk_widget_size_request(m_frameToolBar->m_widget, &req);
103 if (m_frameToolBar->IsVertical())
104 {
105 if (width)
106 *width -= req.width;
107 }
108 else
109 {
110 if (height)
111 *height -= req.height;
112 }
113 }
114#endif // wxUSE_TOOLBAR
115
116 if (width != NULL && *width < 0)
117 *width = 0;
118 if (height != NULL && *height < 0)
119 *height = 0;
120}
121
122#if wxUSE_MENUS && wxUSE_ACCEL
123// Helper for wxCreateAcceleratorTableForMenuBar
124static void wxAddAccelerators(wxList& accelEntries, wxMenu* menu)
125{
126 size_t i;
127 for (i = 0; i < menu->GetMenuItems().GetCount(); i++)
128 {
129 wxMenuItem* item = (wxMenuItem*) menu->GetMenuItems().Item(i)->GetData();
130 if (item->GetSubMenu())
131 {
132 wxAddAccelerators(accelEntries, item->GetSubMenu());
133 }
134 else if (!item->GetItemLabel().IsEmpty())
135 {
136 wxAcceleratorEntry* entry = wxAcceleratorEntry::Create(item->GetItemLabel());
137 if (entry)
138 {
139 entry->Set(entry->GetFlags(), entry->GetKeyCode(), item->GetId());
140 accelEntries.Append((wxObject*) entry);
141 }
142 }
143 }
144}
145
146// Create an accelerator table consisting of all the accelerators
147// from the menubar in the given menus
148static wxAcceleratorTable wxCreateAcceleratorTableForMenuBar(wxMenuBar* menuBar)
149{
150 wxList accelEntries;
151
152 size_t i;
153 for (i = 0; i < menuBar->GetMenuCount(); i++)
154 {
155 wxAddAccelerators(accelEntries, menuBar->GetMenu(i));
156 }
157
158 size_t n = accelEntries.GetCount();
159
160 if (n == 0)
161 return wxAcceleratorTable();
162
163 wxAcceleratorEntry* entries = new wxAcceleratorEntry[n];
164
165 for (i = 0; i < accelEntries.GetCount(); i++)
166 {
167 wxAcceleratorEntry* entry = (wxAcceleratorEntry*) accelEntries.Item(i)->GetData();
168 entries[i] = (*entry);
169 delete entry;
170
171 }
172
173 wxAcceleratorTable table(n, entries);
174 delete[] entries;
175
176 return table;
177}
178#endif // wxUSE_MENUS && wxUSE_ACCEL
179
180bool wxFrame::ShowFullScreen(bool show, long style)
181{
182 if (!wxFrameBase::ShowFullScreen(show, style))
183 return false;
184
185#if wxUSE_MENUS && wxUSE_ACCEL
186 if (show && GetMenuBar())
187 {
188 wxAcceleratorTable table(wxCreateAcceleratorTableForMenuBar(GetMenuBar()));
189 if (table.IsOk())
190 SetAcceleratorTable(table);
191 }
192#endif // wxUSE_MENUS && wxUSE_ACCEL
193
194 wxWindow* const bar[] = {
195#if wxUSE_MENUS
196 m_frameMenuBar,
197#else
198 NULL,
199#endif
200#if wxUSE_TOOLBAR
201 m_frameToolBar,
202#else
203 NULL,
204#endif
205#if wxUSE_STATUSBAR
206 m_frameStatusBar,
207#else
208 NULL,
209#endif
210 };
211 const long fsNoBar[] = {
212 wxFULLSCREEN_NOMENUBAR, wxFULLSCREEN_NOTOOLBAR, wxFULLSCREEN_NOSTATUSBAR
213 };
214 for (int i = 0; i < 3; i++)
215 {
216 if (show)
217 {
218 if (bar[i] && (style & fsNoBar[i]))
219 {
220 if (bar[i]->IsShown())
221 bar[i]->Show(false);
222 else
223 style &= ~fsNoBar[i];
224 }
225 }
226 else
227 {
228 if (bar[i] && (m_fsSaveFlag & fsNoBar[i]))
229 bar[i]->Show(true);
230 }
231 }
232 if (show)
233 m_fsSaveFlag = style;
234
235 return true;
236}
237
238bool wxFrame::SendIdleEvents(wxIdleEvent& event)
239{
240 bool needMore = wxFrameBase::SendIdleEvents(event);
241
242#if wxUSE_MENUS
243 if (m_frameMenuBar && m_frameMenuBar->SendIdleEvents(event))
244 needMore = true;
245#endif
246#if wxUSE_TOOLBAR
247 if (m_frameToolBar && m_frameToolBar->SendIdleEvents(event))
248 needMore = true;
249#endif
250#if wxUSE_STATUSBAR
251 if (m_frameStatusBar && m_frameStatusBar->SendIdleEvents(event))
252 needMore = true;
253#endif
254
255 return needMore;
256}
257
258// ----------------------------------------------------------------------------
259// menu/tool/status bar stuff
260// ----------------------------------------------------------------------------
261
262#if wxUSE_MENUS_NATIVE
263
264void wxFrame::DetachMenuBar()
265{
266 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
267 wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
268
269 if ( m_frameMenuBar )
270 {
271#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
272 hildon_window_set_menu(HILDON_WINDOW(m_widget), NULL);
273#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
274 g_object_ref( m_frameMenuBar->m_widget );
275
276 gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget );
277#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2 /!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
278 }
279
280 wxFrameBase::DetachMenuBar();
281
282 // make sure next size_allocate causes a wxSizeEvent
283 m_oldClientWidth = 0;
284}
285
286void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
287{
288 wxFrameBase::AttachMenuBar(menuBar);
289
290 if (m_frameMenuBar)
291 {
292#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
293 hildon_window_set_menu(HILDON_WINDOW(m_widget),
294 GTK_MENU(m_frameMenuBar->m_menubar));
295#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
296 m_frameMenuBar->SetParent(this);
297
298 // menubar goes into top of vbox (m_mainWidget)
299 gtk_box_pack_start(
300 GTK_BOX(m_mainWidget), menuBar->m_widget, false, false, 0);
301 gtk_box_reorder_child(GTK_BOX(m_mainWidget), menuBar->m_widget, 0);
302
303 // disconnect wxWindowGTK "size_request" handler,
304 // it interferes with sizing of detached GtkHandleBox
305 gulong handler_id = g_signal_handler_find(
306 menuBar->m_widget,
307 GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
308 g_signal_lookup("size_request", GTK_TYPE_WIDGET),
309 0, NULL, NULL, menuBar);
310 if (handler_id != 0)
311 g_signal_handler_disconnect(menuBar->m_widget, handler_id);
312
313 // reset size request to allow native sizing to work
314 gtk_widget_set_size_request(menuBar->m_widget, -1, -1);
315
316 gtk_widget_show( m_frameMenuBar->m_widget );
317#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
318 }
319 // make sure next size_allocate causes a wxSizeEvent
320 m_oldClientWidth = 0;
321}
322#endif // wxUSE_MENUS_NATIVE
323
324#if wxUSE_TOOLBAR
325
326void wxFrame::SetToolBar(wxToolBar *toolbar)
327{
328 m_frameToolBar = toolbar;
329 if (toolbar)
330 {
331 if (toolbar->IsVertical())
332 {
333 // Vertical toolbar and m_wxwindow go into an hbox, inside the
334 // vbox (m_mainWidget). hbox is created on demand.
335 GtkWidget* hbox = gtk_widget_get_parent(m_wxwindow);
336 if (!GTK_IS_HBOX(hbox))
337 {
338 hbox = gtk_hbox_new(false, 0);
339 gtk_widget_show(hbox);
340 gtk_container_add(GTK_CONTAINER(m_mainWidget), hbox);
341 gtk_widget_reparent(m_wxwindow, hbox);
342 }
343 gtk_widget_reparent(toolbar->m_widget, hbox);
344 gtk_box_set_child_packing(GTK_BOX(hbox),
345 toolbar->m_widget, false, false, 0, GTK_PACK_START);
346
347 int pos = 0; // left
348 if (toolbar->HasFlag(wxTB_RIGHT))
349 pos = 1; // right
350 gtk_box_reorder_child(GTK_BOX(hbox), toolbar->m_widget, pos);
351 }
352 else
353 {
354 // Horizontal toolbar goes into vbox (m_mainWidget)
355 gtk_widget_reparent(toolbar->m_widget, m_mainWidget);
356 gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
357 toolbar->m_widget, false, false, 0, GTK_PACK_START);
358
359 int pos = 0; // top
360 if (m_frameMenuBar)
361 pos = 1; // below menubar
362 if (toolbar->HasFlag(wxTB_BOTTOM))
363 pos += 2; // below client area (m_wxwindow)
364 gtk_box_reorder_child(
365 GTK_BOX(m_mainWidget), toolbar->m_widget, pos);
366 }
367
368 // disconnect wxWindowGTK "size_request" handler,
369 // it interferes with sizing of detached GtkHandleBox
370 gulong handler_id = g_signal_handler_find(
371 toolbar->m_widget,
372 GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
373 g_signal_lookup("size_request", GTK_TYPE_WIDGET),
374 0, NULL, NULL, toolbar);
375 if (handler_id != 0)
376 g_signal_handler_disconnect(toolbar->m_widget, handler_id);
377
378 // reset size request to allow native sizing to work
379 gtk_widget_set_size_request(toolbar->m_widget, -1, -1);
380 }
381 // make sure next size_allocate causes a wxSizeEvent
382 m_oldClientWidth = 0;
383}
384
385#endif // wxUSE_TOOLBAR
386
387#if wxUSE_STATUSBAR
388
389void wxFrame::SetStatusBar(wxStatusBar *statbar)
390{
391 m_frameStatusBar = statbar;
392 if (statbar)
393 {
394 // statusbar goes into bottom of vbox (m_mainWidget)
395 gtk_widget_reparent(statbar->m_widget, m_mainWidget);
396 gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
397 statbar->m_widget, false, false, 0, GTK_PACK_END);
398 // make sure next size_allocate on statusbar causes a size event
399 statbar->m_oldClientWidth = 0;
400 }
401 // make sure next size_allocate causes a wxSizeEvent
402 m_oldClientWidth = 0;
403}
404#endif // wxUSE_STATUSBAR