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
28static const int wxSTATUS_HEIGHT  = 25;
29static const int wxPLACE_HOLDER   = 0;
30
31// ----------------------------------------------------------------------------
32// event tables
33// ----------------------------------------------------------------------------
34
35IMPLEMENT_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
51extern "C" {
52static 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
65extern "C" {
66static 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
85extern "C" {
86static 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
98extern "C" {
99static 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
112extern "C" {
113static 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
126extern "C" {
127static 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
157static 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
206void wxFrame::Init()
207{
208    m_menuBarDetached = false;
209    m_toolBarDetached = false;
210    m_menuBarHeight = 2;
211}
212
213bool 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
228wxFrame::~wxFrame()
229{
230    m_isBeingDeleted = true;
231    DeleteAllBars();
232}
233
234// ----------------------------------------------------------------------------
235// overridden wxWindow methods
236// ----------------------------------------------------------------------------
237
238void 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
298void 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
347void 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
557void 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
601void 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
632void 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
672void 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
699wxToolBar* 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
714void 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
746wxStatusBar* 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
759void 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
769void wxFrame::PositionStatusBar()
770{
771    if ( !m_frameStatusBar )
772        return;
773
774    GtkUpdateSize();
775}
776#endif // wxUSE_STATUSBAR
777