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" 
  33 //----------------------------------------------------------------------------- 
  35 //----------------------------------------------------------------------------- 
  37 const int wxMENU_HEIGHT    
= 27; 
  38 const int wxSTATUS_HEIGHT  
= 25; 
  39 const int wxPLACE_HOLDER   
= 0; 
  41 //----------------------------------------------------------------------------- 
  43 //----------------------------------------------------------------------------- 
  45 extern void wxapp_install_idle_handler(); 
  48 //----------------------------------------------------------------------------- 
  50 //----------------------------------------------------------------------------- 
  52 extern wxList wxPendingDelete
; 
  54 //----------------------------------------------------------------------------- 
  56 //----------------------------------------------------------------------------- 
  60 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar 
*window 
); 
  64 //----------------------------------------------------------------------------- 
  66 //----------------------------------------------------------------------------- 
  68 static void gtk_frame_size_callback( GtkWidget 
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame 
*win 
) 
  71         wxapp_install_idle_handler(); 
  73     if (!win
->m_hasVMT
) return; 
  75     if ((win
->m_width 
!= alloc
->width
) || (win
->m_height 
!= alloc
->height
)) 
  77         win
->m_width 
= alloc
->width
; 
  78         win
->m_height 
= alloc
->height
; 
  83 //----------------------------------------------------------------------------- 
  85 //----------------------------------------------------------------------------- 
  87 static gint 
gtk_frame_delete_callback( GtkWidget 
*WXUNUSED(widget
), GdkEvent 
*WXUNUSED(event
), wxFrame 
*win 
) 
  90         wxapp_install_idle_handler(); 
  97 //----------------------------------------------------------------------------- 
  98 // "child_attached" of menu bar 
  99 //----------------------------------------------------------------------------- 
 101 static void gtk_menu_attached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 103     if (!win
->m_hasVMT
) return; 
 105     win
->m_menuBarDetached 
= FALSE
; 
 109 //----------------------------------------------------------------------------- 
 110 // "child_detached" of menu bar 
 111 //----------------------------------------------------------------------------- 
 113 static void gtk_menu_detached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 115     if (!win
->m_hasVMT
) return; 
 117     win
->m_menuBarDetached 
= TRUE
; 
 122 //----------------------------------------------------------------------------- 
 123 // "child_attached" of tool bar 
 124 //----------------------------------------------------------------------------- 
 126 static void gtk_toolbar_attached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 128     if (!win
->m_hasVMT
) return; 
 130     win
->m_toolBarDetached 
= FALSE
; 
 135 //----------------------------------------------------------------------------- 
 136 // "child_detached" of tool bar 
 137 //----------------------------------------------------------------------------- 
 139 static void gtk_toolbar_detached_callback( GtkWidget 
*widget
, GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 142         wxapp_install_idle_handler(); 
 144     if (!win
->m_hasVMT
) return; 
 146     win
->m_toolBarDetached 
= TRUE
; 
 149 #endif // wxUSE_TOOLBAR 
 151 //----------------------------------------------------------------------------- 
 153 //----------------------------------------------------------------------------- 
 155 static gint 
gtk_frame_configure_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventConfigure 
*WXUNUSED(event
), wxFrame 
*win 
) 
 158         wxapp_install_idle_handler(); 
 160     if (!win
->m_hasVMT
) return FALSE
; 
 164     gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y 
); 
 169     wxMoveEvent 
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() ); 
 170     mevent
.SetEventObject( win 
); 
 171     win
->GetEventHandler()->ProcessEvent( mevent 
); 
 176 //----------------------------------------------------------------------------- 
 177 // "realize" from m_widget 
 178 //----------------------------------------------------------------------------- 
 180 /* we cannot MWM hints and icons before the widget has been realized, 
 181    so we do this directly after realization */ 
 184 gtk_frame_realized_callback( GtkWidget 
*widget
, wxFrame 
*win 
) 
 187         wxapp_install_idle_handler(); 
 189     /* all this is for Motif Window Manager "hints" and is supposed to be 
 190        recognized by other WM as well. not tested. */ 
 191     long decor 
= (long) GDK_DECOR_BORDER
; 
 192     long func 
= (long) GDK_FUNC_MOVE
; 
 194     if ((win
->GetWindowStyle() & wxCAPTION
) != 0) 
 195         decor 
