]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/frame.cpp
Use wxControl instead of wxControlWithItems with wxRTTI macros.
[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>
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
fb1585ae 76 if (height)
46dc76ba 77 {
75c9da25 78#if wxUSE_MENUS_NATIVE
047ac72b 79 // menu bar
cca410b3 80 if (m_frameMenuBar && m_frameMenuBar->IsShown())
f03fc89f 81 {
cca410b3
PC
82 GtkRequisition req;
83 gtk_widget_size_request(m_frameMenuBar->m_widget, &req);
4908591c 84#if !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
cca410b3 85 *height -= req.height;
4908591c 86#endif
f03fc89f 87 }
75c9da25 88#endif // wxUSE_MENUS_NATIVE
88ac883a 89
dcf924a3 90#if wxUSE_STATUSBAR
047ac72b 91 // status bar
cca410b3
PC
92 if (m_frameStatusBar && m_frameStatusBar->IsShown())
93 *height -= m_frameStatusBar->m_height;
93fa69f8 94#endif // wxUSE_STATUSBAR
c1fa6f52 95 }
88ac883a 96
dcf924a3 97#if wxUSE_TOOLBAR
c1fa6f52 98 // tool bar
cca410b3 99 if (m_frameToolBar && m_frameToolBar->IsShown())
c1fa6f52 100 {
cca410b3
PC
101 GtkRequisition req;
102 gtk_widget_size_request(m_frameToolBar->m_widget, &req);
e36a8aff 103 if (m_frameToolBar->IsVertical())
fb1585ae 104 {
e36a8aff 105 if (width)
cca410b3 106 *width -= req.width;
c1fa6f52
PC
107 }
108 else
109 {
e36a8aff 110 if (height)
cca410b3 111 *height -= req.height;
fb1585ae 112 }
46dc76ba 113 }
c1fa6f52
PC
114#endif // wxUSE_TOOLBAR
115
116 if (width != NULL && *width < 0)
117 *width = 0;
118 if (height != NULL && *height < 0)
119 *height = 0;
362c6693 120}
c801d85f 121
6c309653 122#if wxUSE_MENUS && wxUSE_ACCEL
e41a1b1c
JS
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;
03647350 170
e41a1b1c
JS
171 }
172
173 wxAcceleratorTable table(n, entries);
174 delete[] entries;
175
176 return table;
177}
6c309653 178#endif // wxUSE_MENUS && wxUSE_ACCEL
e41a1b1c 179
1529bc41
PC
180bool wxFrame::ShowFullScreen(bool show, long style)
181{
182 if (!wxFrameBase::ShowFullScreen(show, style))
183 return false;
184
6c309653 185#if wxUSE_MENUS && wxUSE_ACCEL
e41a1b1c
JS
186 if (show && GetMenuBar())
187 {
188 wxAcceleratorTable table(wxCreateAcceleratorTableForMenuBar(GetMenuBar()));
189 if (table.IsOk())
190 SetAcceleratorTable(table);
191 }
6c309653 192#endif // wxUSE_MENUS && wxUSE_ACCEL
e41a1b1c 193
1529bc41 194 wxWindow* const bar[] = {
28fcfbfe
VZ
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
1529bc41
PC
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
0d53fc34 238void wxFrame::OnInternalIdle()
e52f60e6 239{
e39af974 240 wxFrameBase::OnInternalIdle();
88ac883a 241
75c9da25 242#if wxUSE_MENUS_NATIVE
082b2798 243 if (m_frameMenuBar) m_frameMenuBar->OnInternalIdle();
75c9da25 244#endif // wxUSE_MENUS_NATIVE
dcf924a3 245#if wxUSE_TOOLBAR
082b2798 246 if (m_frameToolBar) m_frameToolBar->OnInternalIdle();
dcf924a3
RR
247#endif
248#if wxUSE_STATUSBAR
e4edaf5c
JS
249 if (m_frameStatusBar)
250 {
251 m_frameStatusBar->OnInternalIdle();
252
253 // There may be controls in the status bar that
254 // need to be updated
255 for ( wxWindowList::compatibility_iterator node = m_frameStatusBar->GetChildren().GetFirst();
256 node;
257 node = node->GetNext() )
258 {
259 wxWindow *child = node->GetData();
260 child->OnInternalIdle();
261 }
262 }
dcf924a3 263#endif
362c6693 264}
c801d85f 265
7c0ea335
VZ
266// ----------------------------------------------------------------------------
267// menu/tool/status bar stuff
268// ----------------------------------------------------------------------------
c801d85f 269
6522713c 270#if wxUSE_MENUS_NATIVE
1e6feb95 271
0d53fc34 272void wxFrame::DetachMenuBar()
c801d85f 273{
223d09f6
KB
274 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
275 wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
8bbe427f 276
6522713c 277 if ( m_frameMenuBar )
186baeb2 278 {
426d19f1 279#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
e2f3bc41 280 hildon_window_set_menu(HILDON_WINDOW(m_widget), NULL);
426d19f1 281#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
186baeb2 282 gtk_widget_ref( m_frameMenuBar->m_widget );
f283a575
RR
283
284 gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget );
426d19f1 285#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2 /!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
186baeb2
RR
286 }
287
6522713c 288 wxFrameBase::DetachMenuBar();
cca410b3
PC
289
290 // make sure next size_allocate causes a wxSizeEvent
291 m_oldClientWidth = 0;
6522713c
VZ
292}
293
0d53fc34 294void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
6522713c
VZ
295{
296 wxFrameBase::AttachMenuBar(menuBar);
8bbe427f 297
f5368809 298 if (m_frameMenuBar)
30dea054 299 {
426d19f1 300#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
e2f3bc41
VZ
301 hildon_window_set_menu(HILDON_WINDOW(m_widget),
302 GTK_MENU(m_frameMenuBar->m_menubar));
426d19f1 303#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
186baeb2 304 m_frameMenuBar->SetParent(this);
91af0895 305
cca410b3
PC
306 // menubar goes into top of vbox (m_mainWidget)
307 gtk_box_pack_start(
308 GTK_BOX(m_mainWidget), menuBar->m_widget, false, false, 0);
309 gtk_box_reorder_child(GTK_BOX(m_mainWidget), menuBar->m_widget, 0);
2b5f62a0 310
cca410b3
PC
311 // disconnect wxWindowGTK "size_request" handler,
312 // it interferes with sizing of detached GtkHandleBox
313 gulong handler_id = g_signal_handler_find(
314 menuBar->m_widget,
315 GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
316 g_signal_lookup("size_request", GTK_TYPE_WIDGET),
317 0, NULL, NULL, menuBar);
318 if (handler_id != 0)
319 g_signal_handler_disconnect(menuBar->m_widget, handler_id);
2b5f62a0 320
cca410b3
PC
321 // reset size request to allow native sizing to work
322 gtk_widget_set_size_request(menuBar->m_widget, -1, -1);
91af0895 323
cca410b3 324 gtk_widget_show( m_frameMenuBar->m_widget );
426d19f1 325#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
8c70a789 326 }
cca410b3
PC
327 // make sure next size_allocate causes a wxSizeEvent
328 m_oldClientWidth = 0;
1d66b099 329}
6522713c 330#endif // wxUSE_MENUS_NATIVE
1e6feb95 331
88ac883a 332#if wxUSE_TOOLBAR
1e6feb95 333
0d53fc34 334void wxFrame::SetToolBar(wxToolBar *toolbar)
7beba2fc 335{
cca410b3
PC
336 m_frameToolBar = toolbar;
337 if (toolbar)
307f16e8 338 {
cca410b3 339 if (toolbar->IsVertical())
307f16e8 340 {
cca410b3
PC
341 // Vertical toolbar and m_wxwindow go into an hbox, inside the
342 // vbox (m_mainWidget). hbox is created on demand.
343 GtkWidget* hbox = m_wxwindow->parent;
344 if (!GTK_IS_HBOX(hbox))
345 {
346 hbox = gtk_hbox_new(false, 0);
347 gtk_widget_show(hbox);
348 gtk_container_add(GTK_CONTAINER(m_mainWidget), hbox);
349 gtk_widget_reparent(m_wxwindow, hbox);
350 }
351 gtk_widget_reparent(toolbar->m_widget, hbox);
352 gtk_box_set_child_packing(GTK_BOX(hbox),
353 toolbar->m_widget, false, false, 0, GTK_PACK_START);
354
355 int pos = 0; // left
356 if (toolbar->HasFlag(wxTB_RIGHT))
357 pos = 1; // right
358 gtk_box_reorder_child(GTK_BOX(hbox), toolbar->m_widget, pos);
7beba2fc 359 }
cca410b3 360 else
94f14509 361 {
cca410b3
PC
362 // Horizontal toolbar goes into vbox (m_mainWidget)
363 gtk_widget_reparent(toolbar->m_widget, m_mainWidget);
364 gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
365 toolbar->m_widget, false, false, 0, GTK_PACK_START);
366
367 int pos = 0; // top
368 if (m_frameMenuBar)
369 pos = 1; // below menubar
370 if (toolbar->HasFlag(wxTB_BOTTOM))
371 pos += 2; // below client area (m_wxwindow)
372 gtk_box_reorder_child(
373 GTK_BOX(m_mainWidget), toolbar->m_widget, pos);
94f14509 374 }
383144c7 375
cca410b3
PC
376 // disconnect wxWindowGTK "size_request" handler,
377 // it interferes with sizing of detached GtkHandleBox
378 gulong handler_id = g_signal_handler_find(
379 toolbar->m_widget,
380 GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
381 g_signal_lookup("size_request", GTK_TYPE_WIDGET),
382 0, NULL, NULL, toolbar);
383 if (handler_id != 0)
384 g_signal_handler_disconnect(toolbar->m_widget, handler_id);
385
386 // reset size request to allow native sizing to work
387 gtk_widget_set_size_request(toolbar->m_widget, -1, -1);
388 }
389 // make sure next size_allocate causes a wxSizeEvent
390 m_oldClientWidth = 0;
307f16e8
RR
391}
392
88ac883a 393#endif // wxUSE_TOOLBAR
46dc76ba 394
88ac883a 395#if wxUSE_STATUSBAR
8bbe427f 396
3851e479
RR
397void wxFrame::SetStatusBar(wxStatusBar *statbar)
398{
cca410b3
PC
399 m_frameStatusBar = statbar;
400 if (statbar)
401 {
402 // statusbar goes into bottom of vbox (m_mainWidget)
403 gtk_widget_reparent(statbar->m_widget, m_mainWidget);
404 gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
405 statbar->m_widget, false, false, 0, GTK_PACK_END);
406 // make sure next size_allocate on statusbar causes a size event
407 statbar->m_oldClientWidth = 0;
408 }
409 // make sure next size_allocate causes a wxSizeEvent
410 m_oldClientWidth = 0;
8febdd39 411}
88ac883a 412#endif // wxUSE_STATUSBAR