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" 
  19 #include "wx/toolbar.h" 
  20 #include "wx/statusbr.h" 
  21 #include "wx/dcclient.h" 
  26 #include "wx/gtk/win_gtk.h" 
  27 #include "gdk/gdkkeysyms.h" 
  29 //----------------------------------------------------------------------------- 
  31 //----------------------------------------------------------------------------- 
  33 const int wxMENU_HEIGHT    
= 27; 
  34 const int wxSTATUS_HEIGHT  
= 25; 
  35 const int wxPLACE_HOLDER   
= 0; 
  37 //----------------------------------------------------------------------------- 
  39 //----------------------------------------------------------------------------- 
  41 extern void wxapp_install_idle_handler(); 
  44 //----------------------------------------------------------------------------- 
  46 //----------------------------------------------------------------------------- 
  48 extern wxList wxPendingDelete
; 
  50 //----------------------------------------------------------------------------- 
  52 //----------------------------------------------------------------------------- 
  56 extern void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar 
*window 
); 
  60 //----------------------------------------------------------------------------- 
  62 //----------------------------------------------------------------------------- 
  64 static void gtk_frame_size_callback( GtkWidget 
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame 
*win 
) 
  67         wxapp_install_idle_handler(); 
  69     if (!win
->m_hasVMT
) return; 
  71     if ((win
->m_width 
!= alloc
->width
) || (win
->m_height 
!= alloc
->height
)) 
  73         win
->m_width 
= alloc
->width
; 
  74         win
->m_height 
= alloc
->height
; 
  79 //----------------------------------------------------------------------------- 
  81 //----------------------------------------------------------------------------- 
  83 static gint 
gtk_frame_delete_callback( GtkWidget 
*WXUNUSED(widget
), GdkEvent 
*WXUNUSED(event
), wxFrame 
*win 
) 
  86         wxapp_install_idle_handler(); 
  93 //----------------------------------------------------------------------------- 
  94 // "child_attached" of menu bar 
  95 //----------------------------------------------------------------------------- 
  97 static void gtk_menu_attached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
  99     if (!win
->m_hasVMT
) return; 
 101     win
->m_menuBarDetached 
= FALSE
; 
 105 //----------------------------------------------------------------------------- 
 106 // "child_detached" of menu bar 
 107 //----------------------------------------------------------------------------- 
 109 static void gtk_menu_detached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 111     if (!win
->m_hasVMT
) return; 
 113     win
->m_menuBarDetached 
= TRUE
; 
 117 //----------------------------------------------------------------------------- 
 118 // "child_attached" of tool bar 
 119 //----------------------------------------------------------------------------- 
 121 static void gtk_toolbar_attached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 123     if (!win
->m_hasVMT
) return; 
 125     win
->m_toolBarDetached 
= FALSE
; 
 130 //----------------------------------------------------------------------------- 
 131 // "child_detached" of tool bar 
 132 //----------------------------------------------------------------------------- 
 134 static void gtk_toolbar_detached_callback( GtkWidget 
*widget
, GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 137         wxapp_install_idle_handler(); 
 139     if (!win
->m_hasVMT
) return; 
 141     win
->m_toolBarDetached 
= TRUE
; 
 145 //----------------------------------------------------------------------------- 
 147 //----------------------------------------------------------------------------- 
 149 static gint 
gtk_frame_configure_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventConfigure 
*event
, wxFrame 
*win 
) 
 152         wxapp_install_idle_handler(); 
 154     if (!win
->m_hasVMT
) return FALSE
; 
 159     wxMoveEvent 
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() ); 
 160     mevent
.SetEventObject( win 
); 
 161     win