|= GDK_DECOR_TITLE
; 
 196     if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0) 
 198        decor 
|= GDK_DECOR_MENU
; 
 199        func 
|= GDK_FUNC_CLOSE
; 
 201     if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0) 
 203         func 
|= GDK_FUNC_MINIMIZE
; 
 204         decor 
|= GDK_DECOR_MINIMIZE
; 
 206     if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0) 
 208         func 
|= GDK_FUNC_MAXIMIZE
; 
 209         decor 
|= GDK_DECOR_MAXIMIZE
; 
 211     if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0) 
 213        func 
|= GDK_FUNC_RESIZE
; 
 214        decor 
|= GDK_DECOR_RESIZEH
; 
 218     gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
); 
 219     gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
); 
 221     /* GTK's shrinking/growing policy */ 
 222     if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0) 
 223         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1); 
 225         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1); 
 228     if (win
->m_icon 
!= wxNullIcon
) 
 230         wxIcon 
icon( win
->m_icon 
); 
 231         win
->m_icon 
= wxNullIcon
; 
 232         win
->SetIcon( icon 
); 
 235     /* we set the focus to the child that accepts the focus. this 
 236        doesn't really have to be done in "realize" but why not? */ 
 237     wxWindowList::Node 
*node 
= win
->GetChildren().GetFirst(); 
 240         wxWindow 
*child 
= node
->GetData(); 
 241         if (child
->AcceptsFocus()) 
 247         node 
= node
->GetNext(); 
 253 //----------------------------------------------------------------------------- 
 254 // InsertChild for wxFrame 
 255 //----------------------------------------------------------------------------- 
 257 /* Callback for wxFrame. This very strange beast has to be used because 
 258  * C++ has no virtual methods in a constructor. We have to emulate a 
 259  * virtual function here as wxWindows requires different ways to insert 
 260  * a child in container classes. */ 
 262 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child 
) 
 264     if (!parent
->m_insertInClientArea
) 
 266         /* these are outside the client area */ 
 267         wxFrame
* frame 
= (wxFrame
*) parent
; 
 268         gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
), 
 269                          GTK_WIDGET(child
->m_widget
), 
 276         /* we connect to these events for recalculating the client area 
 277            space when the toolbar is floating */ 
 278         if (wxIS_KIND_OF(child
,wxToolBar
)) 
 280             wxToolBar 
*toolBar 
= (wxToolBar
*) child
; 
 281             if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
) 
 283                 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached", 
 284                     GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent 
); 
 286                 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached", 
 287                     GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent 
); 
 290 #endif // wxUSE_TOOLBAR 
 294         /* these are inside the client area */ 
 295         gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
), 
 296                          GTK_WIDGET(child
->m_widget
), 
 303     /* resize on OnInternalIdle */ 
 304     parent
->UpdateSize(); 
 307 //----------------------------------------------------------------------------- 
 309 //----------------------------------------------------------------------------- 
 311 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
) 
 312     EVT_SIZE(wxFrame::OnSize
) 
 313     EVT_CLOSE(wxFrame::OnCloseWindow
) 
 314     EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
) 
 317 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
) 
 321     m_frameMenuBar 
= (wxMenuBar 
*) NULL
; 
 323     m_frameStatusBar 
= (wxStatusBar 
*) NULL
; 
 324 #endif // wxUSE_STATUSBAR 
 326     m_frameToolBar 
= (wxToolBar 
*) NULL
; 
 327 #endif // wxUSE_TOOLBAR 
 331     m_mainWidget 
= (GtkWidget
*) NULL
; 
 332     m_menuBarDetached 
= FALSE
; 
 333     m_toolBarDetached 
= FALSE
; 
 334     m_insertInClientArea 
= TRUE
; 
 337 wxFrame::wxFrame( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
 338       const wxPoint 
&pos
, const wxSize 
&size
, 
 339       long style
, const wxString 
&name 
) 
 343     Create( parent
, id
, title
, pos
, size
, style
, name 
); 
 346 bool wxFrame::Create( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
 347       const wxPoint 
&pos
, const wxSize 
&size
, 
 348       long style
, const wxString 
&name 
) 
 350     wxTopLevelWindows
.Append( this ); 
 352     m_needParent 
