1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  11     #pragma implementation "frame.h" 
  15 #include "wx/dialog.h" 
  16 #include "wx/control.h" 
  20 #include "wx/toolbar.h" 
  23 #include "wx/statusbr.h" 
  25 #include "wx/dcclient.h" 
  30 #include "wx/gtk/win_gtk.h" 
  31 #include "gdk/gdkkeysyms.h" 
  34 //----------------------------------------------------------------------------- 
  36 //----------------------------------------------------------------------------- 
  38 const int wxMENU_HEIGHT    
= 27; 
  39 const int wxSTATUS_HEIGHT  
= 25; 
  40 const int wxPLACE_HOLDER   
= 0; 
  42 //----------------------------------------------------------------------------- 
  44 //----------------------------------------------------------------------------- 
  46 extern void wxapp_install_idle_handler(); 
  49 //----------------------------------------------------------------------------- 
  51 //----------------------------------------------------------------------------- 
  53 extern wxList wxPendingDelete
; 
  55 //----------------------------------------------------------------------------- 
  57 //----------------------------------------------------------------------------- 
  61 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar 
*window 
); 
  65 //----------------------------------------------------------------------------- 
  67 //----------------------------------------------------------------------------- 
  69 static void gtk_frame_size_callback( GtkWidget 
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame 
*win 
) 
  72         wxapp_install_idle_handler(); 
  77     if ((win
->m_width 
!= alloc
->width
) || (win
->m_height 
!= alloc
->height
)) 
  80         wxPrintf( "OnSize from " ); 
  81         if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
  82            wxPrintf( win->GetClassInfo()->GetClassName() ); 
  83         wxPrintf( " %d %d %d %d\n", (int)alloc->x, 
  89         win
->m_width 
= alloc
->width
; 
  90         win
->m_height 
= alloc
->height
; 
  95 //----------------------------------------------------------------------------- 
  97 //----------------------------------------------------------------------------- 
  99 static gint 
gtk_frame_delete_callback( GtkWidget 
*WXUNUSED(widget
), GdkEvent 
*WXUNUSED(event
), wxFrame 
*win 
) 
 102         wxapp_install_idle_handler(); 
 109 //----------------------------------------------------------------------------- 
 110 // "child_attached" of menu bar 
 111 //----------------------------------------------------------------------------- 
 113 static void gtk_menu_attached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 115     if (!win
->m_hasVMT
) return; 
 117     win
->m_menuBarDetached 
= FALSE
; 
 121 //----------------------------------------------------------------------------- 
 122 // "child_detached" of menu bar 
 123 //----------------------------------------------------------------------------- 
 125 static void gtk_menu_detached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 127     if (!win
->m_hasVMT
) return; 
 129     win
->m_menuBarDetached 
= TRUE
; 
 134 //----------------------------------------------------------------------------- 
 135 // "child_attached" of tool bar 
 136 //----------------------------------------------------------------------------- 
 138 static void gtk_toolbar_attached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 140     if (!win
->m_hasVMT
) return; 
 142     win
->m_toolBarDetached 
= FALSE
; 
 147 //----------------------------------------------------------------------------- 
 148 // "child_detached" of tool bar 
 149 //----------------------------------------------------------------------------- 
 151 static void gtk_toolbar_detached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 154         wxapp_install_idle_handler(); 
 156     if (!win
->m_hasVMT
) return; 
 158     win
->m_toolBarDetached 
= TRUE
; 
 161 #endif // wxUSE_TOOLBAR 
 163 //----------------------------------------------------------------------------- 
 165 //----------------------------------------------------------------------------- 
 168 #if (GTK_MINOR_VERSON > 0) 
 169 gtk_frame_configure_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventConfigure 
*WXUNUSED(event
), wxFrame 
*win 
) 
 171 gtk_frame_configure_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventConfigure 
*event
, wxFrame 
*win 
) 
 175         wxapp_install_idle_handler(); 
 177     if (!win
->m_hasVMT
) return FALSE
; 
 179 #if (GTK_MINOR_VERSON > 0) 
 182     gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y 
); 
 190     wxMoveEvent 
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() ); 
 191     mevent
.SetEventObject( win 
); 
 192     win
