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