->GetEventHandler()->ProcessEvent( mevent 
); 
 166 //----------------------------------------------------------------------------- 
 167 // "realize" from m_widget 
 168 //----------------------------------------------------------------------------- 
 170 /* we cannot MWM hints and icons before the widget has been realized,  
 171    so we do this directly after realization */ 
 174 gtk_frame_realized_callback( GtkWidget 
*widget
, wxFrame 
*win 
) 
 177         wxapp_install_idle_handler(); 
 179     /* all this is for Motif Window Manager "hints" and is supposed to be 
 180        recognized by other WM as well. not tested. */ 
 181     long decor 
= (long) GDK_DECOR_BORDER
; 
 182     long func 
= (long) GDK_FUNC_MOVE
; 
 184     if ((win
->GetWindowStyle() & wxCAPTION
) != 0) 
 185         decor 
|= GDK_DECOR_TITLE
; 
 186     if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0) 
 188        decor 
|= GDK_DECOR_MENU
; 
 189        func 
|= GDK_FUNC_CLOSE
; 
 191     if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0) 
 193         func 
|= GDK_FUNC_MINIMIZE
; 
 194         decor 
|= GDK_DECOR_MINIMIZE
; 
 196     if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0) 
 198         func 
|= GDK_FUNC_MAXIMIZE
; 
 199         decor 
|= GDK_DECOR_MAXIMIZE
; 
 201     if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0) 
 203        func 
|= GDK_FUNC_RESIZE
; 
 204        decor 
|= GDK_DECOR_RESIZEH
; 
 208     gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
); 
 209     gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
); 
 211     /* GTK's shrinking/growing policy */ 
 212     if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0) 
 213         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1); 
 215         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1); 
 218     if (win
->m_icon 
!= wxNullIcon
) 
 220         wxIcon 
icon( win
->m_icon 
); 
 221         win
->m_icon 
= wxNullIcon
; 
 222         win
->SetIcon( icon 
); 
 225     /* we set the focus to the child that accepts the focus. this 
 226        doesn't really have to be done in "realize" but why not? */ 
 227     wxWindowList::Node 
*node 
= win
->GetChildren().GetFirst(); 
 230         wxWindow 
*child 
= node
->GetData(); 
 231         if (child
->AcceptsFocus()) 
 237         node 
= node
->GetNext(); 
 243 //----------------------------------------------------------------------------- 
 244 // InsertChild for wxFrame 
 245 //----------------------------------------------------------------------------- 
 247 /* Callback for wxFrame. This very strange beast has to be used because 
 248  * C++ has no virtual methods in a constructor. We have to emulate a 
 249  * virtual function here as wxWindows requires different ways to insert 
 250  * a child in container classes. */ 
 252 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child 
) 
 254     if (!parent
->m_insertInClientArea
) 
 256         /* these are outside the client area */ 
 257         wxFrame
* frame 
= (wxFrame
*) parent
; 
 258         gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
), 
 259                          GTK_WIDGET(child
->m_widget
), 
 265         /* we connect to these events for recalculating the client area 
 266            space when the toolbar is floating */ 
 267         if (wxIS_KIND_OF(child
,wxToolBar
)) 
 269             wxToolBar 
*toolBar 
= (wxToolBar
*) child
; 
 270             if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
) 
 272                 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached", 
 273                     GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent 
); 
 275                 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached", 
 276                     GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent 
); 
 282         /* these are inside the client area */ 
 283         gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
), 
 284                          GTK_WIDGET(child
->m_widget
), 
 291     /* resize on OnInternalIdle */ 
 292     parent
->UpdateSize(); 
 295 //----------------------------------------------------------------------------- 
 297 //----------------------------------------------------------------------------- 
 299 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
) 
 300     EVT_SIZE(wxFrame::OnSize
) 
 301     EVT_CLOSE(wxFrame::OnCloseWindow
) 
 302     EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
) 
 305 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
) 
 309     m_frameMenuBar 
= (wxMenuBar 
*) NULL
; 
 310     m_frameStatusBar 
= (wxStatusBar 
*) NULL
; 
 311     m_frameToolBar 
