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, 
  88         win
->m_width 
= alloc
->width
; 
  89         win
->m_height 
= alloc
->height
; 
  94 //----------------------------------------------------------------------------- 
  96 //----------------------------------------------------------------------------- 
  98 static gint 
gtk_frame_delete_callback( GtkWidget 
*WXUNUSED(widget
), GdkEvent 
*WXUNUSED(event
), wxFrame 
*win 
) 
 101         wxapp_install_idle_handler(); 
 108 //----------------------------------------------------------------------------- 
 109 // "child_attached" of menu bar 
 110 //----------------------------------------------------------------------------- 
 112 static void gtk_menu_attached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 114     if (!win
->m_hasVMT
) return; 
 116     win
->m_menuBarDetached 
= FALSE
; 
 120 //----------------------------------------------------------------------------- 
 121 // "child_detached" of menu bar 
 122 //----------------------------------------------------------------------------- 
 124 static void gtk_menu_detached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 126     if (!win
->m_hasVMT
) return; 
 128     win
->m_menuBarDetached 
= TRUE
; 
 133 //----------------------------------------------------------------------------- 
 134 // "child_attached" of tool bar 
 135 //----------------------------------------------------------------------------- 
 137 static void gtk_toolbar_attached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 139     if (!win
->m_hasVMT
) return; 
 141     win
->m_toolBarDetached 
= FALSE
; 
 146 //----------------------------------------------------------------------------- 
 147 // "child_detached" of tool bar 
 148 //----------------------------------------------------------------------------- 
 150 static void gtk_toolbar_detached_callback( GtkWidget 
*WXUNUSED(widget
), GtkWidget 
*WXUNUSED(child
), wxFrame 
*win 
) 
 153         wxapp_install_idle_handler(); 
 155     if (!win
->m_hasVMT
) return; 
 157     win
->m_toolBarDetached 
= TRUE
; 
 160 #endif // wxUSE_TOOLBAR 
 162 //----------------------------------------------------------------------------- 
 164 //----------------------------------------------------------------------------- 
 167 #if (GTK_MINOR_VERSON > 0) 
 168 gtk_frame_configure_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventConfigure 
*WXUNUSED(event
), wxFrame 
*win 
) 
 170 gtk_frame_configure_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventConfigure 
*event
, wxFrame 
*win 
) 
 174         wxapp_install_idle_handler(); 
 176     if (!win
->m_hasVMT
) return FALSE
; 
 178 #if (GTK_MINOR_VERSON > 0) 
 181     gdk_window_get_root_origin( win
->m_widget
->window
, &x
, &y 
); 
 189     wxMoveEvent 
mevent( wxPoint(win
->m_x
,win
->m_y
), win
->GetId() ); 
 190     mevent
.SetEventObject( win 
); 
 191     win
->GetEventHandler()->ProcessEvent( mevent 
); 
 196 //----------------------------------------------------------------------------- 
 197 // "realize" from m_widget 
 198 //----------------------------------------------------------------------------- 
 200 /* we cannot MWM hints and icons before the widget has been realized, 
 201    so we do this directly after realization */ 
 204 gtk_frame_realized_callback( GtkWidget 
*WXUNUSED(widget
), wxFrame 
*win 
) 
 207         wxapp_install_idle_handler(); 
 209     /* all this is for Motif Window Manager "hints" and is supposed to be 
 210        recognized by other WM as well. not tested. */ 
 211     long decor 
= (long) GDK_DECOR_BORDER
; 
 212     long func 
= (long) GDK_FUNC_MOVE
; 
 214     if ((win
->GetWindowStyle() & wxCAPTION
) != 0) 
 215         decor 
|= GDK_DECOR_TITLE
; 
 216     if ((win
->GetWindowStyle() & wxSYSTEM_MENU
) != 0) 
 218        decor 
|= GDK_DECOR_MENU
; 
 219        func 
|= GDK_FUNC_CLOSE
; 
 221     if ((win
->GetWindowStyle() & wxMINIMIZE_BOX
) != 0) 
 223         func 
|= GDK_FUNC_MINIMIZE
; 
 224         decor 
|= GDK_DECOR_MINIMIZE
; 
 226     if ((win
->GetWindowStyle() & wxMAXIMIZE_BOX
) != 0) 
 228         func 
|= GDK_FUNC_MAXIMIZE
; 
 229         decor 
|= GDK_DECOR_MAXIMIZE
; 
 231     if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) != 0) 
 233        func 