= FALSE
; 
 354     PreCreation( parent
, id
, pos
, size
, style
, name 
); 
 358     m_insertCallback 
= (wxInsertChildFunction
) wxInsertChildInFrame
; 
 360     GtkWindowType win_type 
= GTK_WINDOW_TOPLEVEL
; 
 361     if (style 
& wxSIMPLE_BORDER
) win_type 
= GTK_WINDOW_POPUP
; 
 363     m_widget 
= gtk_window_new( win_type 
); 
 366         gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() ); 
 369     debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name 
); 
 372     gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() ); 
 373     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
 375     gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event", 
 376         GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this ); 
 378     /* m_mainWidget holds the toolbar, the menubar and the client area */ 
 379     m_mainWidget 
= gtk_myfixed_new(); 
 380     gtk_widget_show( m_mainWidget 
); 
 381     GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS 
); 
 382     gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget 
); 
 385     debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name 
); 
 388     /* m_wxwindow only represents the client area without toolbar and menubar */ 
 389     m_wxwindow 
= gtk_myfixed_new(); 
 390     gtk_widget_show( m_wxwindow 
); 
 391     gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow 
); 
 394     debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name 
); 
 397     /* we donm't allow the frame to get the focus as otherwise 
 398        the frame will grabit at arbitrary fcous changes. */ 
 399     GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
 401     if (m_parent
) m_parent
->AddChild( this ); 
 405     /*  we cannot set MWM hints and icons before the widget has 
 406         been realized, so we do this directly after realization */ 
 407     gtk_signal_connect( GTK_OBJECT(m_widget
), "realize", 
 408                         GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this ); 
 410     /* the user resized the frame by dragging etc. */ 
 411     gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate", 
 412         GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this ); 
 414     /* the only way to get the window size is to connect to this event */ 
 415     gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event", 
 416         GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this ); 
 423     m_isBeingDeleted 
= TRUE
; 
 425     if (m_frameMenuBar
) delete m_frameMenuBar
; 
 426     m_frameMenuBar 
= (wxMenuBar 
*) NULL
; 
 429     if (m_frameStatusBar
) delete m_frameStatusBar
; 
 430     m_frameStatusBar 
= (wxStatusBar 
*) NULL
; 
 431 #endif // wxUSE_STATUSBAR 
 434     if (m_frameToolBar
) delete m_frameToolBar
; 
 435     m_frameToolBar 
= (wxToolBar 
*) NULL
; 
 436 #endif // wxUSE_TOOLBAR 
 438     wxTopLevelWindows
.DeleteObject( this ); 
 440     if (wxTheApp
->GetTopWindow() == this) 
 441         wxTheApp
->SetTopWindow( (wxWindow
*) NULL 
); 
 443     if (wxTopLevelWindows
.Number() == 0) 
 444         wxTheApp
->ExitMainLoop(); 
 447 bool wxFrame::Show( bool show 
) 
 449     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 451     if (show 
&& !m_sizeSet
) 
 453         /* by calling GtkOnSize here, we don't have to call 
 454            either after showing the frame, which would entail 
 455            much ugly flicker or from within the size_allocate 
 456            handler, because GTK 1.1.X forbids that. */ 
 458         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 461     return wxWindow::Show( show 
); 
 464 bool wxFrame::Destroy() 
 466     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 468     if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this); 
 473 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
 475     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 477     /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */ 
 478     wxASSERT_MSG( (m_wxwindow 
!= NULL
), _T("invalid frame") ); 
 480     /* avoid recursions */ 
 481     if (m_resizing
) return; 
 486     int old_width 
= m_width
; 
 487     int old_height 
