1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   7 // Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  12 #pragma implementation "frame.h" 
  16 #include "wx/dialog.h" 
  17 #include "wx/control.h" 
  19 #include "wx/gtk/win_gtk.h" 
  21 const wxMENU_HEIGHT    
= 28; 
  22 const wxSTATUS_HEIGHT  
= 25; 
  24 extern wxList wxTopLevelWindows
; 
  25 extern wxList wxPendingDelete
; 
  27 //----------------------------------------------------------------------------- 
  29 //----------------------------------------------------------------------------- 
  31 //----------------------------------------------------------------------------- 
  34 void gtk_frame_size_callback( GtkWidget 
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxFrame 
*win 
) 
  36   if (!win
->HasVMT()) return; 
  39   printf( "OnFrameResize from " ); 
  40   if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
  41     printf( win->GetClassInfo()->GetClassName() ); 
  45   win
->GtkOnSize( alloc
->x
, alloc
->y
, alloc
->width
, alloc
->height 
); 
  48 //----------------------------------------------------------------------------- 
  51 bool gtk_frame_delete_callback( GtkWidget 
*WXUNUSED(widget
), GdkEvent 
*WXUNUSED(event
), wxFrame 
*win 
) 
  54   printf( "OnDelete from " ); 
  55   if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
  56     printf( win->GetClassInfo()->GetClassName() ); 
  65 //----------------------------------------------------------------------------- 
  67 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
) 
  68   EVT_SIZE(wxFrame::OnSize
) 
  69   EVT_CLOSE(wxFrame::OnCloseWindow
) 
  70   EVT_IDLE(wxFrame::OnIdle
) 
  73 IMPLEMENT_DYNAMIC_CLASS(wxFrame
,wxWindow
) 
  77   m_doingOnSize 
= FALSE
; 
  78   m_frameMenuBar 
= NULL
; 
  79   m_frameStatusBar 
= NULL
; 
  80   m_frameToolBar 
= NULL
; 
  82   m_addPrivateChild 
= FALSE
; 
  83   wxTopLevelWindows
.Insert( this ); 
  86 wxFrame::wxFrame( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
  87       const wxPoint 
&pos
, const wxSize 
&size
, 
  88       long style
, const wxString 
&name 
) 
  90   m_doingOnSize 
= FALSE
; 
  91   m_frameMenuBar 
= NULL
; 
  92   m_frameStatusBar 
= NULL
; 
  93   m_frameToolBar 
= NULL
; 
  95   m_addPrivateChild 
= FALSE
; 
  96   Create( parent
, id
, title
, pos
, size
, style
, name 
); 
  97   wxTopLevelWindows
.Insert( this ); 
 100 bool wxFrame::Create( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
 101       const wxPoint 
&pos
, const wxSize 
&size
, 
 102       long style
, const wxString 
&name 
) 
 104   m_needParent 
= FALSE
; 
 108   PreCreation( parent
, id
, pos
, size
, style
, name 
); 
 110   m_doingOnSize 
= FALSE
; 
 114   m_widget 
= gtk_window_new( GTK_WINDOW_TOPLEVEL 
); 
 115   if ((size
.x 
!= -1) && (size
.y 
!= -1)) 
 116     gtk_widget_set_usize( m_widget
, m_width
, m_height 
); 
 117   if ((pos
.x 
!= -1) && (pos
.y 
!= -1)) 
 118     gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 120   gtk_window_set_title( GTK_WINDOW(m_widget
), title 
); 
 121   GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
 123   gtk_widget_set( m_widget
, "GtkWindow::allow_shrink", TRUE
, NULL
); 
 125   gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event", 
 126     GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this ); 
 128   m_mainWindow 
= gtk_myfixed_new(); 
 129   gtk_widget_show( m_mainWindow 
); 
 130   GTK_WIDGET_UNSET_FLAGS( m_mainWindow
, GTK_CAN_FOCUS 
); 
 132   gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWindow 
); 
 133   gtk_widget_set_uposition( m_mainWindow
, 0, 0 ); 
 135   m_wxwindow 
= gtk_myfixed_new(); 
 136   gtk_widget_show( m_wxwindow 
); 
 137   GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
 139   gtk_container_add( GTK_CONTAINER(m_mainWindow
), m_wxwindow 
); 
 141   gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate", 
 142     GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this ); 
 146   gtk_widget_realize( m_mainWindow 
); 
 153   if (m_frameMenuBar
) delete m_frameMenuBar
; 
 154   if (m_frameStatusBar
) delete m_frameStatusBar
; 
 156 //  if (m_mainWindow) gtk_widget_destroy( m_mainWindow ); 
 158   wxTopLevelWindows