|= GDK_FUNC_RESIZE
; 
 234        decor 
|= GDK_DECOR_RESIZEH
; 
 237     gdk_window_set_decorations( win
->m_widget
->window
, (GdkWMDecoration
)decor
); 
 238     gdk_window_set_functions( win
->m_widget
->window
, (GdkWMFunction
)func
); 
 240     /* GTK's shrinking/growing policy */ 
 241     if ((win
->GetWindowStyle() & wxRESIZE_BORDER
) == 0) 
 242         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 0, 0, 1); 
 244         gtk_window_set_policy(GTK_WINDOW(win
->m_widget
), 1, 1, 1); 
 247     gint flag 
= GDK_HINT_POS
; 
 248     if ((win
->GetMinWidth() != -1) || (win
->GetMinHeight() != -1)) flag 
|= GDK_HINT_MIN_SIZE
; 
 249     if ((win
->GetMaxWidth() != -1) || (win
->GetMaxHeight() != -1)) flag 
|= GDK_HINT_MAX_SIZE
; 
 252         gdk_window_set_hints( win
->m_widget
->window
,  
 254                               win
->GetMinWidth(), win
->GetMinHeight(), 
 255                               win
->GetMaxWidth(), win
->GetMaxHeight(), 
 260     if (win
->m_icon 
!= wxNullIcon
) 
 262         wxIcon 
icon( win
->m_icon 
); 
 263         win
->m_icon 
= wxNullIcon
; 
 264         win
->SetIcon( icon 
); 
 267     /* we set the focus to the child that accepts the focus. this 
 268        doesn't really have to be done in "realize" but why not? */ 
 269     wxWindowList::Node 
*node 
= win
->GetChildren().GetFirst(); 
 272         wxWindow 
*child 
= node
->GetData(); 
 273         if (child
->AcceptsFocus()) 
 279         node 
= node
->GetNext(); 
 285 //----------------------------------------------------------------------------- 
 286 // InsertChild for wxFrame 
 287 //----------------------------------------------------------------------------- 
 289 /* Callback for wxFrame. This very strange beast has to be used because 
 290  * C++ has no virtual methods in a constructor. We have to emulate a 
 291  * virtual function here as wxWindows requires different ways to insert 
 292  * a child in container classes. */ 
 294 static void wxInsertChildInFrame( wxFrame
* parent
, wxWindow
* child 
) 
 296     wxASSERT( GTK_IS_WIDGET(child
->m_widget
) ); 
 298     if (!parent
->m_insertInClientArea
) 
 300         /* these are outside the client area */ 
 301         wxFrame
* frame 
= (wxFrame
*) parent
; 
 302         gtk_myfixed_put( GTK_MYFIXED(frame
->m_mainWidget
), 
 303                          GTK_WIDGET(child
->m_widget
), 
 310         /* we connect to these events for recalculating the client area 
 311            space when the toolbar is floating */ 
 312         if (wxIS_KIND_OF(child
,wxToolBar
)) 
 314             wxToolBar 
*toolBar 
= (wxToolBar
*) child
; 
 315             if (toolBar
->GetWindowStyle() & wxTB_DOCKABLE
) 
 317                 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_attached", 
 318                     GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback
), (gpointer
)parent 
); 
 320                 gtk_signal_connect( GTK_OBJECT(toolBar
->m_widget
), "child_detached", 
 321                     GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback
), (gpointer
)parent 
); 
 324 #endif // wxUSE_TOOLBAR 
 328         /* these are inside the client area */ 
 329         gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
), 
 330                          GTK_WIDGET(child
->m_widget
), 
 337     /* resize on OnInternalIdle */ 
 338     parent
->UpdateSize(); 
 341 //----------------------------------------------------------------------------- 
 343 //----------------------------------------------------------------------------- 
 345 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
) 
 346     EVT_SIZE(wxFrame::OnSize
) 
 347     EVT_IDLE(wxFrame::OnIdle
) 
 348     EVT_CLOSE(wxFrame::OnCloseWindow
) 
 349     EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
) 
 352 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
) 
 356     m_frameMenuBar 
= (wxMenuBar 
*) NULL
; 
 358     m_frameStatusBar 
= (wxStatusBar 
*) NULL
; 
 359 #endif // wxUSE_STATUSBAR 
 361     m_frameToolBar 
