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