= (wxToolBar 
*) NULL
; 
 315     m_mainWidget 
= (GtkWidget
*) NULL
; 
 316     m_menuBarDetached 
= FALSE
; 
 317     m_toolBarDetached 
= FALSE
; 
 318     m_insertCallback 
= (wxInsertChildFunction
) NULL
; 
 319     m_insertInClientArea 
= TRUE
; 
 322 wxFrame::wxFrame( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
 323       const wxPoint 
&pos
, const wxSize 
&size
, 
 324       long style
, const wxString 
&name 
) 
 326     m_frameMenuBar 
= (wxMenuBar 
*) NULL
; 
 327     m_frameStatusBar 
= (wxStatusBar 
*) NULL
; 
 328     m_frameToolBar 
= (wxToolBar 
*) NULL
; 
 332     m_mainWidget 
= (GtkWidget
*) NULL
; 
 333     m_menuBarDetached 
= FALSE
; 
 334     m_toolBarDetached 
= FALSE
; 
 335     m_insertCallback 
= (wxInsertChildFunction
) NULL
; 
 336     m_insertInClientArea 
= TRUE
; 
 337     Create( parent
, id
, title
, pos
, size
, style
, name 
); 
 340 bool wxFrame::Create( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
 341       const wxPoint 
&pos
, const wxSize 
&size
, 
 342       long style
, const wxString 
&name 
) 
 344     wxTopLevelWindows
.Append( this ); 
 346     m_needParent 
= FALSE
; 
 348     PreCreation( parent
, id
, pos
, size
, style
, name 
); 
 352     m_insertCallback 
= (wxInsertChildFunction
) wxInsertChildInFrame
; 
 354     GtkWindowType win_type 
= GTK_WINDOW_TOPLEVEL
; 
 355     if (style 
& wxSIMPLE_BORDER
) win_type 
= GTK_WINDOW_POPUP
; 
 357     m_widget 
= gtk_window_new( win_type 
); 
 360         gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() ); 
 363     debug_focus_in( m_widget
, _T("wxFrame::m_widget"), name 
); 
 366     gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() ); 
 367     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
 369     gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event", 
 370         GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this ); 
 372     /* m_mainWidget holds the toolbar, the menubar and the client area */ 
 373     m_mainWidget 
= gtk_myfixed_new(); 
 374     gtk_widget_show( m_mainWidget 
); 
 375     GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS 
); 
 376     gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget 
); 
 379     debug_focus_in( m_mainWidget
, _T("wxFrame::m_mainWidget"), name 
); 
 382     /* m_wxwindow only represents the client area without toolbar and menubar */ 
 383     m_wxwindow 
= gtk_myfixed_new(); 
 384     gtk_widget_show( m_wxwindow 
); 
 385     gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow 
); 
 388     debug_focus_in( m_wxwindow
, _T("wxFrame::m_wxwindow"), name 
); 
 391     /* we donm't allow the frame to get the focus as otherwise 
 392        the frame will grabit at arbitrary fcous changes. */ 
 393     GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
 395     if (m_parent
) m_parent
->AddChild( this ); 
 399     /*  we cannot set MWM hints and icons before the widget has 
 400         been realized, so we do this directly after realization */ 
 401     gtk_signal_connect( GTK_OBJECT(m_widget
), "realize", 
 402                         GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this ); 
 404     /* the user resized the frame by dragging etc. */ 
 405     gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate", 
 406         GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this ); 
 408     /* the only way to get the window size is to connect to this event */ 
 409     gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event", 
 410         GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this ); 
 417     m_isBeingDeleted 
= TRUE
; 
 419     if (m_frameMenuBar
) delete m_frameMenuBar
; 
 420     m_frameMenuBar 
= (wxMenuBar 
*) NULL
; 
 422     if (m_frameStatusBar
) delete m_frameStatusBar
; 
 423     m_frameStatusBar 