= (wxToolBar 
*) NULL
; 
 362 #endif // wxUSE_TOOLBAR 
 366     m_mainWidget 
= (GtkWidget
*) NULL
; 
 367     m_menuBarDetached 
= FALSE
; 
 368     m_toolBarDetached 
= FALSE
; 
 369     m_insertInClientArea 
= TRUE
; 
 373 wxFrame::wxFrame( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
 374       const wxPoint 
&pos
, const wxSize 
&size
, 
 375       long style
, const wxString 
&name 
) 
 379     Create( parent
, id
, title
, pos
, size
, style
, name 
); 
 382 bool wxFrame::Create( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
 383       const wxPoint 
&pos
, const wxSize 
&size
, 
 384       long style
, const wxString 
&name 
) 
 386     wxTopLevelWindows
.Append( this ); 
 388     m_needParent 
= FALSE
; 
 390     if (!PreCreation( parent
, pos
, size 
) || 
 391         !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
 393         wxFAIL_MSG( wxT("wxFrame creation failed") ); 
 399     m_insertCallback 
= (wxInsertChildFunction
) wxInsertChildInFrame
; 
 401     GtkWindowType win_type 
= GTK_WINDOW_TOPLEVEL
; 
 402     if (style 
& wxSIMPLE_BORDER
) win_type 
= GTK_WINDOW_POPUP
; 
 404     m_widget 
= gtk_window_new( win_type 
); 
 407         gtk_window_set_wmclass( GTK_WINDOW(m_widget
), name
.mb_str(), name
.mb_str() ); 
 410     debug_focus_in( m_widget
, wxT("wxFrame::m_widget"), name 
); 
 413     gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() ); 
 414     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
 416     gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event", 
 417         GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this ); 
 419     /* m_mainWidget holds the toolbar, the menubar and the client area */ 
 420     m_mainWidget 
= gtk_myfixed_new(); 
 421     gtk_widget_show( m_mainWidget 
); 
 422     GTK_WIDGET_UNSET_FLAGS( m_mainWidget
, GTK_CAN_FOCUS 
); 
 423     gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWidget 
); 
 426     debug_focus_in( m_mainWidget
, wxT("wxFrame::m_mainWidget"), name 
); 
 429     /* m_wxwindow only represents the client area without toolbar and menubar */ 
 430     m_wxwindow 
= gtk_myfixed_new(); 
 431     gtk_widget_show( m_wxwindow 
); 
 432     gtk_container_add( GTK_CONTAINER(m_mainWidget
), m_wxwindow 
); 
 435     debug_focus_in( m_wxwindow
, wxT("wxFrame::m_wxwindow"), name 
); 
 438     /* we donm't allow the frame to get the focus as otherwise 
 439        the frame will grabit at arbitrary fcous changes. */ 
 440     GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
 442     if (m_parent
) m_parent
->AddChild( this ); 
 444     /* the user resized the frame by dragging etc. */ 
 445     gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate", 
 446         GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this ); 
 450     /*  we cannot set MWM hints and icons before the widget has 
 451         been realized, so we do this directly after realization */ 
 452     gtk_signal_connect( GTK_OBJECT(m_widget
), "realize", 
 453                         GTK_SIGNAL_FUNC(gtk_frame_realized_callback
), (gpointer
) this ); 
 455     /* the only way to get the window size is to connect to this event */ 
 456     gtk_signal_connect( GTK_OBJECT(m_widget
), "configure_event", 
 457         GTK_SIGNAL_FUNC(gtk_frame_configure_callback
), (gpointer
)this ); 
 464     m_isBeingDeleted 
= TRUE
; 
 466     if (m_frameMenuBar
) delete m_frameMenuBar
; 
 467     m_frameMenuBar 
= (wxMenuBar 
*) NULL
; 
 470     if (m_frameStatusBar
) delete m_frameStatusBar
; 
 471     m_frameStatusBar 
= (wxStatusBar 
*) NULL
; 
 472 #endif // wxUSE_STATUSBAR 
 475     if (m_frameToolBar
) delete m_frameToolBar
; 
 476     m_frameToolBar 
= (wxToolBar 
*) NULL
; 
 477 #endif // wxUSE_TOOLBAR 
 479     wxTopLevelWindows
.DeleteObject( this ); 
 481     if (wxTheApp
->GetTopWindow() == this) 
 482         wxTheApp
->SetTopWindow( (wxWindow
*) NULL 
); 
 484     if (wxTopLevelWindows
.Number() == 0) 
 485         wxTheApp