= m_height
; 
 489     if ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0) 
 491         if (x 
!= -1) m_x 
= x
; 
 492         if (y 
!= -1) m_y 
= y
; 
 493         if (width 
!= -1) m_width 
= width
; 
 494         if (height 
!= -1) m_height 
= height
; 
 504     if ((sizeFlags 
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
) 
 506         if (width 
== -1) m_width 
= 80; 
 509     if ((sizeFlags 
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
) 
 511        if (height 
== -1) m_height 
= 26; 
 514     if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
 515     if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
 516     if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
 517     if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
 519     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 521         if ((m_x 
!= old_x
) || (m_y 
!= old_y
)) 
 523             gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 527     if ((m_width 
!= old_width
) || (m_height 
!= old_height
)) 
 529         /* we set the size in GtkOnSize, i.e. mostly the actual resizing is 
 530            done either directly before the frame is shown or in idle time 
 531            so that different calls to SetSize() don't lead to flicker. */ 
 538 void wxFrame::Centre( int direction 
) 
 540     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 545     if ((direction 
& wxHORIZONTAL
) == wxHORIZONTAL
) x 
= (gdk_screen_width () - m_width
) / 2; 
 546     if ((direction 
& wxVERTICAL
) == wxVERTICAL
) y 
= (gdk_screen_height () - m_height
) / 2; 
 551 void wxFrame::DoGetClientSize( int *width
, int *height 
) const 
 553     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 555     wxWindow::DoGetClientSize( width
, height 
); 
 561             if (!m_menuBarDetached
) 
 562                 (*height
) -= wxMENU_HEIGHT
; 
 564                 (*height
) -= wxPLACE_HOLDER
; 
 569         if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
; 
 576             if (!m_toolBarDetached
) 
 579                 m_frameToolBar
->GetSize( (int *) NULL
, &y 
); 
 583                 (*height
) -= wxPLACE_HOLDER
; 
 588         (*height
) -= m_miniEdge
*2 + m_miniTitle
; 
 592         (*width
) -= m_miniEdge
*2; 
 596 void wxFrame::DoSetClientSize( int width
, int height 
) 
 598     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 603             if (!m_menuBarDetached
) 
 604                 height 
+= wxMENU_HEIGHT
; 
 606                 height 
+= wxPLACE_HOLDER
; 
 611         if (m_frameStatusBar
) height 
+= wxSTATUS_HEIGHT
; 
 618             if (!m_toolBarDetached
) 
 621                 m_frameToolBar
->GetSize( (int *) NULL
, &y 
); 
 625                 height 
+= wxPLACE_HOLDER
; 
 629     wxWindow::DoSetClientSize( width 
+ m_miniEdge
*2, height  
+ m_miniEdge
*2 + m_miniTitle 
); 
 632 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height 
) 
 634     // due to a bug in gtk, x,y are always 0 
 638     /* avoid recursions */ 
 639     if (m_resizing
) return; 
 642     /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */ 
 643     wxASSERT_MSG( (m_wxwindow 
!= NULL
), _T("invalid frame") ); 
 648     /* space occupied by m_frameToolBar and m_frameMenuBar */ 
 649     int client_area_y_offset 
= 0; 
 651     /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses 
 652        wxWindow::Create to create it's GTK equivalent. m_mainWidget is only 
 653        set in wxFrame::Create so it is used to check what kind of frame we 
 654        have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we 
 655        skip the part which handles m_frameMenuBar, m_frameToolBar and (most 
 656        importantly) m_mainWidget */ 
 660         /* check if size is in legal range */ 
 661         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
 662         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
 663         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
 664         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
 666         /* I revert back to wxGTK's original behaviour. m_mainWidget holds the 
 667          * menubar, the toolbar and the client area, which is represented by 
 669          * this hurts in the eye, but I don't want to call SetSize() 
 670          * because I don't want to call any non-native functions here. */ 
 675             int yy 
= m_miniEdge 
+ m_miniTitle
; 
 676             int ww 
= m_width  
- 2*m_miniEdge
; 
 677             int hh 
= wxMENU_HEIGHT
; 
 678             if (m_menuBarDetached
) hh 
= wxPLACE_HOLDER
; 
 679             m_frameMenuBar
->m_x 
= xx
; 
 680             m_frameMenuBar
->m_y 
= yy
; 
 681             m_frameMenuBar
->m_width 
= ww
; 
 682             m_frameMenuBar
->m_height 
= hh
; 
 683             gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
), 
 684                                   m_frameMenuBar
->m_widget
, 
 686             client_area_y_offset 
+= hh
; 
 693             int yy 
= m_miniEdge 
+ m_miniTitle
; 
 696                 if (!m_menuBarDetached
) 
 699                     yy 
+= wxPLACE_HOLDER
; 
 701             int ww 
= m_width 
- 2*m_miniEdge
; 
 702             int hh 
= m_frameToolBar
->m_height
; 
 703             if (m_toolBarDetached
) hh 
= wxPLACE_HOLDER
; 
 704             m_frameToolBar