= (wxStatusBar 
*) NULL
; 
 425     if (m_frameToolBar
) delete m_frameToolBar
; 
 426     m_frameToolBar 
= (wxToolBar 
*) NULL
; 
 428     wxTopLevelWindows
.DeleteObject( this ); 
 430     if (wxTheApp
->GetTopWindow() == this) 
 431         wxTheApp
->SetTopWindow( (wxWindow
*) NULL 
); 
 433     if (wxTopLevelWindows
.Number() == 0) 
 434         wxTheApp
->ExitMainLoop(); 
 437 bool wxFrame::Show( bool show 
) 
 439     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 441     if (show 
&& !m_sizeSet
) 
 443         /* by calling GtkOnSize here, we don't have to call 
 444            either after showing the frame, which would entail 
 445            much ugly flicker or from within the size_allocate 
 446            handler, because GTK 1.1.X forbids that. */ 
 448         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 451     return wxWindow::Show( show 
); 
 454 bool wxFrame::Destroy() 
 456     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 458     if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this); 
 463 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
 465     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 467     /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */ 
 468     wxASSERT_MSG( (m_wxwindow 
!= NULL
), _T("invalid frame") ); 
 470     /* avoid recursions */ 
 471     if (m_resizing
) return;  
 476     int old_width 
= m_width
; 
 477     int old_height 