->GetEventHandler()->ProcessEvent( mevent 
); 
 197 //----------------------------------------------------------------------------- 
 198 // "realize" from m_widget 
 199 //----------------------------------------------------------------------------- 
 201 /* we cannot MWM hints and icons before the widget has been realized, 
 202    so we do this directly after realization */ 
 205 gtk_frame_realized_callback( GtkWidget 
*widget
, wxFrame 
*win 
) 
 208         wxapp_install_idle_handler(); 
 210     /* I haven't been able to set the position of 
 211        the dialog before it is shown, so I set the 
 212        position in "realize" */ 
 213     gtk_widget_set_uposition( widget
, win
->m_x
, win
->m_y 
); 
 215     /* all this is for Motif Window Manager "hints" and is supposed to be 
 216        recognized by other WM as well. not tested. */ 
 217     long decor 
= (long) GDK_DECOR_BORDER
; 
 218     long func 
= (long) GDK_FUNC_MOVE
; 
 220     if ((win
->GetWindowStyle() & wxCAPTION
) != 0) 
 221         decor 
|= GDK_DECOR_TITLE
; 
 222     if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0) 
 224        decor 
|= GDK_DECOR_MENU
; 
 225        func 
|= GDK_FUNC_CLOSE
; 
 227     if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0) 
 229         func 
|= GDK_FUNC_MINIMIZE
; 
 230         decor 
|= GDK_DECOR_MINIMIZE
; 
 232     if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0) 
 234         func 
|= GDK_FUNC_MAXIMIZE
; 
 235         decor 
|= GDK_DECOR_MAXIMIZE
; 
 237     if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0) 
 239        func 
|= GDK_FUNC_RESIZE
; 
 240        decor 
|= GDK_DECOR_RESIZEH
; 
 243     gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
); 
 244     gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
); 
 246     /* GTK's shrinking/growing policy */ 
 247     if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0) 
 248         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1); 
 250         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1); 
 253     gint flag 
= 0; // GDK_HINT_POS; 
 254     if ((win
->GetMinWidth() != -1) || (win
->GetMinHeight() != -1)) flag 
|= GDK_HINT_MIN_SIZE
; 
 255     if ((win
->GetMaxWidth() != -1) || (win
->GetMaxHeight() != -1)) flag 
|= GDK_HINT_MAX_SIZE
; 
 258         gdk_window_set_hints( win
->m_widget
->window
,  
 260                               win
->GetMinWidth(), win
->GetMinHeight(), 
 261                               win
->GetMaxWidth(), win
->GetMaxHeight(), 
 266     if (win
->m_icon 
!= wxNullIcon
) 
 268         wxIcon 
icon( win
->m_icon 
); 
 269         win
->m_icon 
= wxNullIcon
; 
 270         win
->SetIcon( icon 
); 
 273     /* we set the focus to the child that accepts the focus. this 
 274        doesn't really have to be done in "realize" but why not? */ 
 275     wxWindowList::Node 
*node 
= win
->GetChildren().GetFirst(); 
 278         wxWindow 
*child 
= node
->GetData(); 
 279         if (child
->AcceptsFocus()) 
 285         node 
= node
->GetNext(); 
 291 //----------------------------------------------------------------------------- 
 292 // InsertChild for wxFrame 
 293 //----------------------------------------------------------------------------- 
 295 /* Callback for wxFrame. This very strange beast has to be used because 
 296  * C++ has no virtual methods in a constructor. We have to emulate a 
 297  * virtual function here as wxWindows requires different ways to insert 
 298  * a child in container classes. */ 
 300 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child 
) 
 302     wxASSERT( GTK_IS_WIDGET(child
->m_widget
) ); 
 304     if (!parent
->m_insertInClientArea
) 
 306         /* these are outside the client area */ 
 307         wxFrame