.DeleteObject( this ); 
 159   if (wxTopLevelWindows
.Number() == 0) wxTheApp
->ExitMainLoop(); 
 162 bool wxFrame::Show( bool show 
) 
 166     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
 168     ProcessEvent( event 
); 
 170   return wxWindow::Show( show 
); 
 173 void wxFrame::Enable( bool enable 
) 
 175   wxWindow::Enable( enable 
); 
 176   gtk_widget_set_sensitive( m_mainWindow
, enable 
); 
 179 void wxFrame::OnCloseWindow( wxCloseEvent 
&event 
) 
 181     if ( GetEventHandler()->OnClose() || event
.GetForce()) 
 187 bool wxFrame::Destroy() 
 189   if (!wxPendingDelete
.Member(this)) 
 190     wxPendingDelete
.Append(this); 
 195 void wxFrame::GetClientSize( int *width
, int *height 
) const 
 197   wxWindow::GetClientSize( width
, height 
); 
 200     if (m_frameMenuBar
) (*height
) -= wxMENU_HEIGHT
; 
 201     if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
; 
 205       m_frameToolBar
->GetSize( NULL
, &y 
); 
 211 void wxFrame::GtkOnSize( int x
, int y
, int width
, int height 
) 
 216   if ((m_height 
== height
) && (m_width 
== width
) && 
 218   if (!m_mainWindow
) return; 
 219   if (!m_wxwindow
) return; 
 224   gtk_widget_set_usize( m_widget
, width
, height 
); 
 228   int main_height 
= height
; 
 229   int main_width 
= width
; 
 231   // This emulates Windows behaviour: 
 232   // The menu bar is part of the main window, but the status bar 
 233   // is on the implementation side in the client area. The 
 234   // function GetClientSize returns the size of the client area 
 235   // minus the status bar height. Under wxGTK, the main window 
 236   // is represented by m_mainWindow. The menubar is inserted 
 237   // into m_mainWindow whereas the statusbar is insertes into 
 238   // m_wxwindow just like any other window. 
 241   gtk_widget_set_usize( m_mainWindow
, width
, height 
); 
 245     main_y 
= wxMENU_HEIGHT
; 
 246     main_height 
-= wxMENU_HEIGHT
; 
 249   int toolbar_height 
= 0; 
 250   if (m_frameToolBar
) m_frameToolBar
->GetSize( NULL
, &toolbar_height 
); 
 252   main_y 
+= toolbar_height
; 
 253   main_height 
-= toolbar_height
; 
 255   gtk_widget_set_uposition( GTK_WIDGET(m_wxwindow
), main_x
, main_y 
); 
 256   gtk_widget_set_usize( GTK_WIDGET(m_wxwindow
), main_width
, main_height 
); 
 260     gtk_widget_set_uposition( m_frameMenuBar
->m_widget
, 1, 1 ); 
 261     gtk_widget_set_usize( m_frameMenuBar
->m_widget
, width
-2, wxMENU_HEIGHT
-2 ); 
 266     gtk_widget_set_uposition( m_frameToolBar
->m_widget
, 1, wxMENU_HEIGHT 
); 
 267     gtk_widget_set_usize( m_frameToolBar
->m_widget
, width
-2, toolbar_height 
); 
 270   if (m_frameStatusBar
) 
 272     m_frameStatusBar
->SetSize( 0, main_height
-wxSTATUS_HEIGHT
, width
, wxSTATUS_HEIGHT 
); 
 277   wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
 278   event
.SetEventObject( this ); 
 279   ProcessEvent( event 
); 
 282 void wxFrame::OnSize( wxSizeEvent 
&WXUNUSED(event
) ) 
 284   if ( GetAutoLayout() ) 
 287     // no child: go out ! 
 288     if (!GetChildren()->First()) 
 291     // do we have exactly one child? 
 292     wxWindow 
*child 
= NULL
; 
 293     for(wxNode 
*node 
= GetChildren()->First(); node
; node 
= node
->Next()) 
 295       wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
 296       if (!IS_KIND_OF(win
,wxFrame
) && !IS_KIND_OF(win
,wxDialog
) 
 297 #if 0  // not in m_children anyway 
 298           && (win 
!= m_frameMenuBar
) && 
 299              (win 
!= m_frameToolBar
) && 
 300              (win 
!= m_frameStatusBar
) 
 304         if ( child 
)  // it's the second one: do nothing 
 311     // yes: set it's size to fill all the frame 
 312     int client_x
, client_y
; 
 313     GetClientSize(&client_x
, &client_y
); 
 314     child
->SetSize( 1, 1, client_x
-2, client_y
); 
 318 void wxFrame::AddChild( wxWindow 
*child 
) 
 320   // wxFrame and wxDialog as children aren't placed into the parents 
 322   if (child
->IsKindOf(CLASSINFO(wxFrame
)) || child
->IsKindOf(CLASSINFO(wxDialog
))) 
 324     m_children
.Append( child 
); 
 326     if ((child
->m_x 
!= -1) && (child
->m_y 
!= -1)) 
 327       gtk_widget_set_uposition( child
->m_widget
, child
->m_x
, child
->m_y 
); 
 332   if (m_addPrivateChild
) 
 334     gtk_myfixed_put( GTK_MYFIXED(m_mainWindow
), child
->m_widget
, child
->m_x
, child
->m_y 
); 
 336     gtk_widget_set_usize( child
->m_widget
, child
->m_width
, child
->m_height 
); 
 340     m_children
.Append( child 
); 
 343       gtk_myfixed_put( GTK_MYFIXED(m_wxwindow
), child
->m_widget
, child
->m_x
, child
->m_y 
); 
 345     gtk_widget_set_usize( child
->m_widget
, child
->m_width
, child
->m_height 
); 
 349 static void SetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
 351   menu
->SetInvokingWindow( win 
); 
 352   wxNode 
*node 
= menu
->m_items
.First(); 
 355     wxMenuItem 
*menuitem 
= (wxMenuItem
*)node
->Data(); 
 356     if (menuitem
->IsSubMenu()) 
 357       SetInvokingWindow( menuitem
->GetSubMenu(), win 
); 
 362 void wxFrame::SetMenuBar( wxMenuBar 
*menuBar 
) 
 364   m_frameMenuBar 
= menuBar
; 
 368     if (m_frameMenuBar
->m_parent 
!= this) 
 370       wxNode 
*node 
= m_frameMenuBar
->m_menus
.First(); 
 373         wxMenu 
*menu 
= (wxMenu
*)node
->Data(); 
 374         SetInvokingWindow( menu
, this ); 
 378       m_frameMenuBar
->m_parent 
= this; 
 379       gtk_myfixed_put( GTK_MYFIXED(m_mainWindow
), 
 380         m_frameMenuBar
->m_widget
, m_frameMenuBar
->m_x
, m_frameMenuBar
->m_y 
); 
 385 wxMenuBar 
*wxFrame::GetMenuBar(void) 
 387   return m_frameMenuBar
; 
 390 wxToolBar 
*wxFrame::CreateToolBar( long style 
, wxWindowID id
, const wxString
& name 
) 
 392   m_addPrivateChild 
= TRUE
; 
 394   m_frameToolBar 
= new wxToolBar( this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name 
); 
 396   m_addPrivateChild 
= FALSE
; 
 398   return m_frameToolBar
; 
 401 wxToolBar 
*wxFrame::GetToolBar(void) 
 403   return m_frameToolBar
; 
 406 wxStatusBar
* wxFrame::CreateStatusBar( int number
, long style
, wxWindowID id
, const wxString
& name 
) 
 408   if (m_frameStatusBar
) 
 409   delete m_frameStatusBar
; 
 411   m_frameStatusBar 
= new wxStatusBar( this, id
, wxPoint(0,0), wxSize(100,20), style
, name 
); 
 413   m_frameStatusBar
->SetFieldsCount( number 
); 
 415   return m_frameStatusBar
; 
 418 void wxFrame::SetStatusText( const wxString 
&text
, int number 
) 
 420   if (m_frameStatusBar
) m_frameStatusBar
->SetStatusText( text
, number 
); 
 423 void wxFrame::SetStatusWidths( int n
, int *width 
) 
 425   if (m_frameStatusBar
) m_frameStatusBar
->SetStatusWidths( n
, width 
); 
 428 wxStatusBar 
*wxFrame::GetStatusBar(void) 
 430   return m_frameStatusBar
; 
 433 void wxFrame::SetTitle( const wxString 
&title 
) 
 436   gtk_window_set_title( GTK_WINDOW(m_widget
), title 
); 
 439 void wxFrame::SetSizeHints(int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
) ) 
 442     gdk_window_set_hints( m_wxwindow
->window
, -1, -1,  
 443                           minW
, minH
, maxW
, maxH
, GDK_HINT_MIN_SIZE 
| GDK_HINT_MIN_SIZE 
); 
 446 void wxFrame::SetIcon( const wxIcon 
&icon 
) 
 449   if (!icon
.Ok()) return; 
 451   wxMask 
*mask 
= icon
.GetMask(); 
 452   GdkBitmap 
*bm 
= NULL
; 
 453   if (mask
) bm 
= mask
->GetBitmap(); 
 455   gdk_window_set_icon( m_widget
->window
, NULL
, icon
.GetPixmap(), bm 
);