]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/frame.cpp
no real changes, just move wxMask::GetBitmap() to wxMask section
[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#include "wx/gtk/private/gtk2-compat.h"
23
24#if wxUSE_LIBHILDON
25 #include <hildon-widgets/hildon-window.h>
26#endif // wxUSE_LIBHILDON
27
28#if wxUSE_LIBHILDON2
29 #include <hildon/hildon.h>
30#endif // wxUSE_LIBHILDON2
31
32// ----------------------------------------------------------------------------
33// event tables
34// ----------------------------------------------------------------------------
35
36// ============================================================================
37// implementation
38// ============================================================================
39
40// ----------------------------------------------------------------------------
41// wxFrame creation
42// ----------------------------------------------------------------------------
43
44void wxFrame::Init()
45{
46 m_fsSaveFlag = 0;
47}
48
49bool wxFrame::Create( wxWindow *parent,
50 wxWindowID id,
51 const wxString& title,
52 const wxPoint& pos,
53 const wxSize& sizeOrig,
54 long style,
55 const wxString &name )
56{
57 return wxFrameBase::Create(parent, id, title, pos, sizeOrig, style, name);
58}
59
60wxFrame::~wxFrame()
61{
62 SendDestroyEvent();
63
64 DeleteAllBars();
65}
66
67// ----------------------------------------------------------------------------
68// overridden wxWindow methods
69// ----------------------------------------------------------------------------
70
71void wxFrame::DoGetClientSize( int *width, int *height ) const
72{
73 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
74
75 wxFrameBase::DoGetClientSize(width, height);
76
77 if (m_useCachedClientSize)
78 return;
79
80 if (height)
81 {
82#if wxUSE_MENUS_NATIVE
83 // menu bar
84 if (m_frameMenuBar && m_frameMenuBar->IsShown())
85 {
86 int h;
87 gtk_widget_get_preferred_height(m_frameMenuBar->m_widget, NULL, &h);
88#if !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
89 *height -= h;
90#endif
91 }
92#endif // wxUSE_MENUS_NATIVE
93
94#if wxUSE_STATUSBAR
95 // status bar
96 if (m_frameStatusBar && m_frameStatusBar->IsShown())
97 *height -= m_frameStatusBar->m_height;
98#endif // wxUSE_STATUSBAR
99 }
100
101#if wxUSE_TOOLBAR
102 // tool bar
103 if (m_frameToolBar && m_frameToolBar->IsShown())
104 {
105 if (m_frameToolBar->IsVertical())
106 {
107 if (width)
108 {
109 int w;
110 gtk_widget_get_preferred_width(m_frameToolBar->m_widget, NULL, &w);
111 *width -= w;
112 }
113 }
114 else
115 {
116 if (height)
117 {
118 int h;
119 gtk_widget_get_preferred_height(m_frameToolBar->m_widget, NULL, &h);
120 *height -= h;
121 }
122 }
123 }
124#endif // wxUSE_TOOLBAR
125
126 if (width != NULL && *width < 0)
127 *width = 0;
128 if (height != NULL && *height < 0)
129 *height = 0;
130}
131
132#if wxUSE_MENUS && wxUSE_ACCEL
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;
180
181 }
182
183 wxAcceleratorTable table(n, entries);
184 delete[] entries;
185
186 return table;
187}
188#endif // wxUSE_MENUS && wxUSE_ACCEL
189
190bool wxFrame::ShowFullScreen(bool show, long style)
191{
192 if (!wxFrameBase::ShowFullScreen(show, style))
193 return false;
194
195#if wxUSE_MENUS && wxUSE_ACCEL
196 if (show && GetMenuBar())
197 {
198 wxAcceleratorTable table(wxCreateAcceleratorTableForMenuBar(GetMenuBar()));
199 if (table.IsOk())
200 SetAcceleratorTable(table);
201 }
202#endif // wxUSE_MENUS && wxUSE_ACCEL
203
204 wxWindow* const bar[] = {
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
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
248bool wxFrame::SendIdleEvents(wxIdleEvent& event)
249{
250 bool needMore = wxFrameBase::SendIdleEvents(event);
251
252#if wxUSE_MENUS
253 if (m_frameMenuBar && m_frameMenuBar->SendIdleEvents(event))
254 needMore = true;
255#endif
256#if wxUSE_TOOLBAR
257 if (m_frameToolBar && m_frameToolBar->SendIdleEvents(event))
258 needMore = true;
259#endif
260#if wxUSE_STATUSBAR
261 if (m_frameStatusBar && m_frameStatusBar->SendIdleEvents(event))
262 needMore = true;
263#endif
264
265 return needMore;
266}
267
268// ----------------------------------------------------------------------------
269// menu/tool/status bar stuff
270// ----------------------------------------------------------------------------
271
272#if wxUSE_MENUS_NATIVE
273
274void wxFrame::DetachMenuBar()
275{
276 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
277 wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
278
279 if ( m_frameMenuBar )
280 {
281#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
282 hildon_window_set_menu(HILDON_WINDOW(m_widget), NULL);
283#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
284 g_object_ref( m_frameMenuBar->m_widget );
285
286 gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget );
287#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2 /!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
288 }
289
290 wxFrameBase::DetachMenuBar();
291
292 // make sure next size_allocate causes a wxSizeEvent
293 m_useCachedClientSize = false;
294 m_clientWidth = 0;
295}
296
297void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
298{
299 wxFrameBase::AttachMenuBar(menuBar);
300
301 if (m_frameMenuBar)
302 {
303#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
304 hildon_window_set_menu(HILDON_WINDOW(m_widget),
305 GTK_MENU(m_frameMenuBar->m_widget));
306#else // !wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
307 m_frameMenuBar->SetParent(this);
308
309 // menubar goes into top of vbox (m_mainWidget)
310 gtk_box_pack_start(
311 GTK_BOX(m_mainWidget), menuBar->m_widget, false, false, 0);
312 gtk_box_reorder_child(GTK_BOX(m_mainWidget), menuBar->m_widget, 0);
313
314 // reset size request to allow native sizing to work
315 gtk_widget_set_size_request(menuBar->m_widget, -1, -1);
316
317 gtk_widget_show( m_frameMenuBar->m_widget );
318#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
319 }
320 // make sure next size_allocate causes a wxSizeEvent
321 m_useCachedClientSize = false;
322 m_clientWidth = 0;
323}
324#endif // wxUSE_MENUS_NATIVE
325
326#if wxUSE_TOOLBAR
327
328void wxFrame::SetToolBar(wxToolBar *toolbar)
329{
330 m_frameToolBar = toolbar;
331 if (toolbar)
332 {
333 if (toolbar->IsVertical())
334 {
335 // Vertical toolbar and m_wxwindow go into an hbox, inside the
336 // vbox (m_mainWidget). hbox is created on demand.
337 GtkWidget* hbox = gtk_widget_get_parent(m_wxwindow);
338 if (hbox == m_mainWidget)
339 {
340 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
341 gtk_widget_show(hbox);
342 gtk_box_pack_start(GTK_BOX(m_mainWidget), hbox, true, true, 0);
343 gtk_widget_reparent(m_wxwindow, hbox);
344 }
345 gtk_widget_reparent(toolbar->m_widget, hbox);
346 gtk_box_set_child_packing(GTK_BOX(hbox),
347 toolbar->m_widget, false, false, 0, GTK_PACK_START);
348
349 int pos = 0; // left
350 if (toolbar->HasFlag(wxTB_RIGHT))
351 pos = 1; // right
352 gtk_box_reorder_child(GTK_BOX(hbox), toolbar->m_widget, pos);
353 }
354 else
355 {
356 // Horizontal toolbar goes into vbox (m_mainWidget)
357 gtk_widget_reparent(toolbar->m_widget, m_mainWidget);
358 gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
359 toolbar->m_widget, false, false, 0, GTK_PACK_START);
360
361 int pos = 0; // top
362 if (m_frameMenuBar)
363 pos = 1; // below menubar
364 if (toolbar->HasFlag(wxTB_BOTTOM))
365 pos += 2; // below client area (m_wxwindow)
366 gtk_box_reorder_child(
367 GTK_BOX(m_mainWidget), toolbar->m_widget, pos);
368 }
369 // reset size request to allow native sizing to work
370 gtk_widget_set_size_request(toolbar->m_widget, -1, -1);
371 }
372 // make sure next size_allocate causes a wxSizeEvent
373 m_useCachedClientSize = false;
374 m_clientWidth = 0;
375}
376
377#endif // wxUSE_TOOLBAR
378
379#if wxUSE_STATUSBAR
380
381void wxFrame::SetStatusBar(wxStatusBar *statbar)
382{
383 m_frameStatusBar = statbar;
384 if (statbar)
385 {
386 // statusbar goes into bottom of vbox (m_mainWidget)
387 gtk_widget_reparent(statbar->m_widget, m_mainWidget);
388 gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
389 statbar->m_widget, false, false, 0, GTK_PACK_END);
390 // make sure next size_allocate on statusbar causes a size event
391 statbar->m_useCachedClientSize = false;
392 statbar->m_clientWidth = 0;
393 int h = -1;
394 if (statbar->m_wxwindow)
395 {
396 // statusbar is not a native widget, need to set height request
397 h = statbar->m_height;
398 }
399 gtk_widget_set_size_request(statbar->m_widget, -1, h);
400 }
401 // make sure next size_allocate causes a wxSizeEvent
402 m_useCachedClientSize = false;
403 m_clientWidth = 0;
404}
405#endif // wxUSE_STATUSBAR