* frame 
= (wxFrame
*) parent
; 
 308         gtk_pizza_put( GTK_PIZZA(frame
->m_mainWidget
), 
 309                          GTK_WIDGET(child
->m_widget
), 
 316         /* we connect to these events for recalculating the client area 
 317            space when the toolbar is floating */ 
 318         if (wxIS_KIND_OF(child
,wxToolBar
)) 
 320             wxToolBar 
*toolBar 
= (wxToolBar
*) child
; 
 321             if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
) 
 323                 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached", 
 324                     GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent 
); 
 326                 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached", 
 327                     GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent 
); 
 330 #endif // wxUSE_TOOLBAR 
 334         /* these are inside the client area */ 
 335         gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
), 
 336                          GTK_WIDGET(child
->m_widget
), 
 343     /* resize on OnInternalIdle */ 
 344     parent
->UpdateSize(); 
 347 //----------------------------------------------------------------------------- 
 349 //----------------------------------------------------------------------------- 
 351 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
) 
 352     EVT_SIZE(wxFrame::OnSize
) 
 353     EVT_IDLE(wxFrame::OnIdle
) 
 354     EVT_CLOSE(wxFrame::OnCloseWindow
) 
 355     EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
) 
 358 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
) 
 362     m_frameMenuBar 
= (wxMenuBar 
*) NULL
; 
 364     m_frameStatusBar 
= (wxStatusBar 
*) NULL
; 
 365 #endif // wxUSE_STATUSBAR 
 367     m_frameToolBar 
= (wxToolBar 
*) NULL
; 
 368 #endif // wxUSE_TOOLBAR 
 372     m_mainWidget 
= (GtkWidget
*) NULL
; 
 373     m_menuBarDetached 
= FALSE
; 
 374     m_toolBarDetached 
= FALSE
; 
 375     m_insertInClientArea 
= TRUE
; 
 379 wxFrame::wxFrame( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
 380       const wxPoint 
&pos
, const wxSize 
&size
, 
 381       long style
, const wxString 
&name 
) 
 385     Create( parent
, id
, title
, pos
, size
, style
, name 
); 
 388 bool wxFrame::Create( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
 389       const wxPoint 
&pos
, const wxSize 
&size
, 
 390       long style
, const wxString 
&name 
) 
 392     wxTopLevelWindows
.Append( this ); 
 394     m_needParent 
= FALSE
; 
 396     if (!PreCreation( parent
, pos
, size 
) || 
 397         !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
 399         wxFAIL_MSG( wxT("wxFrame creation failed") ); 
 405     m_insertCallback 
= (wxInsertChildFunction
) wxInsertChildInFrame
; 
 407     GtkWindowType win_type 
= GTK_WINDOW_TOPLEVEL
; 
 408     if (style 
& wxSIMPLE_BORDER
) win_type 
= GTK_WINDOW_POPUP
; 
 410     m_widget 
= gtk_window_new( win_type 
); 
 413         gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() ); 
 416     debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name 
); 
 419     gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() ); 
 420     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
 422     gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event", 
 423         GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this ); 
 425     /* m_mainWidget holds the toolbar, the menubar and the client area */ 
 426     m_mainWidget 
= gtk_pizza_new(); 
 427     gtk_widget_show( m_mainWidget 
); 
 428     GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS 
); 
 429     gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget 
); 
 432     debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name 
); 
 435     /* m_wxwindow only represents the client area without toolbar and menubar */ 
 436     m_wxwindow 
= gtk_pizza_new(); 
 437     gtk_widget_show( m_wxwindow 
); 
 438     gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow 
); 
 441     debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name 
); 
 444     /* we donm't allow the frame to get the focus as otherwise 
 445        the frame will grabit at arbitrary fcous changes. */ 
 446     GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
 448     if (m_parent
) m_parent
->AddChild( this ); 
 450     /* the user resized the frame by dragging etc. */ 
 451     gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate", 
 452         GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this ); 
 456     /*  we cannot set MWM hints and icons before the widget has 
 457         been realized, so we do this directly after realization */ 
 458     gtk_signal_connect( GTK_OBJECT(m_widget
), "realize", 
 459                         GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this ); 
 461     /* the only way to get the window size is to connect to this event */ 
 462     gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event", 
 463         GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this ); 
 470     m_isBeingDeleted 
= TRUE
; 
 472     if (m_frameMenuBar
) delete m_frameMenuBar
; 
 473     m_frameMenuBar 