->ExitMainLoop(); 
 488 bool wxFrame::Show( bool show 
) 
 490     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 492     if (show 
&& !m_sizeSet
) 
 494         /* by calling GtkOnSize here, we don't have to call 
 495            either after showing the frame, which would entail 
 496            much ugly flicker or from within the size_allocate 
 497            handler, because GTK 1.1.X forbids that. */ 
 499         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 502     return wxWindow::Show( show 
); 
 505 bool wxFrame::Destroy() 
 507     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 509     if (!wxPendingDelete
.Member(this)) wxPendingDelete
.Append(this); 
 514 void wxFrame::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
 516     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 518     /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */ 
 519     wxASSERT_MSG( (m_wxwindow 
!= NULL
), wxT("invalid frame") ); 
 521     /* avoid recursions */ 
 522     if (m_resizing
) return; 
 527     int old_width 
= m_width
; 
 528     int old_height 
= m_height
; 
 530     if ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0) 
 532         if (x 
!= -1) m_x 
= x
; 
 533         if (y 
!= -1) m_y 
= y
; 
 534         if (width 
!= -1) m_width 
= width
; 
 535         if (height 
!= -1) m_height 
= height
; 
 545     if ((sizeFlags 
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
) 
 547         if (width 
== -1) m_width 
= 80; 
 550     if ((sizeFlags 
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
) 
 552        if (height 
== -1) m_height 
= 26; 
 555     if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
 556     if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
 557     if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
 558     if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
 560     if ((m_x 
!= -1) || (m_y 
!= -1)) 
 562         if ((m_x 
!= old_x
) || (m_y 
!= old_y
)) 
 564             gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 568     if ((m_width 
!= old_width
) || (m_height 
!= old_height
)) 
 570         /* we set the size in GtkOnSize, i.e. mostly the actual resizing is 
 571            done either directly before the frame is shown or in idle time 
 572            so that different calls to SetSize() don't lead to flicker. */ 
 579 void wxFrame::Centre( int direction 
) 
 581     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 586     if ((direction 
& wxHORIZONTAL
) == wxHORIZONTAL
) x 
= (gdk_screen_width () - m_width
) / 2; 
 587     if ((direction 
& wxVERTICAL
) == wxVERTICAL
) y 
= (gdk_screen_height () - m_height
) / 2; 
 592 void wxFrame::DoGetClientSize( int *width
, int *height 
) const 
 594     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 596     wxWindow::DoGetClientSize( width
, height 
); 
 602             if (!m_menuBarDetached
) 
 603                 (*height
) -= wxMENU_HEIGHT
; 
 605                 (*height
) -= wxPLACE_HOLDER
; 
 610         if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
; 
 617             if (!m_toolBarDetached
) 
 620                 m_frameToolBar
->GetSize( (int *) NULL
, &y 
); 
 624                 (*height
) -= wxPLACE_HOLDER
; 
 629         (*height
) -= m_miniEdge
*2 + m_miniTitle
; 
 633         (*width
) -= m_miniEdge
*2; 
 637 void wxFrame::DoSetClientSize( int width
, int height 
) 
 639     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 644             if (!m_menuBarDetached
) 
 645                 height 
+= wxMENU_HEIGHT
; 
 647                 height 
+= wxPLACE_HOLDER
; 
 652         if (m_frameStatusBar
) height 
+= wxSTATUS_HEIGHT
; 
 659             if (!m_toolBarDetached
) 
 662                 m_frameToolBar
->GetSize( (int *) NULL
, &y 
); 
 666                 height 
+= wxPLACE_HOLDER
; 
 670     wxWindow::DoSetClientSize( width 
+ m_miniEdge
*2, height  
+ m_miniEdge
*2 + m_miniTitle 
); 
 673 void wxFrame::GtkOnSize( int WXUNUSED(x
), int WXUNUSED(y
), int width
, int height 
) 
 675     // due to a bug in gtk, x,y are always 0 
 679     /* avoid recursions */ 
 680     if (m_resizing
) return; 
 683     /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */ 
 684     wxASSERT_MSG( (m_wxwindow 
!= NULL
), wxT("invalid frame") ); 
 689     /* space occupied by m_frameToolBar and m_frameMenuBar */ 
 690     int client_area_y_offset 
= 0; 
 692     /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses 
 693        wxWindow::Create to create it's GTK equivalent. m_mainWidget is only 
 694        set in wxFrame::Create so it is used to check what kind of frame we 
 695        have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we 
 696        skip the part which handles m_frameMenuBar, m_frameToolBar and (most 
 697        importantly) m_mainWidget */ 
 701         /* check if size is in legal range */ 
 702         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
 703         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
 704         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
 705         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
 707         /* I revert back to wxGTK's original behaviour. m_mainWidget holds the 
 708          * menubar, the toolbar and the client area, which is represented by 
 710          * this hurts in the eye, but I don't want to call SetSize() 
 711          * because I don't want to call any non-native functions here. */ 
 716             int yy 
= m_miniEdge 
+ m_miniTitle
; 
 717             int ww 
= m_width  
- 2*m_miniEdge
; 
 718             int hh 
= wxMENU_HEIGHT
; 
 719             if (m_menuBarDetached
) hh 
= wxPLACE_HOLDER
; 
 720             m_frameMenuBar
->m_x 
= xx
; 
 721             m_frameMenuBar
->m_y 
= yy
; 
 722             m_frameMenuBar
->m_width 
= ww
; 
 723             m_frameMenuBar
->m_height 
= hh
; 
 724             gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
), 
 725                                   m_frameMenuBar
->m_widget
, 
 727             client_area_y_offset 
+= hh
; 
 734             int yy 
= m_miniEdge 
+ m_miniTitle
; 
 737                 if (!m_menuBarDetached
) 
 740                     yy 
+= wxPLACE_HOLDER
; 
 742             int ww 
= m_width 
- 2*m_miniEdge
; 
 743             int hh 
= m_frameToolBar
->m_height
; 
 744             if (m_toolBarDetached
) hh 
= wxPLACE_HOLDER
; 
 745             m_frameToolBar
->m_x 
= xx
; 
 746             m_frameToolBar
->m_y 
= yy
; 
 747             /* m_frameToolBar->m_height = hh;   don't change the toolbar's height */ 
 748             m_frameToolBar
->m_width 
= ww
; 
 749             gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
), 
 750                                   m_frameToolBar