= m_height
; 
 479     if ((sizeFlags 
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
) 
 481         if (x 
!= -1) m_x 
= x
; 
 482         if (y 
!= -1) m_y 
= y
; 
 483         if (width 
!= -1) m_width 
= width
; 
 484         if (height 
!= -1) m_height 
= height
; 
 494     if ((sizeFlags 
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
) 
 496         if (width 
== -1) m_width 
= 80; 
 499     if ((sizeFlags 
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
) 
 501        if (height 
== -1) m_height 
= 26; 
 504     if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
 505     if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
 506     if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
 507     if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
 509     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 511         if ((m_x 
!= old_x
) || (m_y 
!= old_y
)) 
 513             gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 517     if ((m_width 
!= old_width
) || (m_height 
!= old_height
)) 
 519         /* we set the size in GtkOnSize, i.e. mostly the actual resizing is 
 520            done either directly before the frame is shown or in idle time 
 521            so that different calls to SetSize() don't lead to flicker. */ 
 528 void wxFrame::Centre( int direction 
) 
 530     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 535     if ((direction 
& wxHORIZONTAL
) == wxHORIZONTAL
) x 
= (gdk_screen_width () - m_width
) / 2; 
 536     if ((direction 
& wxVERTICAL
) == wxVERTICAL
) y 
= (gdk_screen_height () - m_height
) / 2; 
 541 void wxFrame::DoGetClientSize( int *width
, int *height 
) const 
 543     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 545     wxWindow::DoGetClientSize( width
, height 
); 
 551             if (!m_menuBarDetached
)  
 552                 (*height
) -= wxMENU_HEIGHT
; 
 554                 (*height
) -= wxPLACE_HOLDER
; 
 558         if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
; 
 563             if (!m_toolBarDetached
) 
 566                 m_frameToolBar
->GetSize( (int *) NULL
, &y 
); 
 570                 (*height
) -= wxPLACE_HOLDER
; 
 574         (*height
) -= m_miniEdge
*2 + m_miniTitle
; 
 578         (*width
) -= m_miniEdge
*2; 
 582 void wxFrame::DoSetClientSize( int width
, int height 
) 
 584     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 589             if (!m_menuBarDetached
)  
 590                 height 
+= wxMENU_HEIGHT
; 
 592                 height 
+= wxPLACE_HOLDER
; 
 596         if (m_frameStatusBar
) height 
+= wxSTATUS_HEIGHT
; 
 601             if (!m_toolBarDetached
) 
 604                 m_frameToolBar
->GetSize( (int *) NULL
, &y 
); 
 608                 height 
+= wxPLACE_HOLDER
; 
 611     wxWindow::DoSetClientSize( width 
+ m_miniEdge
*2, height  
+ m_miniEdge
*2 + m_miniTitle 
); 
 614 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height 
) 
 616     // due to a bug in gtk, x,y are always 0 
 620     /* avoid recursions */ 
 621     if (m_resizing
) return; 
 624     /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */ 
 625     wxASSERT_MSG( (m_wxwindow 
!= NULL
), _T("invalid frame") ); 
 630     /* space occupied by m_frameToolBar and m_frameMenuBar */ 
 631     int client_area_y_offset 
= 0;  
 633     /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses 
 634        wxWindow::Create to create it's GTK equivalent. m_mainWidget is only 
 635        set in wxFrame::Create so it is used to check what kind of frame we 
 636        have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we 
 637        skip the part which handles m_frameMenuBar, m_frameToolBar and (most 
 638        importantly) m_mainWidget */ 
 642         /* check if size is in legal range */ 
 643         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
 644         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
 645         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
 646         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
 648         /* I revert back to wxGTK's original behaviour. m_mainWidget holds the 
 649          * menubar, the toolbar and the client area, which is represented by 
 651          * this hurts in the eye, but I don't want to call SetSize() 
 652          * because I don't want to call any non-native functions here. */ 
 657             int yy 
= m_miniEdge 
+ m_miniTitle
; 
 658             int ww 
= m_width  
- 2*m_miniEdge
; 
 659             int hh 
= wxMENU_HEIGHT
; 
 660             if (m_menuBarDetached
) hh 
= wxPLACE_HOLDER
; 
 661             m_frameMenuBar
->m_x 
= xx
; 
 662             m_frameMenuBar
->m_y 
= yy
; 
 663             m_frameMenuBar
->m_width 
= ww
; 
 664             m_frameMenuBar
->m_height 
= hh
; 
 665             gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),  
 666                                   m_frameMenuBar
->m_widget
,  
 668             client_area_y_offset 
+= hh
; 
 674             int yy 
= m_miniEdge 
+ m_miniTitle
; 
 677                 if (!m_menuBarDetached
)  
 680                     yy 
+= wxPLACE_HOLDER
; 
 682             int ww 
= m_width 
- 2*m_miniEdge
; 
 683             int hh 
= m_frameToolBar
->m_height
; 
 684             if (m_toolBarDetached
) hh 
= wxPLACE_HOLDER
;  
 685             m_frameToolBar
->m_x 
= xx
; 
 686             m_frameToolBar
->m_y 
= yy
; 
 687             /* m_frameToolBar->m_height = hh;   don't change the toolbar's height */ 
 688             m_frameToolBar
->m_width 
= ww
; 
 689             gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),  
 690                                   m_frameToolBar
->m_widget
,  
 692             client_area_y_offset 
+= hh
; 
 695         int client_x 
= m_miniEdge
; 
 696         int client_y 
= client_area_y_offset 
+ m_miniEdge 
+ m_miniTitle
; 
 697         int client_w 
= m_width 
- 2*m_miniEdge
; 
 698         int client_h 
= m_height 
- client_area_y_offset
- 2*m_miniEdge 
- m_miniTitle
; 
 699         gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
),  
 701                               client_x
, client_y
, client_w
, client_h 
); 
 705         /* if there is no m_mainWidget between m_widget and m_wxwindow there 
 706            is no need to set the size or position of m_wxwindow. */ 
 709     if (m_frameStatusBar
) 
 711         int xx 
= 0 + m_miniEdge
; 
 712         int yy 
= m_height 
- wxSTATUS_HEIGHT 
- m_miniEdge 
- client_area_y_offset
; 
 713         int ww 
= m_width 
- 2*m_miniEdge
; 
 714         int hh 
= wxSTATUS_HEIGHT
; 
 715         m_frameStatusBar