->m_x 
= xx
; 
 705             m_frameToolBar
->m_y 
= yy
; 
 706             /* m_frameToolBar->m_height = hh;   don't change the toolbar's height */ 
 707             m_frameToolBar
->m_width 
= ww
; 
 708             gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
), 
 709                                   m_frameToolBar
->m_widget
, 
 711             client_area_y_offset 
+= hh
; 
 715         int client_x 
= m_miniEdge
; 
 716         int client_y 
= client_area_y_offset 
+ m_miniEdge 
+ m_miniTitle
; 
 717         int client_w 
= m_width 
- 2*m_miniEdge
; 
 718         int client_h 
= m_height 
- client_area_y_offset
- 2*m_miniEdge 
- m_miniTitle
; 
 719         gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
), 
 721                               client_x
, client_y
, client_w
, client_h 
); 
 725         /* if there is no m_mainWidget between m_widget and m_wxwindow there 
 726            is no need to set the size or position of m_wxwindow. */ 
 730     if (m_frameStatusBar
) 
 732         int xx 
= 0 + m_miniEdge
; 
 733         int yy 
= m_height 
- wxSTATUS_HEIGHT 
- m_miniEdge 
- client_area_y_offset
; 
 734         int ww 
= m_width 
- 2*m_miniEdge
; 
 735         int hh 
= wxSTATUS_HEIGHT
; 
 736         m_frameStatusBar
->m_x 
= xx
; 
 737         m_frameStatusBar
->m_y 
= yy
; 
 738         m_frameStatusBar
->m_width 
= ww
; 
 739         m_frameStatusBar
->m_height 
= hh
; 
 740         gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
), 
 741                               m_frameStatusBar
->m_widget
, 
 746     /* we actually set the size of a frame here and no-where else */ 
 747     gtk_widget_set_usize( m_widget
, m_width
, m_height 
); 
 751     /* send size event to frame */ 
 752     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
 753     event
.SetEventObject( this ); 
 754     GetEventHandler()->ProcessEvent( event 
); 
 756     /* send size event to status bar */ 
 757     if (m_frameStatusBar
) 
 759         wxSizeEvent 
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() ); 
 760         event2
.SetEventObject( m_frameStatusBar 
); 
 761         m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2 
); 
 767 void wxFrame::MakeModal( bool modal 
) 
 770         gtk_grab_add( m_widget 
); 
 772         gtk_grab_remove( m_widget 
); 
 775 void wxFrame::OnInternalIdle() 
 777     if (!m_sizeSet 
&& GTK_WIDGET_REALIZED(m_wxwindow
)) 
 778         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 782     if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle(); 
 784     if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle(); 
 787     if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle(); 
 791 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) ) 
 796 void wxFrame::OnSize( wxSizeEvent 
&WXUNUSED(event
) ) 
 798     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 800 #if wxUSE_CONSTRAINTS 
 806 #endif // wxUSE_CONSTRAINTS 
 808         /* do we have exactly one child? */ 
 809         wxWindow 
*child 
= (wxWindow 
*)NULL
; 
 810         for ( wxNode 
*node 
= GetChildren().First(); node
; node 
= node
->Next() ) 
 812             wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
 813             if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) ) 
 817                     /* it's the second one: do nothing */ 
 825         /* no children at all? */ 
 828             /* yes: set it's size to fill all the frame */ 
 829             int client_x
, client_y
; 
 830             DoGetClientSize( &client_x
, &client_y 
); 
 831             child
->SetSize( 1, 1, client_x
-2, client_y
-2 ); 
 836 void wxFrame::SetMenuBar( wxMenuBar 
*menuBar 
) 
 838     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 839     wxASSERT_MSG( (m_wxwindow 
!= NULL
), _T("invalid frame") ); 
 841     m_frameMenuBar 
= menuBar
; 
 845         m_frameMenuBar
->SetInvokingWindow( this ); 
 847         if (m_frameMenuBar
->GetParent() != this) 
 849             m_frameMenuBar
->SetParent(this); 
 850             gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
), 
 851                 m_frameMenuBar
->m_widget
, 
 854                 m_frameMenuBar
->m_width
, 
 855                 m_frameMenuBar
->m_height 
); 
 857             if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
) 
 859                 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached", 
 860                     GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this ); 
 862                 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached", 
 863                     GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this ); 
 866             m_frameMenuBar