->m_widget
, 
 752             client_area_y_offset 
+= hh
; 
 756         int client_x 
= m_miniEdge
; 
 757         int client_y 
= client_area_y_offset 
+ m_miniEdge 
+ m_miniTitle
; 
 758         int client_w 
= m_width 
- 2*m_miniEdge
; 
 759         int client_h 
= m_height 
- client_area_y_offset
- 2*m_miniEdge 
- m_miniTitle
; 
 760         gtk_myfixed_set_size( GTK_MYFIXED(m_mainWidget
), 
 762                               client_x
, client_y
, client_w
, client_h 
); 
 766         /* if there is no m_mainWidget between m_widget and m_wxwindow there 
 767            is no need to set the size or position of m_wxwindow. */ 
 771     if (m_frameStatusBar
) 
 773         int xx 
= 0 + m_miniEdge
; 
 774         int yy 
= m_height 
- wxSTATUS_HEIGHT 
- m_miniEdge 
- client_area_y_offset
; 
 775         int ww 
= m_width 
- 2*m_miniEdge
; 
 776         int hh 
= wxSTATUS_HEIGHT
; 
 777         m_frameStatusBar
->m_x 
= xx
; 
 778         m_frameStatusBar
->m_y 
= yy
; 
 779         m_frameStatusBar
->m_width 
= ww
; 
 780         m_frameStatusBar