= (wxMenuBar 
*) NULL
; 
 476     if (m_frameStatusBar
) delete m_frameStatusBar
; 
 477     m_frameStatusBar 
= (wxStatusBar 
*) NULL
; 
 478 #endif // wxUSE_STATUSBAR 
 481     if (m_frameToolBar
) delete m_frameToolBar
; 
 482     m_frameToolBar 
= (wxToolBar 
*) NULL
; 
 483 #endif // wxUSE_TOOLBAR 
 485     wxTopLevelWindows
.DeleteObject( this ); 
 487     if (wxTheApp
->GetTopWindow() == this) 
 488         wxTheApp
->SetTopWindow( (wxWindow
*) NULL 
); 
 490     if (wxTopLevelWindows
.Number() == 0) 
 491         wxTheApp
->ExitMainLoop(); 
 494 bool wxFrame::Show( bool show 
) 
 496     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 498     if (show 
&& !m_sizeSet
) 
 500         /* by calling GtkOnSize here, we don't have to call 
 501            either after showing the frame, which would entail 
 502            much ugly flicker or from within the size_allocate 
 503            handler, because GTK 1.1.X forbids that. */ 
 505         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 508     return wxWindow::Show( show 
); 
 511 bool wxFrame::Destroy() 
 513     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 515     if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this); 
 520 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
 522     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 524     /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */ 
 525     wxASSERT_MSG( (m_wxwindow 
!= NULL
), wxT("invalid frame") ); 
 527     /* avoid recursions */ 
 528     if (m_resizing
) return; 
 533     int old_width 
= m_width
; 
 534     int old_height 
= m_height
; 
 536     if ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0) 
 538         if (x 
!= -1) m_x 
= x
; 
 539         if (y 
!= -1) m_y 
= y
; 
 540         if (width 
!= -1) m_width 
= width
; 
 541         if (height 
!= -1) m_height 
= height
; 
 552     if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH) 
 554         if (width == -1) m_width = 80; 
 557     if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT) 
 559        if (height == -1) m_height = 26; 
 563     if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
 564     if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
 565     if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
 566     if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
 568     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 570         if ((m_x 
!= old_x
) || (m_y 
!= old_y
)) 
 572             gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 576     if ((m_width 
!= old_width
) || (m_height 
!= old_height
)) 
 578         /* we set the size in GtkOnSize, i.e. mostly the actual resizing is 
 579            done either directly before the frame is shown or in idle time 
 580            so that different calls to SetSize() don't lead to flicker. */ 
 587 void wxFrame::Centre( int direction 
) 
 589     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 594     if ((direction 
& wxHORIZONTAL
) == wxHORIZONTAL
) x 
= (gdk_screen_width () - m_width
) / 2; 
 595     if ((direction 
& wxVERTICAL
) == wxVERTICAL
) y 
= (gdk_screen_height () - m_height
) / 2; 
 600 void wxFrame::DoGetClientSize( int *width
, int *height 
) const 
 602     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 604     wxWindow::DoGetClientSize( width
, height 
); 
 610             if (!m_menuBarDetached
) 
 611                 (*height
) -= wxMENU_HEIGHT
; 
 613                 (*height
) -= wxPLACE_HOLDER
; 
 618         if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
; 
 625             if (!m_toolBarDetached
) 
 628                 m_frameToolBar
->GetSize( (int *) NULL
, &y 
); 
 632                 (*height
) -= wxPLACE_HOLDER
; 
 637         (*height
) -= m_miniEdge
*2 + m_miniTitle
; 
 641         (*width
) -= m_miniEdge
*2; 
 645 void wxFrame::DoSetClientSize( int width
, int height 
) 
 647     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 652             if (!m_menuBarDetached
) 
 653                 height 
+= wxMENU_HEIGHT
; 
 655                 height 
+= wxPLACE_HOLDER
; 
 660         if (m_frameStatusBar
) height 
+= wxSTATUS_HEIGHT
; 
 667             if (!m_toolBarDetached
) 
 670                 m_frameToolBar
->GetSize( (int *) NULL
, &y 
); 
 674                 height 
