1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/gtk/frame.cpp
3 // Purpose:
4 // Author:      Robert Roebling
5 // Id:          $Id: frame.cpp 67149 2011-03-08 14:47:25Z JS $
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 "wx/gtk/private.h"
22 #include "wx/gtk/win_gtk.h"
23 
24 // ----------------------------------------------------------------------------
25 // constants
26 // ----------------------------------------------------------------------------
27 
28 static const int wxSTATUS_HEIGHT  = 25;
29 static const int wxPLACE_HOLDER   = 0;
30 
31 // ----------------------------------------------------------------------------
32 // event tables
33 // ----------------------------------------------------------------------------
34 
IMPLEMENT_DYNAMIC_CLASS(wxFrame,wxTopLevelWindow)35 IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxTopLevelWindow)
36 
37 // ============================================================================
38 // implementation
39 // ============================================================================
40 
41 // ----------------------------------------------------------------------------
42 // GTK callbacks
43 // ----------------------------------------------------------------------------
44 
45 #if wxUSE_MENUS_NATIVE
46 
47 //-----------------------------------------------------------------------------
48 // "child_attached" of menu bar
49 //-----------------------------------------------------------------------------
50 
51 extern "C" {
52 static void gtk_menu_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
53 {
54     if (!win->m_hasVMT) return;
55 
56     win->m_menuBarDetached = false;
57     win->GtkUpdateSize();
58 }
59 }
60 
61 //-----------------------------------------------------------------------------
62 // "child_detached" of menu bar
63 //-----------------------------------------------------------------------------
64 
65 extern "C" {
gtk_menu_detached_callback(GtkWidget * WXUNUSED (widget),GtkWidget * WXUNUSED (child),wxFrame * win)66 static void gtk_menu_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
67 {
68     if (g_isIdle)
69         wxapp_install_idle_handler();
70 
71     if (!win->m_hasVMT) return;
72 
73     // Raise the client area area
74     gdk_window_raise( win->m_wxwindow->window );
75 
76     win->m_menuBarDetached = true;
77     win->GtkUpdateSize();
78 }
79 }
80 
81 //-----------------------------------------------------------------------------
82 // "size-request" from menubar
83 //-----------------------------------------------------------------------------
84 
85 extern "C" {
menubar_size_request(GtkWidget * widget,GtkRequisition *,wxFrame * win)86 static void menubar_size_request(GtkWidget* widget, GtkRequisition*, wxFrame* win)
87 {
88     g_signal_handlers_disconnect_by_func(
89         widget, (void*)menubar_size_request, win);
90     win->UpdateMenuBarSize();
91 }
92 }
93 
94 //-----------------------------------------------------------------------------
95 // "style-set" from menubar
96 //-----------------------------------------------------------------------------
97 
98 extern "C" {
menubar_style_set(GtkWidget * widget,GtkStyle *,wxFrame * win)99 static void menubar_style_set(GtkWidget* widget, GtkStyle*, wxFrame* win)
100 {
101     g_signal_connect(widget, "size-request",
102         G_CALLBACK(menubar_size_request), win);
103 }
104 }
105 #endif // wxUSE_MENUS_NATIVE
106 
107 #if wxUSE_TOOLBAR
108 //-----------------------------------------------------------------------------
109 // "child_attached" of tool bar
110 //-----------------------------------------------------------------------------
111 
112 extern "C" {
gtk_toolbar_attached_callback(GtkWidget * WXUNUSED (widget),GtkWidget * WXUNUSED (child),wxFrame * win)113 static void gtk_toolbar_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
114 {
115     if (!win->m_hasVMT) return;
116 
117     win->m_toolBarDetached = false;
118     win->GtkUpdateSize();
119 }
120 }
121 
122 //-----------------------------------------------------------------------------
123 // "child_detached" of tool bar
124 //-----------------------------------------------------------------------------
125 
126 extern "C" {
gtk_toolbar_detached_callback(GtkWidget * WXUNUSED (widget),GtkWidget * WXUNUSED (child),wxFrame * win)127 static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
128 {
129     if (g_isIdle)
130         wxapp_install_idle_handler();
131 
132     if (!win->m_hasVMT) return;
133 
134     // Raise the client area area
135     gdk_window_raise( win->m_wxwindow->window );
136 
137     win->m_toolBarDetached = true;
138     win->GtkUpdateSize();
139 }
140 }
141 #endif // wxUSE_TOOLBAR
142 
143 
144 // ----------------------------------------------------------------------------
145 // wxFrame itself
146 // ----------------------------------------------------------------------------
147 
148 //-----------------------------------------------------------------------------
149 // InsertChild for wxFrame
150 //-----------------------------------------------------------------------------
151 
152 /* Callback for wxFrame. This very strange beast has to be used because
153  * C++ has no virtual methods in a constructor. We have to emulate a
154  * virtual function here as wxWidgets requires different ways to insert
155  * a child in container classes. */
156 
wxInsertChildInFrame(wxFrame * parent,wxWindow * child)157 static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child )
158 {
159     wxASSERT( GTK_IS_WIDGET(child->m_widget) );
160 
161     if (!parent->m_insertInClientArea)
162     {
163         // These are outside the client area
164         wxFrame* frame = (wxFrame*) parent;
165         gtk_pizza_put( GTK_PIZZA(frame->m_mainWidget),
166                          GTK_WIDGET(child->m_widget),
167                          child->m_x,
168                          child->m_y,
169                          child->m_width,
170                          child->m_height );
171 
172 #if wxUSE_TOOLBAR_NATIVE
173         // We connect to these events for recalculating the client area
174         // space when the toolbar is floating
175         if (wxIS_KIND_OF(child,wxToolBar))
176         {
177             wxToolBar *toolBar = (wxToolBar*) child;
178             if (toolBar->GetWindowStyle() & wxTB_DOCKABLE)
179             {
180                 g_signal_connect (toolBar->m_widget, "child_attached",
181                                   G_CALLBACK (gtk_toolbar_attached_callback),
182                                   parent);
183                 g_signal_connect (toolBar->m_widget, "child_detached",
184                                   G_CALLBACK (gtk_toolbar_detached_callback),
185                                   parent);
186             }
187         }
188 #endif // wxUSE_TOOLBAR
189     }
190     else
191     {
192         // These are inside the client area
193         gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow),
194                          GTK_WIDGET(child->m_widget),
195                          child->m_x,
196                          child->m_y,
197                          child->m_width,
198                          child->m_height );
199     }
200 }
201 
202 // ----------------------------------------------------------------------------
203 // wxFrame creation
204 // ----------------------------------------------------------------------------
205 
Init()206 void wxFrame::Init()
207 {
208     m_menuBarDetached = false;
209     m_toolBarDetached = false;
210     m_menuBarHeight = 2;
211 }
212 
Create(wxWindow * parent,wxWindowID id,const wxString & title,const wxPoint & pos,const wxSize & sizeOrig,long style,const wxString & name)213 bool wxFrame::Create( wxWindow *parent,
214                       wxWindowID id,
215                       const wxString& title,
216                       const wxPoint& pos,
217                       const wxSize& sizeOrig,
218                       long style,
219                       const wxString &name )
220 {
221     bool rt = wxTopLevelWindow::Create(parent, id, title, pos, sizeOrig,
222                                        style, name);
223     m_insertCallback = (wxInsertChildFunction) wxInsertChildInFrame;
224 
225     return rt;
226 }
227 
~wxFrame()228 wxFrame::~wxFrame()
229 {
230     m_isBeingDeleted = true;
231     DeleteAllBars();
232 }
233 
234 // ----------------------------------------------------------------------------
235 // overridden wxWindow methods
236 // ----------------------------------------------------------------------------
237 
DoGetClientSize(int * width,int * height) const238 void wxFrame::DoGetClientSize( int *width, int *height ) const
239 {
240     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
241 
242     wxTopLevelWindow::DoGetClientSize( width, height );
243 
244     if (height)
245     {
246 #if wxUSE_MENUS_NATIVE
247         // menu bar
248         if (m_frameMenuBar && !(m_fsIsShowing && (m_fsSaveFlag & wxFULLSCREEN_NOMENUBAR) != 0))
249         {
250             if (!m_menuBarDetached)
251                 (*height) -= m_menuBarHeight;
252             else
253                 (*height) -= wxPLACE_HOLDER;
254         }
255 #endif // wxUSE_MENUS_NATIVE
256 
257 #if wxUSE_STATUSBAR
258         // status bar
259         if (m_frameStatusBar && m_frameStatusBar->IsShown() &&
260             !(m_fsIsShowing && (m_fsSaveFlag & wxFULLSCREEN_NOSTATUSBAR) != 0))
261             (*height) -= wxSTATUS_HEIGHT;
262 #endif // wxUSE_STATUSBAR
263     }
264 
265 #if wxUSE_TOOLBAR
266     // tool bar
267     if (m_frameToolBar && m_frameToolBar->IsShown())
268     {
269         if (m_toolBarDetached)
270         {
271             if (height != NULL)
272                 *height -= wxPLACE_HOLDER;
273         }
274         else
275         {
276             int x, y;
277             m_frameToolBar->GetSize( &x, &y );
278             if ( m_frameToolBar->IsVertical() )
279             {
280                 if (width != NULL)
281                     *width -= x;
282             }
283             else
284             {
285                 if (height != NULL)
286                     *height -= y;
287             }
288         }
289     }
290 #endif // wxUSE_TOOLBAR
291 
292     if (width != NULL && *width < 0)
293         *width = 0;
294     if (height != NULL && *height < 0)
295         *height = 0;
296 }
297 
DoSetClientSize(int width,int height)298 void wxFrame::DoSetClientSize( int width, int height )
299 {
300     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
301 
302 #if wxUSE_MENUS_NATIVE
303         // menu bar
304         if (m_frameMenuBar && !(m_fsIsShowing && (m_fsSaveFlag & wxFULLSCREEN_NOMENUBAR) != 0))
305         {
306             if (!m_menuBarDetached)
307                 height += m_menuBarHeight;
308             else
309                 height += wxPLACE_HOLDER;
310         }
311 #endif // wxUSE_MENUS_NATIVE
312 
313 #if wxUSE_STATUSBAR
314         // status bar
315         if (m_frameStatusBar && m_frameStatusBar->IsShown() &&
316             !(m_fsIsShowing && (m_fsSaveFlag & wxFULLSCREEN_NOSTATUSBAR) != 0))
317             height += wxSTATUS_HEIGHT;
318 #endif
319 
320 #if wxUSE_TOOLBAR
321         // tool bar
322         if (m_frameToolBar && m_frameToolBar->IsShown())
323         {
324             if (m_toolBarDetached)
325             {
326                 height += wxPLACE_HOLDER;
327             }
328             else
329             {
330                 int x, y;
331                 m_frameToolBar->GetSize( &x, &y );
332                 if ( m_frameToolBar->IsVertical() )
333                 {
334                     width += x;
335                 }
336                 else
337                 {
338                     height += y;
339                 }
340             }
341         }
342 #endif
343 
344     wxTopLevelWindow::DoSetClientSize( width, height );
345 }
346 
GtkOnSize()347 void wxFrame::GtkOnSize()
348 {
349     // avoid recursions
350     if (m_resizing) return;
351     m_resizing = true;
352 
353     // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
354     wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
355 
356     // space occupied by m_frameToolBar and m_frameMenuBar
357     int client_area_x_offset = 0,
358         client_area_y_offset = 0;
359 
360     /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
361        wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
362        set in wxFrame::Create so it is used to check what kind of frame we
363        have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
364        skip the part which handles m_frameMenuBar, m_frameToolBar and (most
365        importantly) m_mainWidget */
366 
367     int minWidth = GetMinWidth(),
368         minHeight = GetMinHeight(),
369         maxWidth = GetMaxWidth(),
370         maxHeight = GetMaxHeight();
371 
372     if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth;
373     if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight;
374     if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth;
375     if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight;
376 
377     if (m_mainWidget)
378     {
379         // TODO
380         // Rewrite this terrible code to using GtkVBox
381 
382         // m_mainWidget holds the menubar, the toolbar and the client
383         // area, which is represented by m_wxwindow.
384 
385 #if wxUSE_MENUS_NATIVE
386         if (m_frameMenuBar && !(m_fsIsShowing && (m_fsSaveFlag & wxFULLSCREEN_NOMENUBAR) != 0))
387         {
388             if (m_frameMenuBar->IsShown() && !GTK_WIDGET_VISIBLE(m_frameMenuBar->m_widget))
389                 gtk_widget_show( m_frameMenuBar->m_widget );
390             int xx = m_miniEdge;
391             int yy = m_miniEdge + m_miniTitle;
392             int ww = m_width  - 2*m_miniEdge;
393             if (ww < 0)
394                 ww = 0;
395             int hh = m_menuBarHeight;
396             if (m_menuBarDetached) hh = wxPLACE_HOLDER;
397             m_frameMenuBar->m_x = xx;
398             m_frameMenuBar->m_y = yy;
399             m_frameMenuBar->m_width = ww;
400             m_frameMenuBar->m_height = hh;
401             gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
402                                   m_frameMenuBar->m_widget,
403                                   xx, yy, ww, hh );
404             client_area_y_offset += hh;
405         }
406         else
407         {
408             if (m_frameMenuBar)
409             {
410                 if (GTK_WIDGET_VISIBLE(m_frameMenuBar->m_widget))
411                     gtk_widget_hide( m_frameMenuBar->m_widget );
412             }
413         }
414 #endif // wxUSE_MENUS_NATIVE
415 
416 #if wxUSE_TOOLBAR
417         if ((m_frameToolBar) && m_frameToolBar->IsShown() &&
418             (m_frameToolBar->m_widget->parent == m_mainWidget))
419         {
420             int xx = m_miniEdge;
421             int yy = m_miniEdge + m_miniTitle;
422 #if wxUSE_MENUS_NATIVE
423             if (m_frameMenuBar)
424             {
425                 if (!m_menuBarDetached)
426                     yy += m_menuBarHeight;
427                 else
428                     yy += wxPLACE_HOLDER;
429             }
430 #endif // wxUSE_MENUS_NATIVE
431 
432             m_frameToolBar->m_x = xx;
433             m_frameToolBar->m_y = yy;
434 
435             // don't change the toolbar's reported height/width
436             int ww, hh;
437             if ( m_frameToolBar->GetWindowStyle() & wxTB_VERTICAL )
438             {
439                 ww = m_toolBarDetached ? wxPLACE_HOLDER
440                                        : m_frameToolBar->m_width;
441                 hh = m_height - 2*m_miniEdge;
442 
443                 client_area_x_offset += ww;
444             }
445             else if( m_frameToolBar->HasFlag(wxTB_RIGHT) )
446             {
447                yy += 2;
448                ww = m_toolBarDetached ? wxPLACE_HOLDER
449                                       : m_frameToolBar->m_width;
450                xx = GetClientSize().x - 1;
451                hh = m_height - 2*m_miniEdge;
452                if( hh < 0 )
453                   hh = 0;
454 
455             }
456             else if( m_frameToolBar->GetWindowStyle() & wxTB_BOTTOM )
457             {
458                 xx = m_miniEdge;
459                 yy = GetClientSize().y;
460 #if wxUSE_MENUS_NATIVE
461                 yy += m_menuBarHeight;
462 #endif // wxUSE_MENU_NATIVE
463                 m_frameToolBar->m_x = xx;
464                 m_frameToolBar->m_y = yy;
465                 ww = m_width - 2*m_miniEdge;
466                 hh = m_toolBarDetached ? wxPLACE_HOLDER
467                                        : m_frameToolBar->m_height;
468             }
469             else
470             {
471                 ww = m_width - 2*m_miniEdge;
472                 hh = m_toolBarDetached ? wxPLACE_HOLDER
473                                        : m_frameToolBar->m_height;
474 
475                 client_area_y_offset += hh;
476             }
477 
478             if (ww < 0)
479                 ww = 0;
480             if (hh < 0)
481                 hh = 0;
482             gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
483                                   m_frameToolBar->m_widget,
484                                   xx, yy, ww, hh );
485         }
486 #endif // wxUSE_TOOLBAR
487 
488         int client_x = client_area_x_offset + m_miniEdge;
489         int client_y = client_area_y_offset + m_miniEdge + m_miniTitle;
490         int client_w = m_width - client_area_x_offset - 2*m_miniEdge;
491         int client_h = m_height - client_area_y_offset- 2*m_miniEdge - m_miniTitle;
492         if (client_w < 0)
493             client_w = 0;
494         if (client_h < 0)
495             client_h = 0;
496         gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
497                               m_wxwindow,
498                               client_x, client_y, client_w, client_h );
499     }
500     else
501     {
502         // If there is no m_mainWidget between m_widget and m_wxwindow there
503         // is no need to set the size or position of m_wxwindow.
504     }
505 
506 #if wxUSE_STATUSBAR
507     if (m_frameStatusBar && m_frameStatusBar->IsShown() &&
508         !(m_fsIsShowing && (m_fsSaveFlag & wxFULLSCREEN_NOSTATUSBAR) != 0))
509     {
510         if (!GTK_WIDGET_VISIBLE(m_frameStatusBar->m_widget))
511             gtk_widget_show( m_frameStatusBar->m_widget );
512 
513         int xx = 0 + m_miniEdge;
514         int yy = m_height - wxSTATUS_HEIGHT - m_miniEdge - client_area_y_offset;
515         int ww = m_width - 2*m_miniEdge;
516         if (ww < 0)
517             ww = 0;
518         int hh = wxSTATUS_HEIGHT;
519         m_frameStatusBar->m_x = xx;
520         m_frameStatusBar->m_y = yy;
521         m_frameStatusBar->m_width = ww;
522         m_frameStatusBar->m_height = hh;
523         gtk_pizza_set_size( GTK_PIZZA(m_wxwindow),
524                             m_frameStatusBar->m_widget,
525                             xx, yy, ww, hh );
526     }
527     else
528     {
529         if (m_frameStatusBar)
530         {
531             if (GTK_WIDGET_VISIBLE(m_frameStatusBar->m_widget))
532                 gtk_widget_hide( m_frameStatusBar->m_widget );
533         }
534     }
535 #endif // wxUSE_STATUSBAR
536 
537     m_sizeSet = true;
538 
539     // send size event to frame
540     wxSizeEvent event( wxSize(m_width,m_height), GetId() );
541     event.SetEventObject( this );
542     GetEventHandler()->ProcessEvent( event );
543 
544 #if wxUSE_STATUSBAR
545     // send size event to status bar
546     if (m_frameStatusBar)
547     {
548         wxSizeEvent event2( wxSize(m_frameStatusBar->m_width,m_frameStatusBar->m_height), m_frameStatusBar->GetId() );
549         event2.SetEventObject( m_frameStatusBar );
550         m_frameStatusBar->GetEventHandler()->ProcessEvent( event2 );
551     }
552 #endif // wxUSE_STATUSBAR
553 
554     m_resizing = false;
555 }
556 
OnInternalIdle()557 void wxFrame::OnInternalIdle()
558 {
559     wxFrameBase::OnInternalIdle();
560 
561 #if wxUSE_MENUS_NATIVE
562     if (m_frameMenuBar) m_frameMenuBar->OnInternalIdle();
563 
564     // UpdateMenuBarSize may return a height of zero on some
565     // systems (e.g. Ubuntu 11.04 Alpha as of 2010-12-06),
566     // when the menubar widget has not been fully realized.
567     // Update the menu bar size again at this point, otherwise
568     // the menu would not be visible at all.
569     if (!m_menuBarHeight)
570     {
571         UpdateMenuBarSize();
572     }
573 #endif // wxUSE_MENUS_NATIVE
574 #if wxUSE_TOOLBAR
575     if (m_frameToolBar) m_frameToolBar->OnInternalIdle();
576 #endif
577 #if wxUSE_STATUSBAR
578     if (m_frameStatusBar)
579     {
580         m_frameStatusBar->OnInternalIdle();
581 
582         // There may be controls in the status bar that
583         // need to be updated
584         for ( wxWindowList::compatibility_iterator node = m_frameStatusBar->GetChildren().GetFirst();
585           node;
586           node = node->GetNext() )
587         {
588             wxWindow *child = node->GetData();
589             child->OnInternalIdle();
590         }
591     }
592 #endif
593 }
594 
595 // ----------------------------------------------------------------------------
596 // menu/tool/status bar stuff
597 // ----------------------------------------------------------------------------
598 
599 #if wxUSE_MENUS_NATIVE
600 
DetachMenuBar()601 void wxFrame::DetachMenuBar()
602 {
603     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
604     wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
605 
606     if ( m_frameMenuBar )
607     {
608         g_signal_handlers_disconnect_by_func(
609             m_frameMenuBar->m_widget, (void*)menubar_style_set, this);
610 
611         m_frameMenuBar->UnsetInvokingWindow( this );
612 
613         if (m_frameMenuBar->GetWindowStyle() & wxMB_DOCKABLE)
614         {
615             g_signal_handlers_disconnect_by_func (m_frameMenuBar->m_widget,
616                     (gpointer) gtk_menu_attached_callback,
617                     this);
618 
619             g_signal_handlers_disconnect_by_func (m_frameMenuBar->m_widget,
620                     (gpointer) gtk_menu_detached_callback,
621                     this);
622         }
623 
624         gtk_widget_ref( m_frameMenuBar->m_widget );
625 
626         gtk_container_remove( GTK_CONTAINER(m_mainWidget), m_frameMenuBar->m_widget );
627     }
628 
629     wxFrameBase::DetachMenuBar();
630 }
631 
AttachMenuBar(wxMenuBar * menuBar)632 void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
633 {
634     wxFrameBase::AttachMenuBar(menuBar);
635 
636     if (m_frameMenuBar)
637     {
638         m_frameMenuBar->SetInvokingWindow( this );
639 
640         m_frameMenuBar->SetParent(this);
641         gtk_pizza_put( GTK_PIZZA(m_mainWidget),
642                 m_frameMenuBar->m_widget,
643                 m_frameMenuBar->m_x,
644                 m_frameMenuBar->m_y,
645                 m_frameMenuBar->m_width,
646                 m_frameMenuBar->m_height );
647 
648         if (menuBar->GetWindowStyle() & wxMB_DOCKABLE)
649         {
650             g_signal_connect (menuBar->m_widget, "child_attached",
651                               G_CALLBACK (gtk_menu_attached_callback),
652                               this);
653             g_signal_connect (menuBar->m_widget, "child_detached",
654                               G_CALLBACK (gtk_menu_detached_callback),
655                               this);
656         }
657 
658         gtk_widget_show( m_frameMenuBar->m_widget );
659 
660         UpdateMenuBarSize();
661 
662         g_signal_connect(menuBar->m_widget, "style-set",
663             G_CALLBACK(menubar_style_set), this);
664     }
665     else
666     {
667         m_menuBarHeight = 2;
668         GtkUpdateSize();        // resize window in OnInternalIdle
669     }
670 }
671 
UpdateMenuBarSize()672 void wxFrame::UpdateMenuBarSize()
673 {
674     int oldMenuBarHeight = m_menuBarHeight;
675     m_menuBarHeight = 2;
676 
677     // this is called after Remove with a NULL m_frameMenuBar
678     if ( m_frameMenuBar )
679     {
680         GtkRequisition req;
681         gtk_widget_ensure_style(m_frameMenuBar->m_widget);
682         // have to call class method directly because
683         // "size_request" signal is overridden by wx
684         GTK_WIDGET_GET_CLASS(m_frameMenuBar->m_widget)->size_request(
685             m_frameMenuBar->m_widget, &req);
686 
687         m_menuBarHeight = req.height;
688     }
689 
690     // resize window in OnInternalIdle
691     if (oldMenuBarHeight != m_menuBarHeight)
692         GtkUpdateSize();
693 }
694 
695 #endif // wxUSE_MENUS_NATIVE
696 
697 #if wxUSE_TOOLBAR
698 
CreateToolBar(long style,wxWindowID id,const wxString & name)699 wxToolBar* wxFrame::CreateToolBar( long style, wxWindowID id, const wxString& name )
700 {
701     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
702 
703     m_insertInClientArea = false;
704 
705     m_frameToolBar = wxFrameBase::CreateToolBar( style, id, name );
706 
707     m_insertInClientArea = true;
708 
709     GtkUpdateSize();
710 
711     return m_frameToolBar;
712 }
713 
SetToolBar(wxToolBar * toolbar)714 void wxFrame::SetToolBar(wxToolBar *toolbar)
715 {
716     bool hadTbar = m_frameToolBar != NULL;
717 
718     wxFrameBase::SetToolBar(toolbar);
719 
720     if ( m_frameToolBar )
721     {
722         // insert into toolbar area if not already there
723         if ((m_frameToolBar->m_widget->parent) &&
724             (m_frameToolBar->m_widget->parent != m_mainWidget))
725         {
726             GetChildren().DeleteObject( m_frameToolBar );
727 
728             gtk_widget_reparent( m_frameToolBar->m_widget, m_mainWidget );
729             GtkUpdateSize();
730         }
731     }
732     else // toolbar unset
733     {
734         // still need to update size if it had been there before
735         if ( hadTbar )
736         {
737             GtkUpdateSize();
738         }
739     }
740 }
741 
742 #endif // wxUSE_TOOLBAR
743 
744 #if wxUSE_STATUSBAR
745 
CreateStatusBar(int number,long style,wxWindowID id,const wxString & name)746 wxStatusBar* wxFrame::CreateStatusBar(int number,
747                                       long style,
748                                       wxWindowID id,
749                                       const wxString& name)
750 {
751     wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
752 
753     // because it will change when toolbar is added
754     GtkUpdateSize();
755 
756     return wxFrameBase::CreateStatusBar( number, style, id, name );
757 }
758 
SetStatusBar(wxStatusBar * statbar)759 void wxFrame::SetStatusBar(wxStatusBar *statbar)
760 {
761     bool hadStatBar = m_frameStatusBar != NULL;
762 
763     wxFrameBase::SetStatusBar(statbar);
764 
765     if (hadStatBar && !m_frameStatusBar)
766         GtkUpdateSize();
767 }
768 
PositionStatusBar()769 void wxFrame::PositionStatusBar()
770 {
771     if ( !m_frameStatusBar )
772         return;
773 
774     GtkUpdateSize();
775 }
776 #endif // wxUSE_STATUSBAR
777