]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/frame.cpp
Fix memory leak when a spacer is added, and crash when a window is added before wxSiz...
[wxWidgets.git] / src / gtk1 / frame.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: frame.cpp
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
7c0ea335
VZ
10// ============================================================================
11// declarations
12// ============================================================================
13
14// ----------------------------------------------------------------------------
15// headers
16// ----------------------------------------------------------------------------
17
14f355c2 18#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
fe4e9e6c 19 #pragma implementation "frame.h"
c801d85f
KB
20#endif
21
14f355c2
VS
22// For compilers that support precompilation, includes "wx.h".
23#include "wx/wxprec.h"
24
0c394212
VZ
25#include "wx/defs.h"
26
e1bf3ad3 27#include "wx/frame.h"
c801d85f
KB
28#include "wx/dialog.h"
29#include "wx/control.h"
30#include "wx/app.h"
cf4219e7 31#include "wx/menu.h"
dcf924a3 32#if wxUSE_TOOLBAR
7c0ea335 33 #include "wx/toolbar.h"
dcf924a3
RR
34#endif
35#if wxUSE_STATUSBAR
7c0ea335 36 #include "wx/statusbr.h"
dcf924a3 37#endif
362c6693 38#include "wx/dcclient.h"
83624f79 39
55703c91 40#include <glib.h>
9e691f46
VZ
41#include "wx/gtk/private.h"
42
55703c91
RR
43#include <gdk/gdkkeysyms.h>
44#include <gdk/gdkx.h>
45
c801d85f
KB
46#include "wx/gtk/win_gtk.h"
47
7c0ea335 48// ----------------------------------------------------------------------------
2f2aa628 49// constants
7c0ea335 50// ----------------------------------------------------------------------------
2f2aa628 51
c67daf87 52const int wxSTATUS_HEIGHT = 25;
41ca191f 53const int wxPLACE_HOLDER = 0;
c801d85f 54
7c0ea335 55// ----------------------------------------------------------------------------
acfd422a 56// idle system
7c0ea335 57// ----------------------------------------------------------------------------
acfd422a
RR
58
59extern void wxapp_install_idle_handler();
60extern bool g_isIdle;
2d68e1b4 61extern int g_openDialogs;
acfd422a 62
7c0ea335
VZ
63// ----------------------------------------------------------------------------
64// event tables
65// ----------------------------------------------------------------------------
66
0d53fc34 67IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxTopLevelWindow)
2e563988 68
7c0ea335
VZ
69// ============================================================================
70// implementation
71// ============================================================================
72
73// ----------------------------------------------------------------------------
74// GTK callbacks
75// ----------------------------------------------------------------------------
76
6522713c
VZ
77#if wxUSE_MENUS_NATIVE
78
16bcc879
RR
79//-----------------------------------------------------------------------------
80// "child_attached" of menu bar
81//-----------------------------------------------------------------------------
82
865bb325 83extern "C" {
0d53fc34 84static void gtk_menu_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
16bcc879 85{
a2053b27 86 if (!win->m_hasVMT) return;
88ac883a 87
16bcc879 88 win->m_menuBarDetached = FALSE;
5b8a521e 89 win->GtkUpdateSize();
16bcc879 90}
865bb325 91}
16bcc879
RR
92
93//-----------------------------------------------------------------------------
94// "child_detached" of menu bar
95//-----------------------------------------------------------------------------
96
865bb325 97extern "C" {
0d53fc34 98static void gtk_menu_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
16bcc879 99{
047ac72b
RR
100 if (g_isIdle)
101 wxapp_install_idle_handler();
102
a2053b27 103 if (!win->m_hasVMT) return;
88ac883a 104
047ac72b
RR
105 // Raise the client area area
106 gdk_window_raise( win->m_wxwindow->window );
107
16bcc879 108 win->m_menuBarDetached = TRUE;
5b8a521e 109 win->GtkUpdateSize();
16bcc879 110}
865bb325 111}
6522713c
VZ
112
113#endif // wxUSE_MENUS_NATIVE
16bcc879 114
88ac883a 115#if wxUSE_TOOLBAR
16bcc879
RR
116//-----------------------------------------------------------------------------
117// "child_attached" of tool bar
118//-----------------------------------------------------------------------------
119
865bb325 120extern "C" {
0d53fc34 121static void gtk_toolbar_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
16bcc879 122{
a2053b27 123 if (!win->m_hasVMT) return;
88ac883a 124
16bcc879 125 win->m_toolBarDetached = FALSE;
5b8a521e 126 win->GtkUpdateSize();
16bcc879 127}
865bb325 128}
16bcc879
RR
129
130//-----------------------------------------------------------------------------
131// "child_detached" of tool bar
132//-----------------------------------------------------------------------------
133
865bb325 134extern "C" {
0d53fc34 135static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
16bcc879 136{
88ac883a 137 if (g_isIdle)
801aa178 138 wxapp_install_idle_handler();
acfd422a 139
a2053b27 140 if (!win->m_hasVMT) return;
88ac883a 141
047ac72b
RR
142 // Raise the client area area
143 gdk_window_raise( win->m_wxwindow->window );
144
16bcc879 145 win->m_toolBarDetached = TRUE;
5b8a521e 146 win->GtkUpdateSize();
16bcc879 147}
865bb325 148}
88ac883a 149#endif // wxUSE_TOOLBAR
16bcc879 150
117247fd 151
7c0ea335 152// ----------------------------------------------------------------------------
0d53fc34 153// wxFrame itself
7c0ea335
VZ
154// ----------------------------------------------------------------------------
155
f362b96d 156//-----------------------------------------------------------------------------
0d53fc34 157// InsertChild for wxFrame
f362b96d
RR
158//-----------------------------------------------------------------------------
159
0d53fc34 160/* Callback for wxFrame. This very strange beast has to be used because
f362b96d 161 * C++ has no virtual methods in a constructor. We have to emulate a
77ffb593 162 * virtual function here as wxWidgets requires different ways to insert
f362b96d
RR
163 * a child in container classes. */
164
0d53fc34 165static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child )
f362b96d 166{
5fd11f09 167 wxASSERT( GTK_IS_WIDGET(child->m_widget) );
7beba2fc 168
6bc8a1c8 169 if (!parent->m_insertInClientArea)
f362b96d 170 {
047ac72b 171 // These are outside the client area
0d53fc34 172 wxFrame* frame = (wxFrame*) parent;
da048e3d 173 gtk_pizza_put( GTK_PIZZA(frame->m_mainWidget),
a2053b27
RR
174 GTK_WIDGET(child->m_widget),
175 child->m_x,
176 child->m_y,
177 child->m_width,
178 child->m_height );
2b5f62a0 179
caf51f95 180#if wxUSE_TOOLBAR_NATIVE
047ac72b
RR
181 // We connect to these events for recalculating the client area
182 // space when the toolbar is floating
f03fc89f
VZ
183 if (wxIS_KIND_OF(child,wxToolBar))
184 {
185 wxToolBar *toolBar = (wxToolBar*) child;
186 if (toolBar->GetWindowStyle() & wxTB_DOCKABLE)
187 {
a2053b27 188 gtk_signal_connect( GTK_OBJECT(toolBar->m_widget), "child_attached",
41ca191f 189 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback), (gpointer)parent );
88ac883a 190
a2053b27 191 gtk_signal_connect( GTK_OBJECT(toolBar->m_widget), "child_detached",
41ca191f 192 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback), (gpointer)parent );
f03fc89f
VZ
193 }
194 }
88ac883a 195#endif // wxUSE_TOOLBAR
f362b96d
RR
196 }
197 else
198 {
047ac72b 199 // These are inside the client area
da048e3d 200 gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow),
a2053b27
RR
201 GTK_WIDGET(child->m_widget),
202 child->m_x,
203 child->m_y,
204 child->m_width,
205 child->m_height );
f362b96d 206 }
2b5f62a0 207
047ac72b 208 // Resize on OnInternalIdle
5b8a521e 209 parent->GtkUpdateSize();
f362b96d
RR
210}
211
7c0ea335 212// ----------------------------------------------------------------------------
0d53fc34 213// wxFrame creation
7c0ea335 214// ----------------------------------------------------------------------------
c801d85f 215
0d53fc34 216void wxFrame::Init()
c801d85f 217{
16bcc879
RR
218 m_menuBarDetached = FALSE;
219 m_toolBarDetached = FALSE;
2b5f62a0 220 m_menuBarHeight = 2;
362c6693 221}
c801d85f 222
0d53fc34 223bool wxFrame::Create( wxWindow *parent,
7c0ea335 224 wxWindowID id,
ca8bf976
VZ
225 const wxString& title,
226 const wxPoint& pos,
227 const wxSize& sizeOrig,
7c0ea335
VZ
228 long style,
229 const wxString &name )
c801d85f 230{
7b4c2a06 231 bool rt = wxTopLevelWindow::Create(parent, id, title, pos, sizeOrig,
7d9f12f3 232 style, name);
6bc8a1c8 233 m_insertCallback = (wxInsertChildFunction) wxInsertChildInFrame;
2b5f62a0 234
7d9f12f3 235 return rt;
362c6693 236}
c801d85f 237
0d53fc34 238wxFrame::~wxFrame()
c801d85f 239{
31c6b4fc 240 m_isBeingDeleted = TRUE;
7c0ea335 241 DeleteAllBars();
3d0c4d2e
RR
242}
243
7c0ea335
VZ
244// ----------------------------------------------------------------------------
245// overridden wxWindow methods
246// ----------------------------------------------------------------------------
247
0d53fc34 248void wxFrame::DoGetClientSize( int *width, int *height ) const
c801d85f 249{
223d09f6 250 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
7b4c2a06 251
7d9f12f3 252 wxTopLevelWindow::DoGetClientSize( width, height );
8bbe427f 253
fb1585ae 254 if (height)
46dc76ba 255 {
75c9da25 256#if wxUSE_MENUS_NATIVE
047ac72b 257 // menu bar
41ca191f 258 if (m_frameMenuBar)
f03fc89f 259 {
88ac883a 260 if (!m_menuBarDetached)
2b5f62a0 261 (*height) -= m_menuBarHeight;
f03fc89f
VZ
262 else
263 (*height) -= wxPLACE_HOLDER;
264 }
75c9da25 265#endif // wxUSE_MENUS_NATIVE
88ac883a 266
dcf924a3 267#if wxUSE_STATUSBAR
047ac72b 268 // status bar
7b4c2a06 269 if (m_frameStatusBar && m_frameStatusBar->IsShown())
7d9f12f3 270 (*height) -= wxSTATUS_HEIGHT;
93fa69f8 271#endif // wxUSE_STATUSBAR
88ac883a 272
dcf924a3 273#if wxUSE_TOOLBAR
047ac72b 274 // tool bar
fa755cf1 275 if (m_frameToolBar && m_frameToolBar->IsShown())
fb1585ae 276 {
93fa69f8 277 if (m_toolBarDetached)
f03fc89f 278 {
93fa69f8 279 *height -= wxPLACE_HOLDER;
f03fc89f
VZ
280 }
281 else
93fa69f8
VZ
282 {
283 int x, y;
284 m_frameToolBar->GetSize( &x, &y );
285 if ( m_frameToolBar->GetWindowStyle() & wxTB_VERTICAL )
286 {
287 *width -= x;
288 }
289 else
290 {
291 *height -= y;
292 }
293 }
fb1585ae 294 }
93fa69f8 295#endif // wxUSE_TOOLBAR
46dc76ba 296 }
362c6693 297}
c801d85f 298
0d53fc34 299void wxFrame::DoSetClientSize( int width, int height )
b593568e 300{
223d09f6 301 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
8bbe427f 302
75c9da25 303#if wxUSE_MENUS_NATIVE
047ac72b 304 // menu bar
41ca191f 305 if (m_frameMenuBar)
f03fc89f 306 {
88ac883a 307 if (!m_menuBarDetached)
2b5f62a0 308 height += m_menuBarHeight;
f03fc89f
VZ
309 else
310 height += wxPLACE_HOLDER;
311 }
75c9da25 312#endif // wxUSE_MENUS_NATIVE
88ac883a 313
dcf924a3 314#if wxUSE_STATUSBAR
047ac72b 315 // status bar
fa755cf1 316 if (m_frameStatusBar && m_frameStatusBar->IsShown()) height += wxSTATUS_HEIGHT;
dcf924a3 317#endif
88ac883a 318
dcf924a3 319#if wxUSE_TOOLBAR
047ac72b 320 // tool bar
fa755cf1 321 if (m_frameToolBar && m_frameToolBar->IsShown())
41ca191f 322 {
93fa69f8 323 if (m_toolBarDetached)
f03fc89f 324 {
93fa69f8 325 height += wxPLACE_HOLDER;
f03fc89f
VZ
326 }
327 else
93fa69f8
VZ
328 {
329 int x, y;
330 m_frameToolBar->GetSize( &x, &y );
331 if ( m_frameToolBar->GetWindowStyle() & wxTB_VERTICAL )
332 {
333 width += x;
334 }
335 else
336 {
337 height += y;
338 }
339 }
41ca191f 340 }
dcf924a3 341#endif
88ac883a 342
7d9f12f3 343 wxTopLevelWindow::DoSetClientSize( width, height );
362c6693 344}
b593568e 345
0d53fc34 346void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
7c0ea335 347 int width, int height )
c801d85f 348{
f5368809
RR
349 // due to a bug in gtk, x,y are always 0
350 // m_x = x;
351 // m_y = y;
352
047ac72b 353 // avoid recursions
e52f60e6
RR
354 if (m_resizing) return;
355 m_resizing = TRUE;
8bbe427f 356
047ac72b 357 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
223d09f6 358 wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
88ac883a 359
f5368809
RR
360 m_width = width;
361 m_height = height;
7beba2fc 362
047ac72b 363 // space occupied by m_frameToolBar and m_frameMenuBar
93fa69f8
VZ
364 int client_area_x_offset = 0,
365 client_area_y_offset = 0;
8bbe427f 366
0d53fc34 367 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
ab2b3dd4 368 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
0d53fc34 369 set in wxFrame::Create so it is used to check what kind of frame we
ab2b3dd4
RR
370 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
371 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
372 importantly) m_mainWidget */
88ac883a 373
e7dda1ff
VS
374 int minWidth = GetMinWidth(),
375 minHeight = GetMinHeight(),
376 maxWidth = GetMaxWidth(),
377 maxHeight = GetMaxHeight();
378
379 if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth;
380 if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight;
381 if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth;
382 if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight;
1f3c610d 383
ab2b3dd4 384 if (m_mainWidget)
f5368809 385 {
047ac72b 386 // set size hints
f6bcfd97 387 gint flag = 0; // GDK_HINT_POS;
e7dda1ff
VS
388 if ((minWidth != -1) || (minHeight != -1)) flag |= GDK_HINT_MIN_SIZE;
389 if ((maxWidth != -1) || (maxHeight != -1)) flag |= GDK_HINT_MAX_SIZE;
f6bcfd97 390 GdkGeometry geom;
e7dda1ff
VS
391 geom.min_width = minWidth;
392 geom.min_height = minHeight;
393 geom.max_width = maxWidth;
394 geom.max_height = maxHeight;
f6bcfd97
BP
395 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget),
396 (GtkWidget*) NULL,
397 &geom,
398 (GdkWindowHints) flag );
ab2b3dd4 399
047ac72b
RR
400 // I revert back to wxGTK's original behaviour. m_mainWidget holds
401 // the menubar, the toolbar and the client area, which is represented
402 // by m_wxwindow.
403 // This hurts in the eye, but I don't want to call SetSize()
404 // because I don't want to call any non-native functions here.
88ac883a 405
75c9da25 406#if wxUSE_MENUS_NATIVE
ab2b3dd4
RR
407 if (m_frameMenuBar)
408 {
409 int xx = m_miniEdge;
410 int yy = m_miniEdge + m_miniTitle;
411 int ww = m_width - 2*m_miniEdge;
2b5f62a0 412 int hh = m_menuBarHeight;
f03fc89f 413 if (m_menuBarDetached) hh = wxPLACE_HOLDER;
121a3581
RR
414 m_frameMenuBar->m_x = xx;
415 m_frameMenuBar->m_y = yy;
416 m_frameMenuBar->m_width = ww;
417 m_frameMenuBar->m_height = hh;
da048e3d 418 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
88ac883a 419 m_frameMenuBar->m_widget,
f03fc89f
VZ
420 xx, yy, ww, hh );
421 client_area_y_offset += hh;
ab2b3dd4 422 }
75c9da25 423#endif // wxUSE_MENUS_NATIVE
88ac883a 424
dcf924a3 425#if wxUSE_TOOLBAR
fa755cf1 426 if ((m_frameToolBar) && m_frameToolBar->IsShown() &&
7beba2fc 427 (m_frameToolBar->m_widget->parent == m_mainWidget))
ab2b3dd4
RR
428 {
429 int xx = m_miniEdge;
430 int yy = m_miniEdge + m_miniTitle;
75c9da25 431#if wxUSE_MENUS_NATIVE
41ca191f 432 if (m_frameMenuBar)
f03fc89f 433 {
88ac883a 434 if (!m_menuBarDetached)
2b5f62a0 435 yy += m_menuBarHeight;
88ac883a 436 else
f03fc89f
VZ
437 yy += wxPLACE_HOLDER;
438 }
75c9da25 439#endif // wxUSE_MENUS_NATIVE
93fa69f8 440
121a3581
RR
441 m_frameToolBar->m_x = xx;
442 m_frameToolBar->m_y = yy;
93fa69f8 443
047ac72b 444 // don't change the toolbar's reported height/width
93fa69f8
VZ
445 int ww, hh;
446 if ( m_frameToolBar->GetWindowStyle() & wxTB_VERTICAL )
447 {
448 ww = m_toolBarDetached ? wxPLACE_HOLDER
449 : m_frameToolBar->m_width;
450 hh = m_height - 2*m_miniEdge;
451
452 client_area_x_offset += ww;
453 }
454 else
455 {
456 ww = m_width - 2*m_miniEdge;
457 hh = m_toolBarDetached ? wxPLACE_HOLDER
458 : m_frameToolBar->m_height;
7b4c2a06 459
93fa69f8
VZ
460 client_area_y_offset += hh;
461 }
462
da048e3d 463 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
88ac883a 464 m_frameToolBar->m_widget,
f03fc89f 465 xx, yy, ww, hh );
ab2b3dd4 466 }
93fa69f8 467#endif // wxUSE_TOOLBAR
88ac883a 468
93fa69f8 469 int client_x = client_area_x_offset + m_miniEdge;
f03fc89f 470 int client_y = client_area_y_offset + m_miniEdge + m_miniTitle;
93fa69f8 471 int client_w = m_width - client_area_x_offset - 2*m_miniEdge;
f03fc89f 472 int client_h = m_height - client_area_y_offset- 2*m_miniEdge - m_miniTitle;
da048e3d 473 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
88ac883a 474 m_wxwindow,
f03fc89f 475 client_x, client_y, client_w, client_h );
32a95f9f
RR
476 }
477 else
478 {
047ac72b
RR
479 // If there is no m_mainWidget between m_widget and m_wxwindow there
480 // is no need to set the size or position of m_wxwindow.
f5368809 481 }
88ac883a 482
dcf924a3 483#if wxUSE_STATUSBAR
fa755cf1 484 if (m_frameStatusBar && m_frameStatusBar->IsShown())
f5368809 485 {
b2b3ccc5 486 int xx = 0 + m_miniEdge;
f362b96d 487 int yy = m_height - wxSTATUS_HEIGHT - m_miniEdge - client_area_y_offset;
ac57418f
RR
488 int ww = m_width - 2*m_miniEdge;
489 int hh = wxSTATUS_HEIGHT;
121a3581
RR
490 m_frameStatusBar->m_x = xx;
491 m_frameStatusBar->m_y = yy;
492 m_frameStatusBar->m_width = ww;
493 m_frameStatusBar->m_height = hh;
da048e3d 494 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow),
7c0ea335
VZ
495 m_frameStatusBar->m_widget,
496 xx, yy, ww, hh );
b6fa52db 497 gtk_widget_draw( m_frameStatusBar->m_widget, (GdkRectangle*) NULL );
f5368809 498 }
1e6feb95 499#endif // wxUSE_STATUSBAR
8bbe427f 500
7b4c2a06 501 m_sizeSet = TRUE;
7beba2fc 502
54517652 503 // send size event to frame
43a18898
RR
504 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
505 event.SetEventObject( this );
e52f60e6 506 GetEventHandler()->ProcessEvent( event );
8bbe427f 507
1e6feb95 508#if wxUSE_STATUSBAR
54517652 509 // send size event to status bar
5aa5e35a
RR
510 if (m_frameStatusBar)
511 {
a2053b27 512 wxSizeEvent event2( wxSize(m_frameStatusBar->m_width,m_frameStatusBar->m_height), m_frameStatusBar->GetId() );
5aa5e35a
RR
513 event2.SetEventObject( m_frameStatusBar );
514 m_frameStatusBar->GetEventHandler()->ProcessEvent( event2 );
515 }
1e6feb95 516#endif // wxUSE_STATUSBAR
884470b1 517
e52f60e6
RR
518 m_resizing = FALSE;
519}
520
0d53fc34 521void wxFrame::OnInternalIdle()
e52f60e6 522{
e39af974 523 wxFrameBase::OnInternalIdle();
88ac883a 524
75c9da25 525#if wxUSE_MENUS_NATIVE
082b2798 526 if (m_frameMenuBar) m_frameMenuBar->OnInternalIdle();
75c9da25 527#endif // wxUSE_MENUS_NATIVE
dcf924a3 528#if wxUSE_TOOLBAR
082b2798 529 if (m_frameToolBar) m_frameToolBar->OnInternalIdle();
dcf924a3
RR
530#endif
531#if wxUSE_STATUSBAR
e4edaf5c
JS
532 if (m_frameStatusBar)
533 {
534 m_frameStatusBar->OnInternalIdle();
535
536 // There may be controls in the status bar that
537 // need to be updated
538 for ( wxWindowList::compatibility_iterator node = m_frameStatusBar->GetChildren().GetFirst();
539 node;
540 node = node->GetNext() )
541 {
542 wxWindow *child = node->GetData();
543 child->OnInternalIdle();
544 }
545 }
dcf924a3 546#endif
362c6693 547}
c801d85f 548
7c0ea335
VZ
549// ----------------------------------------------------------------------------
550// menu/tool/status bar stuff
551// ----------------------------------------------------------------------------
c801d85f 552
6522713c 553#if wxUSE_MENUS_NATIVE
1e6feb95 554
0d53fc34 555void wxFrame::DetachMenuBar()
c801d85f 556{
223d09f6
KB
557 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
558 wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
8bbe427f 559
6522713c 560 if ( m_frameMenuBar )
186baeb2
RR
561 {
562 m_frameMenuBar->UnsetInvokingWindow( this );
563
564 if (m_frameMenuBar->GetWindowStyle() & wxMB_DOCKABLE)
565 {
566 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar->m_widget),
567 GTK_SIGNAL_FUNC(gtk_menu_attached_callback), (gpointer)this );
568
569 gtk_signal_disconnect_by_func( GTK_OBJECT(m_frameMenuBar->m_widget),
570 GTK_SIGNAL_FUNC(gtk_menu_detached_callback), (gpointer)this );
571 }
f6bcfd97 572
186baeb2 573 gtk_widget_ref( m_frameMenuBar->m_widget );
f283a575
RR
574
575 gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget );
186baeb2
RR
576 }
577
6522713c
VZ
578 wxFrameBase::DetachMenuBar();
579}
580
0d53fc34 581void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
6522713c
VZ
582{
583 wxFrameBase::AttachMenuBar(menuBar);
8bbe427f 584
f5368809 585 if (m_frameMenuBar)
30dea054 586 {
5bd9e519 587 m_frameMenuBar->SetInvokingWindow( this );
8bbe427f 588
186baeb2
RR
589 m_frameMenuBar->SetParent(this);
590 gtk_pizza_put( GTK_PIZZA(m_mainWidget),
88ac883a
VZ
591 m_frameMenuBar->m_widget,
592 m_frameMenuBar->m_x,
a2053b27
RR
593 m_frameMenuBar->m_y,
594 m_frameMenuBar->m_width,
595 m_frameMenuBar->m_height );
88ac883a 596
186baeb2
RR
597 if (menuBar->GetWindowStyle() & wxMB_DOCKABLE)
598 {
599 gtk_signal_connect( GTK_OBJECT(menuBar->m_widget), "child_attached",
600 GTK_SIGNAL_FUNC(gtk_menu_attached_callback), (gpointer)this );
7beba2fc 601
186baeb2
RR
602 gtk_signal_connect( GTK_OBJECT(menuBar->m_widget), "child_detached",
603 GTK_SIGNAL_FUNC(gtk_menu_detached_callback), (gpointer)this );
f5368809 604 }
2b5f62a0 605
02a8e64c 606 gtk_widget_show( m_frameMenuBar->m_widget );
2b5f62a0
VZ
607
608 UpdateMenuBarSize();
716b7364 609 }
2b5f62a0
VZ
610 else
611 {
612 m_menuBarHeight = 2;
613 GtkUpdateSize(); // resize window in OnInternalIdle
614 }
615}
616
617void wxFrame::UpdateMenuBarSize()
618{
2b5f62a0
VZ
619 GtkRequisition req;
620
621 req.width = 2;
622 req.height = 2;
e5894d19
CE
623
624 // this is called after Remove with a NULL m_frameMenuBar
625 if ( m_frameMenuBar )
2b5f62a0
VZ
626 (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(m_frameMenuBar->m_widget) )->size_request )
627 (m_frameMenuBar->m_widget, &req );
628
629 m_menuBarHeight = req.height;
630
631 // resize window in OnInternalIdle
8bbe427f 632
b8b7f03c 633 GtkUpdateSize();
362c6693 634}
c801d85f 635
6522713c 636#endif // wxUSE_MENUS_NATIVE
1e6feb95 637
88ac883a 638#if wxUSE_TOOLBAR
1e6feb95 639
0d53fc34 640wxToolBar* wxFrame::CreateToolBar( long style, wxWindowID id, const wxString& name )
46dc76ba 641{
223d09f6 642 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
8bbe427f 643
6bc8a1c8 644 m_insertInClientArea = FALSE;
88ac883a 645
7c0ea335 646 m_frameToolBar = wxFrameBase::CreateToolBar( style, id, name );
8bbe427f 647
6bc8a1c8 648 m_insertInClientArea = TRUE;
8bbe427f 649
b8b7f03c 650 GtkUpdateSize();
8bbe427f 651
f5368809 652 return m_frameToolBar;
362c6693 653}
46dc76ba 654
0d53fc34 655void wxFrame::SetToolBar(wxToolBar *toolbar)
7beba2fc 656{
94f14509
VZ
657 bool hadTbar = m_frameToolBar != NULL;
658
7c0ea335
VZ
659 wxFrameBase::SetToolBar(toolbar);
660
94f14509 661 if ( m_frameToolBar )
307f16e8 662 {
f283a575 663 // insert into toolbar area if not already there
3017f78d
RR
664 if ((m_frameToolBar->m_widget->parent) &&
665 (m_frameToolBar->m_widget->parent != m_mainWidget))
307f16e8 666 {
3017f78d 667 GetChildren().DeleteObject( m_frameToolBar );
7beba2fc
VZ
668
669 gtk_widget_reparent( m_frameToolBar->m_widget, m_mainWidget );
5b8a521e 670 GtkUpdateSize();
7beba2fc 671 }
307f16e8 672 }
94f14509
VZ
673 else // toolbar unset
674 {
675 // still need to update size if it had been there before
676 if ( hadTbar )
677 {
678 GtkUpdateSize();
679 }
680 }
307f16e8
RR
681}
682
88ac883a 683#endif // wxUSE_TOOLBAR
46dc76ba 684
88ac883a 685#if wxUSE_STATUSBAR
8bbe427f 686
0d53fc34 687wxStatusBar* wxFrame::CreateStatusBar(int number,
7c0ea335
VZ
688 long style,
689 wxWindowID id,
690 const wxString& name)
c801d85f 691{
223d09f6 692 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
8bbe427f 693
7c0ea335 694 // because it will change when toolbar is added
b8b7f03c 695 GtkUpdateSize();
c801d85f 696
7c0ea335 697 return wxFrameBase::CreateStatusBar( number, style, id, name );
362c6693
RR
698}
699
3851e479
RR
700void wxFrame::SetStatusBar(wxStatusBar *statbar)
701{
702 bool hadStatBar = m_frameStatusBar != NULL;
703
704 wxFrameBase::SetStatusBar(statbar);
705
fbbc1982 706 if (hadStatBar && !m_frameStatusBar)
3851e479
RR
707 GtkUpdateSize();
708}
709
0d53fc34 710void wxFrame::PositionStatusBar()
8febdd39
RR
711{
712 if ( !m_frameStatusBar )
713 return;
714
b8b7f03c 715 GtkUpdateSize();
8febdd39 716}
88ac883a 717#endif // wxUSE_STATUSBAR
c801d85f 718