+= wxPLACE_HOLDER
; 
 678     DoSetSize( -1, -1, width 
+ m_miniEdge
*2, height  
+ m_miniEdge
*2 + m_miniTitle
, 0 ); 
 681 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height 
) 
 683     // due to a bug in gtk, x,y are always 0 
 687     /* avoid recursions */ 
 688     if (m_resizing
) return; 
 691     /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */ 
 692     wxASSERT_MSG( (m_wxwindow 
!= NULL
), wxT("invalid frame") ); 
 697     /* space occupied by m_frameToolBar and m_frameMenuBar */ 
 698     int client_area_y_offset 
= 0; 
 700     /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses 
 701        wxWindow::Create to create it's GTK equivalent. m_mainWidget is only 
 702        set in wxFrame::Create so it is used to check what kind of frame we 
 703        have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we 
 704        skip the part which handles m_frameMenuBar, m_frameToolBar and (most 
 705        importantly) m_mainWidget */ 
 709         /* check if size is in legal range */ 
 710         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
 711         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
 712         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
 713         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
 715         /* I revert back to wxGTK's original behaviour. m_mainWidget holds the 
 716          * menubar, the toolbar and the client area, which is represented by 
 718          * this hurts in the eye, but I don't want to call SetSize() 
 719          * because I don't want to call any non-native functions here. */ 
 724             int yy 
= m_miniEdge 
+ m_miniTitle
; 
 725             int ww 
= m_width  
- 2*m_miniEdge
; 
 726             int hh 
= wxMENU_HEIGHT
; 
 727             if (m_menuBarDetached
) hh 
= wxPLACE_HOLDER
; 
 728             m_frameMenuBar
->m_x 
= xx
; 
 729             m_frameMenuBar
->m_y 
= yy
; 
 730             m_frameMenuBar
->m_width 
= ww
; 
 731             m_frameMenuBar
->m_height 
= hh
; 
 732             gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
), 
 733                                   m_frameMenuBar
->m_widget
, 
 735             client_area_y_offset 
+= hh
; 
 739         if ((m_frameToolBar
) && 
 740             (m_frameToolBar
->m_widget
->parent 
== m_mainWidget
)) 
 743             int yy 
= m_miniEdge 
+ m_miniTitle
; 
 746                 if (!m_menuBarDetached
) 
 749                     yy 
+= wxPLACE_HOLDER
; 
 751             int ww 
= m_width 
- 2*m_miniEdge
; 
 752             int hh 
= m_frameToolBar
->m_height
; 
 753             if (m_toolBarDetached
) hh 
= wxPLACE_HOLDER
; 
 754             m_frameToolBar
->m_x 
= xx
; 
 755             m_frameToolBar
->m_y 
= yy
; 
 756             /* m_frameToolBar->m_height = hh;   don't change the toolbar's reported size 
 757                m_frameToolBar->m_width = ww; */ 
 758             gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
), 
 759                                   m_frameToolBar
->m_widget
, 
 761             client_area_y_offset 
+= hh
; 
 765         int client_x 
= m_miniEdge
; 
 766         int client_y 
= client_area_y_offset 
+ m_miniEdge 
+ m_miniTitle
; 
 767         int client_w 
= m_width 
- 2*m_miniEdge
; 
 768         int client_h 
= m_height 
- client_area_y_offset
- 2*m_miniEdge 
- m_miniTitle
; 
 769         gtk_pizza_set_size( GTK_PIZZA(m_mainWidget
), 
 771                               client_x
, client_y
, client_w
, client_h 
); 
 775         /* if there is no m_mainWidget between m_widget and m_wxwindow there 
 776            is no need to set the size or position of m_wxwindow. */ 
 780     if (m_frameStatusBar
) 
 782         int xx 
= 0 + m_miniEdge
; 
 783         int yy 
= m_height 
- wxSTATUS_HEIGHT 
- m_miniEdge 
- client_area_y_offset
; 
 784         int ww 
= m_width 
- 2*m_miniEdge
; 
 785         int hh 
= wxSTATUS_HEIGHT
; 
 786         m_frameStatusBar
->m_x 
= xx
; 
 787         m_frameStatusBar
->m_y 
= yy
; 
 788         m_frameStatusBar
->m_width 
= ww
; 
 789         m_frameStatusBar