->m_height 
= hh
; 
 781         gtk_myfixed_set_size( GTK_MYFIXED(m_wxwindow
), 
 782                               m_frameStatusBar
->m_widget
, 
 787     /* we actually set the size of a frame here and no-where else */ 
 788     gtk_widget_set_usize( m_widget
, m_width
, m_height 
); 
 793     // send size event to frame 
 794     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
 795     event
.SetEventObject( this ); 
 796     GetEventHandler()->ProcessEvent( event 
); 
 798     // send size event to status bar 
 799     if (m_frameStatusBar
) 
 801         wxSizeEvent 
event2( wxSize(m_frameStatusBar
->m_width
,m_frameStatusBar
->m_height
), m_frameStatusBar
->GetId() ); 
 802         event2
.SetEventObject( m_frameStatusBar 
); 
 803         m_frameStatusBar
->GetEventHandler()->ProcessEvent( event2 
); 
 809 void wxFrame::MakeModal( bool modal 
) 
 812         gtk_grab_add( m_widget 
); 
 814         gtk_grab_remove( m_widget 
); 
 817 void wxFrame::OnInternalIdle() 
 819     if (!m_sizeSet 
&& GTK_WIDGET_REALIZED(m_wxwindow
)) 
 821         GtkOnSize( m_x
, m_y
, m_width
, m_height 
); 
 823         // we'll come back later 
 825             wxapp_install_idle_handler(); 
 829     if (m_frameMenuBar
) m_frameMenuBar
->OnInternalIdle(); 
 831     if (m_frameToolBar
) m_frameToolBar
->OnInternalIdle(); 
 834     if (m_frameStatusBar
) m_frameStatusBar
->OnInternalIdle(); 
 837     wxWindow::OnInternalIdle(); 
 840 void wxFrame::OnCloseWindow( wxCloseEvent
& WXUNUSED(event
) ) 
 845 void wxFrame::OnSize( wxSizeEvent 
&WXUNUSED(event
) ) 
 847     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 849 #if wxUSE_CONSTRAINTS 
 855 #endif // wxUSE_CONSTRAINTS 
 857         /* do we have exactly one child? */ 
 858         wxWindow 
*child 
= (wxWindow 
*)NULL
; 
 859         for ( wxNode 
*node 
= GetChildren().First(); node
; node 
= node
->Next() ) 
 861             wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
 862             if ( !wxIS_KIND_OF(win
,wxFrame
) && !wxIS_KIND_OF(win
,wxDialog
) ) 
 866                     /* it's the second one: do nothing */ 
 874         /* no children at all? */ 
 877             /* yes: set it's size to fill all the frame */ 
 878             int client_x
, client_y
; 
 879             DoGetClientSize( &client_x
, &client_y 
); 
 880             child
->SetSize( 1, 1, client_x
-2, client_y
-2 ); 
 885 void wxFrame::SetMenuBar( wxMenuBar 
*menuBar 
) 
 887     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 888     wxASSERT_MSG( (m_wxwindow 
!= NULL
), wxT("invalid frame") ); 
 890     m_frameMenuBar 
= menuBar
; 
 894         m_frameMenuBar
->SetInvokingWindow( this ); 
 896         if (m_frameMenuBar
->GetParent() != this) 
 898             m_frameMenuBar
->SetParent(this); 
 899             gtk_myfixed_put( GTK_MYFIXED(m_mainWidget
), 
 900                 m_frameMenuBar
->m_widget
, 
 903                 m_frameMenuBar
->m_width
, 
 904                 m_frameMenuBar
->m_height 
); 
 906             if (menuBar
->GetWindowStyle() & wxMB_DOCKABLE
) 
 908                 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_attached", 
 909                     GTK_SIGNAL_FUNC(gtk_menu_attached_callback
), (gpointer
)this ); 
 911                 gtk_signal_connect( GTK_OBJECT(menuBar
->m_widget
), "child_detached", 
 912                     GTK_SIGNAL_FUNC(gtk_menu_detached_callback
), (gpointer
)this ); 
 915             m_frameMenuBar
->Show( TRUE 
); 
 919     /* resize window in OnInternalIdle */ 
 923 wxMenuBar 
*wxFrame::GetMenuBar() const 
 925     return m_frameMenuBar
; 
 928 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
) 
 933         // if no help string found, we will clear the status bar text 
 936         int menuId 
= event
.GetMenuId(); 
 939             wxMenuBar 
*menuBar 
= GetMenuBar(); 
 942                 helpString 
= menuBar
->GetHelpString(menuId
); 
 946         SetStatusText(helpString
); 
 948 #endif // wxUSE_STATUSBAR 
 952 wxToolBar
* wxFrame::CreateToolBar( long style
, wxWindowID id
, const wxString
& name 
) 
 954     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
 956     wxCHECK_MSG( m_frameToolBar 
== NULL
, FALSE
, wxT("recreating toolbar in wxFrame") ); 
 958     m_insertInClientArea 
= FALSE
; 
 960     m_frameToolBar 
= OnCreateToolBar( style
, id
, name 
); 
 962     if (m_frameToolBar
) GetChildren().DeleteObject( m_frameToolBar 
); 
 964     m_insertInClientArea 
= TRUE
; 
 968     return m_frameToolBar
; 
 971 wxToolBar