->m_x 
= xx
; 
 716         m_frameStatusBar
->m_y 
= yy
; 
 717         m_frameStatusBar
->m_width 
= ww
; 
 718         m_frameStatusBar
->m_height 
= hh
; 
 719         gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
),  
 720                               m_frameStatusBar
->m_widget
,  
 724     /* we actually set the size of a frame here and no-where else */ 
 725     gtk_widget_set_usize( m_widget
, m_width
, m_height 
); 
 729     /* send size event to frame */ 
 730     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
 731     event
.SetEventObject( this ); 
 732     GetEventHandler()->ProcessEvent( event 
); 
 734     /* send size event to status bar */ 
 735     if (m_frameStatusBar
) 
 737         wxSizeEvent 
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() ); 
 738         event2
.SetEventObject( m_frameStatusBar 
); 
 739         m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2 
); 
 745 void wxFrame::OnInternalIdle() 
 747     if (!m_sizeSet 
&& GTK_WIDGET_REALIZED(m_wxwindow
)) 
 748         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 752     if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle(); 
 753     if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle(); 
 754     if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle(); 
 757 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) ) 
 762 void wxFrame::OnSize( wxSizeEvent 
&WXUNUSED(event
) ) 
 764     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 772         /* do we have exactly one child? */ 
 773         wxWindow 
*child 
= (wxWindow 
*)NULL
; 
 774         for ( wxNode 
*node 
= GetChildren().First(); node
; node 
= node
->Next() ) 
 776             wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
 777             if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) ) 
 781                     /* it's the second one: do nothing */ 
 789         /* no children at all? */ 
 792             /* yes: set it's size to fill all the frame */ 
 793             int client_x
, client_y
; 
 794             DoGetClientSize( &client_x
, &client_y 
); 
 795             child
->SetSize( 1, 1, client_x
-2, client_y
-2 ); 
 800 static void SetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
 802     menu
->SetInvokingWindow( win 
); 
 804 #if (GTK_MINOR_VERSION > 0) 
 805     /* support for native hot keys  */ 
 806     gtk_accel_group_attach( menu
->m_accel
, GTK_OBJECT(win
->m_widget
)); 
 809     wxNode 
*node 
= menu
->GetItems().First(); 
 812         wxMenuItem 
*menuitem 
= (wxMenuItem
*)node
->Data(); 
 813         if (menuitem
->IsSubMenu()) 
 814             SetInvokingWindow( menuitem
->GetSubMenu(), win 
); 
 819 void wxFrame::SetMenuBar( wxMenuBar 
*menuBar 
) 
 821     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 822     wxASSERT_MSG( (m_wxwindow 
!= NULL
), _T("invalid frame") ); 
 824     m_frameMenuBar 
= menuBar
; 
 828 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0) 
 829         /* support for native key accelerators indicated by underscroes */ 
 830          gtk_accel_group_attach( m_frameMenuBar
->m_accel
, GTK_OBJECT(m_widget
)); 
 833         wxNode 
*node 
= m_frameMenuBar
->GetMenus().First(); 
 836             wxMenu 
*menu 
= (wxMenu
*)node
->Data(); 
 837             SetInvokingWindow( menu
, this ); 
 841         if (m_frameMenuBar
->GetParent() != this) 
 843             m_frameMenuBar
->SetParent(this); 
 844             gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
), 
 845                 m_frameMenuBar
->m_widget
,  
 848                 m_frameMenuBar
->m_width
, 
 849                 m_frameMenuBar
->m_height 
); 
 851             if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
) 
 853                 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached", 
 854                     GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this ); 
 856                 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached", 
 857                     GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this ); 
 862     /* resize window in OnInternalIdle */ 
 866 wxMenuBar 
*wxFrame::GetMenuBar() const 
 868     return m_frameMenuBar
; 
 871 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
) 
 875         // if no help string found, we will clear the status bar text 
 878         int menuId 