->m_height 
= hh
; 
 790         gtk_pizza_set_size( GTK_PIZZA(m_wxwindow
), 
 791                               m_frameStatusBar
->m_widget
, 
 796     /* we actually set the size of a frame here and no-where else */ 
 797     gtk_widget_set_usize( m_widget
, m_width
, m_height 
); 
 802     // send size event to frame 
 803     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
 804     event
.SetEventObject( this ); 
 805     GetEventHandler()->ProcessEvent( event 
); 
 807     // send size event to status bar 
 808     if (m_frameStatusBar
) 
 810         wxSizeEvent 
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() ); 
 811         event2
.SetEventObject( m_frameStatusBar 
); 
 812         m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2 
); 
 818 void wxFrame::MakeModal( bool modal 
) 
 821         gtk_grab_add( m_widget 
); 
 823         gtk_grab_remove( m_widget 
); 
 826 void wxFrame::OnInternalIdle() 
 828     if (!m_sizeSet 
&& GTK_WIDGET_REALIZED(m_wxwindow
)) 
 830         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 832         // we'll come back later 
 834             wxapp_install_idle_handler(); 
 838     if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle(); 
 840     if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle(); 
 843     if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle(); 
 846     wxWindow::OnInternalIdle(); 
 849 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) ) 
 854 void wxFrame::OnSize( wxSizeEvent 
&WXUNUSED(event
) ) 
 856     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 858 #if wxUSE_CONSTRAINTS 
 864 #endif // wxUSE_CONSTRAINTS 
 866         /* do we have exactly one child? */ 
 867         wxWindow 
*child 
= (wxWindow 
*)NULL
; 
 868         for ( wxNode 
*node 
= GetChildren().First(); node
; node 
= node
->Next() ) 
 870             wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
 871             if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) ) 
 875                     /* it's the second one: do nothing */ 
 883         /* no children at all? */ 
 886             /* yes: set it's size to fill all the frame */ 
 887             int client_x
, client_y
; 
 888             DoGetClientSize( &client_x
, &client_y 
); 
 889             child
->SetSize( 1, 1, client_x
-2, client_y
-2 ); 
 894 void wxFrame::SetMenuBar( wxMenuBar 
*menuBar 
) 
 896     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 897     wxASSERT_MSG( (m_wxwindow 
!= NULL
), wxT("invalid frame") ); 
 899     m_frameMenuBar 
= menuBar
; 
 903         m_frameMenuBar
->SetInvokingWindow( this ); 
 905         if (m_frameMenuBar
->GetParent() != this) 
 907             m_frameMenuBar
->SetParent(this); 
 908             gtk_pizza_put( GTK_PIZZA(m_mainWidget
), 
 909                 m_frameMenuBar
->m_widget
, 
 912                 m_frameMenuBar
->m_width
, 
 913                 m_frameMenuBar
->m_height 
); 
 915             if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
) 
 917                 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached", 
 918                     GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this ); 
 920                 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached", 
 921                     GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this ); 
 924             m_frameMenuBar
->Show( TRUE 
); 
 928     /* resize window in OnInternalIdle */ 
 932 wxMenuBar 
*wxFrame::GetMenuBar() const 
 934     return m_frameMenuBar
; 
 937 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
) 
 942         // if no help string found, we will clear the status bar text 
 945         int menuId 
= event
.GetMenuId(); 
 946         if ( menuId 
!= wxID_SEPARATOR 
&& menuId 
!= -2 /* wxID_TITLE */ ) 
 948             wxMenuBar 
*menuBar 
= GetMenuBar(); 
 951                 // it's ok if we don't find the item because it might belong to 
 953                 wxMenuItem 
*item 
= menuBar
->FindItem(menuId
); 
 955                     helpString 
= item
->GetHelp(); 
 959         SetStatusText(helpString
); 
 961 #endif // wxUSE_STATUSBAR 
 965 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name 
) 
 967     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 969     wxCHECK_MSG( m_frameToolBar 
== NULL
, FALSE
, wxT("recreating toolbar in wxFrame") ); 
 971     m_insertInClientArea 
= FALSE
; 
 973     m_frameToolBar 
= OnCreateToolBar( style
, id
, name 
); 
 975     if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar 
); 
 977     m_insertInClientArea 