* wxFrame::OnCreateToolBar( long style
, wxWindowID id
, const wxString
& name 
) 
 973     return new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name 
); 
 976 void wxFrame::SetToolBar(wxToolBar 
*toolbar
)  
 978     m_frameToolBar 
= toolbar
;  
 981         /* insert into toolbar area if not already there */ 
 982         if (m_frameToolBar
->m_widget
->parent 
!= m_mainWidget
) 
 984             gtk_widget_ref( m_frameToolBar
->m_widget 
); 
 985             gtk_widget_unparent( m_frameToolBar
->m_widget 
); 
 987             m_insertInClientArea 
= TRUE
; 
 988             wxInsertChildInFrame( this, m_frameToolBar 
); 
 989             m_insertInClientArea 
= FALSE
; 
 991             gtk_widget_unref( m_frameToolBar
->m_widget 
); 
 996 wxToolBar 
*wxFrame::GetToolBar() const 
 998     return m_frameToolBar
; 
1000 #endif // wxUSE_TOOLBAR 
1003 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name 
) 
1005     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1007     wxCHECK_MSG( m_frameStatusBar 
== NULL
, FALSE
, wxT("recreating status bar in wxFrame") ); 
1009     m_frameStatusBar 
= OnCreateStatusBar( number
, style
, id
, name 
); 
1013     return m_frameStatusBar
; 
1016 wxStatusBar 
*wxFrame::OnCreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name 
) 
1018     wxStatusBar 
*statusBar 
= (wxStatusBar 
*) NULL
; 
1020     statusBar 
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), style
, name
); 
1022     // Set the height according to the font and the border size 
1023     wxClientDC 
dc(statusBar
); 
1024     dc
.SetFont( statusBar
->GetFont() ); 
1027     dc
.GetTextExtent( "X", &x
, &y 
); 
1029     int height 
= (int)( (y  
* 1.1) + 2* statusBar
->GetBorderY()); 
1031     statusBar
->SetSize( -1, -1, 100, height 
); 
1033     statusBar
->SetFieldsCount( number 
); 
1037 wxStatusBar 
*wxFrame::GetStatusBar() const 
1039     return m_frameStatusBar
; 
1042 void wxFrame::SetStatusText(const wxString
& text
, int number
) 
1044     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1046     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set text for") ); 
1048     m_frameStatusBar
->SetStatusText(text
, number
); 
1051 void wxFrame::SetStatusWidths(int n
, const int widths_field
[] ) 
1053     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1055     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set widths for") ); 
1057     m_frameStatusBar
->SetStatusWidths(n
, widths_field
); 
1059 #endif // wxUSE_STATUSBAR 
1061 void wxFrame::Command( int id 
) 
1063     wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
); 
1064     commandEvent
.SetInt( id 
); 
1065     commandEvent
.SetEventObject( this ); 
1067     wxMenuBar 
*bar 
= GetMenuBar(); 
1070     wxMenuItem 
*item 
= bar
->FindItemForId(id
) ; 
1071     if (item 
&& item
->IsCheckable()) 
1073         bar
->Check(id
,!bar
->Checked(id
)) ; 
1076     wxEvtHandler
* evtHandler 
= GetEventHandler(); 
1078     evtHandler
->ProcessEvent(commandEvent
); 
1081 void wxFrame::SetTitle( const wxString 
&title 
) 
1083     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1086     if (m_title
.IsNull()) m_title 
= wxT(""); 
1087     gtk_window_set_title( GTK_WINDOW(m_widget
), title
.mbc_str() ); 
1090 void wxFrame::SetIcon( const wxIcon 
&icon 
) 
1092     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid frame") ); 
1095     if (!icon
.Ok()) return; 
1097     if (!m_widget
->window
) return; 
1099     wxMask 
*mask 
= icon
.GetMask(); 
1100     GdkBitmap 
*bm 
= (GdkBitmap 
*) NULL
; 
1101     if (mask
) bm 
= mask
->GetBitmap(); 
1103     gdk_window_set_icon( m_widget
->window
, (GdkWindow 
*) NULL
, icon
.GetPixmap(), bm 
); 
1106 void wxFrame::Maximize(bool WXUNUSED(maximize
))  
1110 void wxFrame::Restore()  
1114 void wxFrame::Iconize( bool iconize 
)  
1118         XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget
->window 
), 
1119                         GDK_WINDOW_XWINDOW( m_widget
->window 
), 
1120                         DefaultScreen( GDK_DISPLAY() ) ); 
1124 bool wxFrame::IsIconized() const