= event
.GetMenuId(); 
 881             wxMenuBar 
*menuBar 
= GetMenuBar(); 
 884                 helpString 
= menuBar
->GetHelpString(menuId
); 
 888         SetStatusText(helpString
); 
 892 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name 
) 
 894     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 896     wxCHECK_MSG( m_frameToolBar 
== NULL
, FALSE
, _T("recreating toolbar in wxFrame") ); 
 898     m_insertInClientArea 
= FALSE
; 
 900     m_frameToolBar 
= OnCreateToolBar( style
, id
, name 
); 
 902     if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar 
); 
 904     m_insertInClientArea 
= TRUE
; 
 908     return m_frameToolBar
; 
 911 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name 
) 
 913     return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name 
); 
 916 wxToolBar 
*wxFrame::GetToolBar() const 
 918     return m_frameToolBar
; 
 921 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name 
) 
 923     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 925     wxCHECK_MSG( m_frameStatusBar 
== NULL
, FALSE
, _T("recreating status bar in wxFrame") ); 
 927     m_frameStatusBar 
= OnCreateStatusBar( number
, style
, id
, name 
); 
 931     return m_frameStatusBar
; 
 934 wxStatusBar 
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name 
) 
 936     wxStatusBar 
*statusBar 
= (wxStatusBar 
*) NULL
; 
 938     statusBar 
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
); 
 940     // Set the height according to the font and the border size 
 941     wxClientDC 
dc(statusBar
); 
 942     dc
.SetFont( statusBar
->GetFont() ); 
 945     dc
.GetTextExtent( "X", &x
, &y 
); 
 947     int height 
= (int)( (y  
* 1.1) + 2* statusBar
->GetBorderY()); 
 949     statusBar
->SetSize( -1, -1, 100, height 
); 
 951     statusBar
->SetFieldsCount( number 
); 
 955 void wxFrame::Command( int id 
) 
 957     wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
); 
 958     commandEvent
.SetInt( id 
); 
 959     commandEvent
.SetEventObject( this ); 
 961     wxMenuBar 
*bar 
= GetMenuBar(); 
 964     wxMenuItem 
*item 
= bar
->FindItemForId(id
) ; 
 965     if (item 
&& item
->IsCheckable()) 
 967         bar
->Check(id
,!bar
->Checked(id
)) ; 
 970     wxEvtHandler
* evtHandler 
= GetEventHandler(); 
 972     evtHandler
->ProcessEvent(commandEvent
); 
 975 void wxFrame::SetStatusText(const wxString
& text
, int number
) 
 977     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 979     wxCHECK_RET( m_frameStatusBar 
!= NULL
, _T("no statusbar to set text for") ); 
 981     m_frameStatusBar
->SetStatusText(text
, number
); 
 984 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] ) 
 986     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
 988     wxCHECK_RET( m_frameStatusBar 
!= NULL
, _T("no statusbar to set widths for") ); 
 990     m_frameStatusBar
->SetStatusWidths(n
, widths_field
); 
 993 wxStatusBar 
*wxFrame::GetStatusBar() const 
 995     return m_frameStatusBar
; 
 998 void wxFrame::SetTitle( const wxString 
&title 
) 
1000     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
1003     if (m_title
.IsNull()) m_title 
= _T(""); 
1004     gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() ); 
1007 void wxFrame::SetIcon( const wxIcon 
&icon 
) 
1009     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid frame") ); 
1012     if (!icon
.Ok()) return; 
1014     if (!m_widget
->window
) return; 
1016     wxMask 
*mask 
= icon
.GetMask(); 
1017     GdkBitmap 
*bm 
= (GdkBitmap 
*) NULL
; 
1018     if (mask
) bm 
= mask
->GetBitmap(); 
1020     gdk_window_set_icon( m_widget
->window
, (GdkWindow 
*) NULL
, icon
.GetPixmap(), bm 
);