= TRUE
; 
 981     return m_frameToolBar
; 
 984 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name 
) 
 986     return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name 
); 
 989 void wxFrame::SetToolBar(wxToolBar 
*toolbar
)  
 991     m_frameToolBar 
= toolbar
;  
 994         /* insert into toolbar area if not already there */ 
 995         if ((m_frameToolBar
->m_widget
->parent
) && 
 996             (m_frameToolBar
->m_widget
->parent 
!= m_mainWidget
)) 
 998             GetChildren().DeleteObject( m_frameToolBar 
); 
1000             gtk_widget_reparent( m_frameToolBar
->m_widget
, m_mainWidget 
); 
1006 wxToolBar 
*wxFrame::GetToolBar() const 
1008     return m_frameToolBar
; 
1010 #endif // wxUSE_TOOLBAR 
1013 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name 
) 
1015     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1017     wxCHECK_MSG( m_frameStatusBar 
== NULL
, FALSE
, wxT("recreating status bar in wxFrame") ); 
1019     m_frameStatusBar 
= OnCreateStatusBar( number
, style
, id
, name 
); 
1023     return m_frameStatusBar
; 
1026 wxStatusBar 
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name 
) 
1028     wxStatusBar 
*statusBar 
= (wxStatusBar 
*) NULL
; 
1030     statusBar 
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
); 
1032     // Set the height according to the font and the border size 
1033     wxClientDC 
dc(statusBar
); 
1034     dc
.SetFont( statusBar
->GetFont() ); 
1037     dc
.GetTextExtent( "X", &x
, &y 
); 
1039     int height 
= (int)( (y  
* 1.1) + 2* statusBar
->GetBorderY()); 
1041     statusBar
->SetSize( -1, -1, 100, height 
); 
1043     statusBar
->SetFieldsCount( number 
); 
1047 wxStatusBar 
*wxFrame::GetStatusBar() const 
1049     return m_frameStatusBar
; 
1052 void wxFrame::SetStatusText(const wxString
& text
, int number
) 
1054     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1056     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set text for") ); 
1058     m_frameStatusBar
->SetStatusText(text
, number
); 
1061 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] ) 
1063     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1065     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set widths for") ); 
1067     m_frameStatusBar
->SetStatusWidths(n
, widths_field
); 
1069 #endif // wxUSE_STATUSBAR 
1071 void wxFrame::Command( int id 
) 
1073     wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
); 
1074     commandEvent
.SetInt( id 
); 
1075     commandEvent
.SetEventObject( this ); 
1077     wxMenuBar 
*bar 
= GetMenuBar(); 
1080     wxMenuItem 
*item 
= bar
->FindItem(id
) ; 
1081     if (item 
&& item
->IsCheckable()) 
1083         bar
->Check(id
, !bar
->IsChecked(id
)) ; 
1086     wxEvtHandler
* evtHandler 
= GetEventHandler(); 
1088     evtHandler
->ProcessEvent(commandEvent
); 
1091 void wxFrame::SetTitle( const wxString 
&title 
) 
1093     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1096     if (m_title
.IsNull()) m_title 
= wxT(""); 
1097     gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() ); 
1100 void wxFrame::SetIcon( const wxIcon 
&icon 
) 
1102     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1105     if (!icon
.Ok()) return; 
1107     if (!m_widget
->window
) return; 
1109     wxMask 
*mask 
= icon
.GetMask(); 
1110     GdkBitmap 
*bm 
= (GdkBitmap 
*) NULL
; 
1111     if (mask
) bm 
= mask
->GetBitmap(); 
1113     gdk_window_set_icon( m_widget
->window
, (GdkWindow 
*) NULL
, icon
.GetPixmap(), bm 
); 
1116 void wxFrame::Maximize(bool WXUNUSED(maximize
))  
1120 void wxFrame::Restore()  
1124 void wxFrame::Iconize( bool iconize 
)  
1128         XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window 
), 
1129                         GDK_WINDOW_XWINDOW( m_widget
->window 
), 
1130                         DefaultScreen( GDK_DISPLAY() ) ); 
1134 bool wxFrame::IsIconized() const