->Show( TRUE 
); 
 870     /* resize window in OnInternalIdle */ 
 874 wxMenuBar 
*wxFrame::GetMenuBar() const 
 876     return m_frameMenuBar
; 
 879 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
) 
 884         // if no help string found, we will clear the status bar text 
 887         int menuId 
= event
.GetMenuId(); 
 890             wxMenuBar 
*menuBar 
= GetMenuBar(); 
 893                 helpString 
= menuBar
->GetHelpString(menuId
); 
 897         SetStatusText(helpString
); 
 899 #endif // wxUSE_STATUSBAR 
 903 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name 
) 
 905     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 907     wxCHECK_MSG( m_frameToolBar 
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") ); 
 909     m_insertInClientArea 
= FALSE
; 
 911     m_frameToolBar 
= OnCreateToolBar( style
, id
, name 
); 
 913     if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar 
); 
 915     m_insertInClientArea 
= TRUE
; 
 919     return m_frameToolBar
; 
 922 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name 
) 
 924     return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name 
); 
 927 wxToolBar 
*wxFrame::GetToolBar() const 
 929     return m_frameToolBar
; 
 931 #endif // wxUSE_TOOLBAR 
 934 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name 
) 
 936     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 938     wxCHECK_MSG( m_frameStatusBar 
== NULL
, FALSE
, _T("recreating status bar in wxFrame") ); 
 940     m_frameStatusBar 
= OnCreateStatusBar( number
, style
, id
, name 
); 
 944     return m_frameStatusBar
; 
 947 wxStatusBar 
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name 
) 
 949     wxStatusBar 
*statusBar 
= (wxStatusBar 
*) NULL
; 
 951     statusBar 
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
); 
 953     // Set the height according to the font and the border size 
 954     wxClientDC 
dc(statusBar
); 
 955     dc
.SetFont( statusBar
->GetFont() ); 
 958     dc
.GetTextExtent( "X", &x
, &y 
); 
 960     int height 
= (int)( (y  
* 1.1) + 2* statusBar
->GetBorderY()); 
 962     statusBar
->SetSize( -1, -1, 100, height 
); 
 964     statusBar
->SetFieldsCount( number 
); 
 968 wxStatusBar 
*wxFrame::GetStatusBar() const 
 970     return m_frameStatusBar
; 
 973 void wxFrame::SetStatusText(const wxString
& text
, int number
) 
 975     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 977     wxCHECK_RET( m_frameStatusBar 
!= NULL
, _T("no statusbar to set text for") ); 
 979     m_frameStatusBar
->SetStatusText(text
, number
); 
 982 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] ) 
 984     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 986     wxCHECK_RET( m_frameStatusBar 
!= NULL
, _T("no statusbar to set widths for") ); 
 988     m_frameStatusBar
->SetStatusWidths(n
, widths_field
); 
 990 #endif // wxUSE_STATUSBAR 
 992 void wxFrame::Command( int id 
) 
 994     wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
); 
 995     commandEvent
.SetInt( id 
); 
 996     commandEvent
.SetEventObject( this ); 
 998     wxMenuBar 
*bar 
= GetMenuBar(); 
1001     wxMenuItem 
*item 
= bar
->FindItemForId(id
) ; 
1002     if (item 
&& item
->IsCheckable()) 
1004         bar
->Check(id
,!bar
->Checked(id
)) ; 
1007     wxEvtHandler
* evtHandler 
= GetEventHandler(); 
1009     evtHandler
->ProcessEvent(commandEvent
); 
1012 void wxFrame::SetTitle( const wxString 
&title 
) 
1014     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
1017     if (m_title
.IsNull()) m_title 
= _T(""); 
1018     gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() ); 
1021 void wxFrame::SetIcon( const wxIcon 
&icon 
) 
1023     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
1026     if (!icon
.Ok()) return; 
1028     if (!m_widget
->window
) return; 
1030     wxMask 
*mask 
= icon
.GetMask(); 
1031     GdkBitmap 
*bm 
= (GdkBitmap 
*) NULL
; 
1032     if (mask
) bm 
= mask
->GetBitmap(); 
1034     gdk_window_set_icon( m_widget
->window
, (GdkWindow 
*) NULL
, icon
.GetPixmap(), bm 
);