]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/frame.cpp
Add wxControlWithItems::SendSelectionChangedEvent() helper.
[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
fb1585ae 77 if (height)
46dc76ba 78 {
75c9da25 79#if wxUSE_MENUS_NATIVE
047ac72b 80 // menu bar
cca410b3 81 if (m_frameMenuBar && m_frameMenuBar->IsShown())
f03fc89f 82 {
1897abe1
PC
83 int h;
84 gtk_widget_get_preferred_height(m_frameMenuBar->m_widget, NULL, &h);
4908591c 85#if !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
1897abe1 86 *height -= h;
4908591c 87#endif
f03fc89f 88 }
75c9da25 89#endif // wxUSE_MENUS_NATIVE
88ac883a 90
dcf924a3 91#if wxUSE_STATUSBAR
047ac72b 92 // status bar
cca410b3
PC
93 if (m_frameStatusBar && m_frameStatusBar->IsShown())
94 *height -= m_frameStatusBar->m_height;
93fa69f8 95#endif // wxUSE_STATUSBAR
c1fa6f52 96 }
88ac883a 97
dcf924a3 98#if wxUSE_TOOLBAR
c1fa6f52 99 // tool bar
cca410b3 100 if (m_frameToolBar && m_frameToolBar->IsShown())
c1fa6f52 101 {
e36a8aff 102 if (m_frameToolBar->IsVertical())
fb1585ae 103 {
e36a8aff 104 if (width)
1897abe1
PC
105 {
106 int w;
107 gtk_widget_get_preferred_width(m_frameToolBar->m_widget, NULL, &w);
108 *width -= w;
109 }
c1fa6f52
PC
110 }
111 else
112 {
e36a8aff 113 if (height)
1897abe1
PC
114 {
115 int h;
116 gtk_widget_get_preferred_height(m_frameToolBar->m_widget, NULL, &h);
117 *height -= h;
118 }
fb1585ae 119 }
46dc76ba 120 }
c1fa6f52
PC
121#endif // wxUSE_TOOLBAR
122
123 if (width != NULL && *width < 0)
124 *width = 0;
125 if (height != NULL && *height < 0)
126 *height = 0;
362c6693 127}
c801d85f 128
6c309653 129#if wxUSE_MENUS && wxUSE_ACCEL
e41a1b1c
JS
130// Helper for wxCreateAcceleratorTableForMenuBar
131static void wxAddAccelerators(wxList& accelEntries, wxMenu* menu)
132{
133 size_t i;
134 for (i = 0; i < menu->GetMenuItems().GetCount(); i++)
135 {
136 wxMenuItem* item = (wxMenuItem*) menu->GetMenuItems().Item(i)->GetData();
137 if (item->GetSubMenu())
138 {
139 wxAddAccelerators(accelEntries, item->GetSubMenu());
140 }
141 else if (!item->GetItemLabel().IsEmpty())
142 {
143 wxAcceleratorEntry* entry = wxAcceleratorEntry::Create(item->GetItemLabel());
144 if (entry)
145 {
146 entry->Set(entry->GetFlags(), entry->GetKeyCode(), item->GetId());
147 accelEntries.Append((wxObject*) entry);
148 }
149 }
150 }
151}
152
153// Create an accelerator table consisting of all the accelerators
154// from the menubar in the given menus
155static wxAcceleratorTable wxCreateAcceleratorTableForMenuBar(wxMenuBar* menuBar)
156{
157 wxList accelEntries;
158
159 size_t i;
160 for (i = 0; i < menuBar->GetMenuCount(); i++)
161 {
162 wxAddAccelerators(accelEntries, menuBar->GetMenu(i));
163 }
164
165 size_t n = accelEntries.GetCount();
166
167 if (n == 0)
168 return wxAcceleratorTable();
169
170 wxAcceleratorEntry* entries = new wxAcceleratorEntry[n];
171
172 for (i = 0; i < accelEntries.GetCount(); i++)
173 {
174 wxAcceleratorEntry* entry = (wxAcceleratorEntry*) accelEntries.Item(i)->GetData();
175 entries[i] = (*entry);
176 delete entry;
03647350 177
e41a1b1c
JS
178 }
179
180 wxAcceleratorTable table(n, entries);
181 delete[] entries;
182
183 return table;
184}
6c309653 185#endif // wxUSE_MENUS && wxUSE_ACCEL
e41a1b1c 186
1529bc41
PC
187bool wxFrame::ShowFullScreen(bool show, long style)
188{
189 if (!wxFrameBase::ShowFullScreen(show, style))
190 return false;
191
6c309653 192#if wxUSE_MENUS && wxUSE_ACCEL
e41a1b1c
JS
193 if (show && GetMenuBar())
194 {
195 wxAcceleratorTable table(wxCreateAcceleratorTableForMenuBar(GetMenuBar()));
196 if (table.IsOk())
197 SetAcceleratorTable(table);
198 }
6c309653 199#endif // wxUSE_MENUS && wxUSE_ACCEL
e41a1b1c 200
1529bc41 201 wxWindow* const bar[] = {
28fcfbfe
VZ
202#if wxUSE_MENUS
203 m_frameMenuBar,
204#else
205 NULL,
206#endif
207#if wxUSE_TOOLBAR
208 m_frameToolBar,
209#else
210 NULL,
211#endif
212#if wxUSE_STATUSBAR
213 m_frameStatusBar,
214#else
215 NULL,
216#endif
1529bc41
PC
217 };
218 const long fsNoBar[] = {
219 wxFULLSCREEN_NOMENUBAR, wxFULLSCREEN_NOTOOLBAR, wxFULLSCREEN_NOSTATUSBAR
220 };
221 for (int i = 0; i < 3; i++)
222 {
223 if (show)
224 {
225 if (bar[i] && (style & fsNoBar[i]))
226 {
227 if (bar[i]->IsShown())
228 bar[i]->Show(false);
229 else
230 style &= ~fsNoBar[i];
231 }
232 }
233 else
234 {
235 if (bar[i] && (m_fsSaveFlag & fsNoBar[i]))
236 bar[i]->Show(true);
237 }
238 }
239 if (show)
240 m_fsSaveFlag = style;
241
242 return true;
243}
244
0c3e2a5b 245bool wxFrame::SendIdleEvents(wxIdleEvent& event)
e52f60e6 246{
0c3e2a5b 247 bool needMore = wxFrameBase::SendIdleEvents(event);
88ac883a 248
0c3e2a5b
PC
249#if wxUSE_MENUS
250 if (m_frameMenuBar && m_frameMenuBar->SendIdleEvents(event))
251 needMore = true;
252#endif
dcf924a3 253#if wxUSE_TOOLBAR
0c3e2a5b
PC
254 if (m_frameToolBar && m_frameToolBar->SendIdleEvents(event))
255 needMore = true;
dcf924a3
RR
256#endif
257#if wxUSE_STATUSBAR
0c3e2a5b
PC
258 if (m_frameStatusBar && m_frameStatusBar->SendIdleEvents(event))
259 needMore = true;
dcf924a3 260#endif
0c3e2a5b
PC
261
262 return needMore;
362c6693 263}
c801d85f 264
7c0ea335
VZ
265// ----------------------------------------------------------------------------
266// menu/tool/status bar stuff
267// ----------------------------------------------------------------------------
c801d85f 268
6522713c 269#if wxUSE_MENUS_NATIVE
1e6feb95 270
0d53fc34 271void wxFrame::DetachMenuBar()
c801d85f 272{
223d09f6
KB
273 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
274 wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
8bbe427f 275
6522713c 276 if ( m_frameMenuBar )
186baeb2 277 {
426d19f1 278#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
e2f3bc41 279 hildon_window_set_menu(HILDON_WINDOW(m_widget), NULL);
426d19f1 280#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
80b8c88a 281 g_object_ref( m_frameMenuBar->m_widget );
f283a575
RR
282
283 gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget );
426d19f1 284#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2 /!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
186baeb2
RR
285 }
286
6522713c 287 wxFrameBase::DetachMenuBar();
cca410b3
PC
288
289 // make sure next size_allocate causes a wxSizeEvent
290 m_oldClientWidth = 0;
6522713c
VZ
291}
292
0d53fc34 293void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
6522713c
VZ
294{
295 wxFrameBase::AttachMenuBar(menuBar);
8bbe427f 296
f5368809 297 if (m_frameMenuBar)
30dea054 298 {
426d19f1 299#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
e2f3bc41
VZ
300 hildon_window_set_menu(HILDON_WINDOW(m_widget),
301 GTK_MENU(m_frameMenuBar->m_menubar));
426d19f1 302#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
186baeb2 303 m_frameMenuBar->SetParent(this);
91af0895 304
cca410b3
PC
305 // menubar goes into top of vbox (m_mainWidget)
306 gtk_box_pack_start(
307 GTK_BOX(m_mainWidget), menuBar->m_widget, false, false, 0);
308 gtk_box_reorder_child(GTK_BOX(m_mainWidget), menuBar->m_widget, 0);
2b5f62a0 309
cca410b3
PC
310 // reset size request to allow native sizing to work
311 gtk_widget_set_size_request(menuBar->m_widget, -1, -1);
91af0895 312
cca410b3 313 gtk_widget_show( m_frameMenuBar->m_widget );
426d19f1 314#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
8c70a789 315 }
cca410b3
PC
316 // make sure next size_allocate causes a wxSizeEvent
317 m_oldClientWidth = 0;
1d66b099 318}
6522713c 319#endif // wxUSE_MENUS_NATIVE
1e6feb95 320
88ac883a 321#if wxUSE_TOOLBAR
1e6feb95 322
0d53fc34 323void wxFrame::SetToolBar(wxToolBar *toolbar)
7beba2fc 324{
cca410b3
PC
325 m_frameToolBar = toolbar;
326 if (toolbar)
307f16e8 327 {
cca410b3 328 if (toolbar->IsVertical())
307f16e8 329 {
cca410b3
PC
330 // Vertical toolbar and m_wxwindow go into an hbox, inside the
331 // vbox (m_mainWidget). hbox is created on demand.
385e8575 332 GtkWidget* hbox = gtk_widget_get_parent(m_wxwindow);
1897abe1 333 if (hbox == m_mainWidget)
cca410b3 334 {
1897abe1 335 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
cca410b3 336 gtk_widget_show(hbox);
1897abe1 337 gtk_box_pack_start(GTK_BOX(m_mainWidget), hbox, true, true, 0);
cca410b3
PC
338 gtk_widget_reparent(m_wxwindow, hbox);
339 }
340 gtk_widget_reparent(toolbar->m_widget, hbox);
341 gtk_box_set_child_packing(GTK_BOX(hbox),
342 toolbar->m_widget, false, false, 0, GTK_PACK_START);
343
344 int pos = 0; // left
345 if (toolbar->HasFlag(wxTB_RIGHT))
346 pos = 1; // right
347 gtk_box_reorder_child(GTK_BOX(hbox), toolbar->m_widget, pos);
7beba2fc 348 }
cca410b3 349 else
94f14509 350 {
cca410b3
PC
351 // Horizontal toolbar goes into vbox (m_mainWidget)
352 gtk_widget_reparent(toolbar->m_widget, m_mainWidget);
353 gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
354 toolbar->m_widget, false, false, 0, GTK_PACK_START);
355
356 int pos = 0; // top
357 if (m_frameMenuBar)
358 pos = 1; // below menubar
359 if (toolbar->HasFlag(wxTB_BOTTOM))
360 pos += 2; // below client area (m_wxwindow)
361 gtk_box_reorder_child(
362 GTK_BOX(m_mainWidget), toolbar->m_widget, pos);
94f14509 363 }
cca410b3
PC
364 // reset size request to allow native sizing to work
365 gtk_widget_set_size_request(toolbar->m_widget, -1, -1);
366 }
367 // make sure next size_allocate causes a wxSizeEvent
368 m_oldClientWidth = 0;
307f16e8
RR
369}
370
88ac883a 371#endif // wxUSE_TOOLBAR
46dc76ba 372
88ac883a 373#if wxUSE_STATUSBAR
8bbe427f 374
3851e479
RR
375void wxFrame::SetStatusBar(wxStatusBar *statbar)
376{
cca410b3
PC
377 m_frameStatusBar = statbar;
378 if (statbar)
379 {
380 // statusbar goes into bottom of vbox (m_mainWidget)
381 gtk_widget_reparent(statbar->m_widget, m_mainWidget);
382 gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
383 statbar->m_widget, false, false, 0, GTK_PACK_END);
384 // make sure next size_allocate on statusbar causes a size event
385 statbar->m_oldClientWidth = 0;
3b7067a0
PC
386 int h = -1;
387 if (statbar->m_wxwindow)
388 {
389 // statusbar is not a native widget, need to set height request
390 h = statbar->m_height;
391 }
392 gtk_widget_set_size_request(statbar->m_widget, -1, h);
cca410b3
PC
393 }
394 // make sure next size_allocate causes a wxSizeEvent
395 m_oldClientWidth = 0;
8febdd39 396}
88ac883a 397#endif // wxUSE_STATUSBAR