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
; 
  81   wxTopLevelWindows
.Insert( this ); 
  84 wxFrame::wxFrame( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
  85       const wxPoint 
&pos
, const wxSize 
&size
, 
  86       long style
, const wxString 
&name 
) 
  89   Create( parent
, id
, title
, pos
, size
, style
, name 
); 
  90   wxTopLevelWindows
.Insert( this ); 
  93 bool wxFrame::Create( wxWindow 
*parent
, wxWindowID id
, const wxString 
&title
, 
  94       const wxPoint 
&pos
, const wxSize 
&size
, 
  95       long style
, const wxString 
&name 
) 
 101   PreCreation( parent
, id
, pos
, size
, style
, name 
); 
 103   m_doingOnSize 
= FALSE
; 
 107   m_widget 
= gtk_window_new( GTK_WINDOW_TOPLEVEL 
); 
 108   if ((size
.x 
!= -1) && (size
.y 
!= -1)) 
 109     gtk_widget_set_usize( m_widget
, m_width
, m_height 
); 
 110   if ((pos
.x 
!= -1) && (pos
.y 
!= -1)) 
 111     gtk_widget_set_uposition( m_widget
, m_x
, m_y 
); 
 113   gtk_window_set_title( GTK_WINDOW(m_widget
), title 
); 
 114   GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
 116   gtk_widget_set( m_widget
, "GtkWindow::allow_shrink", TRUE
, NULL
); 
 118   gtk_signal_connect( GTK_OBJECT(m_widget
), "delete_event", 
 119     GTK_SIGNAL_FUNC(gtk_frame_delete_callback
), (gpointer
)this ); 
 121   m_mainWindow 
= gtk_myfixed_new(); 
 122   gtk_widget_show( m_mainWindow 
); 
 123   GTK_WIDGET_UNSET_FLAGS( m_mainWindow
, GTK_CAN_FOCUS 
); 
 125   gtk_container_add( GTK_CONTAINER(m_widget
), m_mainWindow 
); 
 126   gtk_widget_set_uposition( m_mainWindow
, 0, 0 ); 
 128   m_wxwindow 
= gtk_myfixed_new(); 
 129   gtk_widget_show( m_wxwindow 
); 
 130   GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
 132   gtk_container_add( GTK_CONTAINER(m_mainWindow
), m_wxwindow 
); 
 134   m_frameMenuBar 
= NULL
; 
 135   m_frameStatusBar 
= NULL
; 
 137   gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate", 
 138     GTK_SIGNAL_FUNC(gtk_frame_size_callback
), (gpointer
)this ); 
 142   gtk_widget_realize( m_mainWindow 
); 
 149   if (m_frameMenuBar
) delete m_frameMenuBar
; 
 150   if (m_frameStatusBar
) delete m_frameStatusBar
; 
 152 //  if (m_mainWindow) gtk_widget_destroy( m_mainWindow ); 
 154   wxTopLevelWindows
.DeleteObject( this ); 
 155   if (wxTopLevelWindows
.Number() == 0) wxTheApp
->ExitMainLoop(); 
 158 bool wxFrame::Show( bool show 
) 
 162     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
 164     ProcessEvent( event 
); 
 166   return wxWindow::Show( show 
); 
 169 void wxFrame::Enable( bool enable 
) 
 171   wxWindow::Enable( enable 
); 
 172   gtk_widget_set_sensitive( m_mainWindow
, enable 
); 
 175 void wxFrame::OnCloseWindow( wxCloseEvent 
&event 
) 
 177     if ( GetEventHandler()->OnClose() || event
.GetForce()) 
 183 bool wxFrame::Destroy() 
 185   if (!wxPendingDelete
.Member(this)) 
 186     wxPendingDelete
.Append(this); 
 191 void wxFrame::GetClientSize( int *width
, int *height 
) const 
 193   wxWindow::GetClientSize( width
, height 
); 
 196     if (m_frameMenuBar
) (*height
) -= wxMENU_HEIGHT
; 
 197     if (m_frameStatusBar
) (*height
) -= wxSTATUS_HEIGHT
; 
 201 void wxFrame::GtkOnSize( int x
, int y
, int width
, int height 
) 
 206   if ((m_height 
== height
) && (m_width 
== width
) && 
 208   if (!m_mainWindow
) return; 
 209   if (!m_wxwindow
) return; 
 214   gtk_widget_set_usize( m_widget
, width
, height 
); 
 218   int main_height 
= height
; 
 219   int main_width 
= width
; 
 221   // This emulates Windows behaviour: 
 222   // The menu bar is part of the main window, but the status bar 
 223   // is on the implementation side in the client area. The 
 224   // function GetClientSize returns the size of the client area 
 225   // minus the status bar height. Under wxGTK, the main window 
 226   // is represented by m_mainWindow. The menubar is inserted 
 227   // into m_mainWindow whereas the statusbar is insertes into 
 228   // m_wxwindow just like any other window. 
 231   gtk_widget_set_usize( m_mainWindow
, width
, height 
); 
 235     main_y 
= wxMENU_HEIGHT
; 
 236     main_height 
-= wxMENU_HEIGHT
; 
 239   gtk_widget_set_uposition( GTK_WIDGET(m_wxwindow
), main_x
, main_y 
); 
 240   gtk_widget_set_usize( GTK_WIDGET(m_wxwindow
), main_width
, main_height 
); 
 244     gtk_widget_set_uposition( m_frameMenuBar
->m_widget
, 1, 1 ); 
 245     gtk_widget_set_usize( m_frameMenuBar
->m_widget
, width
-2, wxMENU_HEIGHT
-2 ); 
 248   if (m_frameStatusBar
) 
 250     m_frameStatusBar
->SetSize( 0, main_height
-wxSTATUS_HEIGHT
, width
, wxSTATUS_HEIGHT 
); 
 255   wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
 256   event
.SetEventObject( this ); 
 257   ProcessEvent( event 
); 
 260 void wxFrame::OnSize( wxSizeEvent 
&WXUNUSED(event
) ) 
 262   if ( GetAutoLayout() ) 
 265     // no child: go out ! 
 266     if (!GetChildren()->First()) 
 269     // do we have exactly one child? 
 270     wxWindow 
*child 
= NULL
; 
 271     for(wxNode 
*node 
= GetChildren()->First(); node
; node 
= node
->Next()) 
 273       wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
 274       if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && 
 275           !win
->IsKindOf(CLASSINFO(wxDialog
)) 
 276 #if 0 // not in m_children anyway 
 277           && (win 
!= m_frameMenuBar
) && 
 278              (win 
!= m_frameStatusBar
) 
 282         if ( child 
)  // it's the second one: do nothing 
 289     // yes: set it's size to fill all the frame 
 290     int client_x
, client_y
; 
 291     GetClientSize(&client_x
, &client_y
); 
 292     child
->SetSize( 1, 1, client_x
-2, client_y
); 
 296 static void SetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
 298   menu
->SetInvokingWindow( win 
); 
 299   wxNode 
*node 
= menu
->m_items
.First(); 
 302     wxMenuItem 
*menuitem 
= (wxMenuItem
*)node
->Data(); 
 303     if (menuitem
->IsSubMenu()) 
 304       SetInvokingWindow( menuitem
->GetSubMenu(), win 
); 
 309 void wxFrame::SetMenuBar( wxMenuBar 
*menuBar 
) 
 311   m_frameMenuBar 
= menuBar
; 
 315     if (m_frameMenuBar
->m_parent 
!= this) 
 317       wxNode 
*node 
= m_frameMenuBar
->m_menus
.First(); 
 320         wxMenu 
*menu 
= (wxMenu
*)node
->Data(); 
 321         SetInvokingWindow( menu
, this ); 
 325       m_frameMenuBar
->m_parent 
= this; 
 326       gtk_myfixed_put( GTK_MYFIXED(m_mainWindow
), 
 327         m_frameMenuBar
->m_widget
, m_frameMenuBar
->m_x
, m_frameMenuBar
->m_y 
); 
 332 bool wxFrame::CreateStatusBar( int number 
) 
 334   if (m_frameStatusBar
) 
 335   delete m_frameStatusBar
; 
 337   m_frameStatusBar 
= new wxStatusBar( this, -1, wxPoint(0,0), wxSize(100,20) ); 
 339   m_frameStatusBar
->SetFieldsCount( number 
); 
 343 void wxFrame::SetStatusText( const wxString 
&text
, int number 
) 
 345   if (m_frameStatusBar
) m_frameStatusBar
->SetStatusText( text
, number 
); 
 348 void wxFrame::SetStatusWidths( int n
, int *width 
) 
 350   if (m_frameStatusBar
) m_frameStatusBar
->SetStatusWidths( n
, width 
); 
 353 wxStatusBar 
*wxFrame::GetStatusBar() 
 355   return m_frameStatusBar
; 
 358 wxMenuBar 
*wxFrame::GetMenuBar() 
 360   return m_frameMenuBar
; 
 363 void wxFrame::SetTitle( const wxString 
&title 
) 
 366   gtk_window_set_title( GTK_WINDOW(m_widget
), title 
); 
 369 void wxFrame::SetSizeHints(int minW
, int minH
, int maxW
, int maxH
, int incW
) 
 371   // VZ: I don't know a way to set the max size for the window in GTK and have 
 372   //     no idea about what incW might be 
 373   gtk_widget_set_usize(m_widget
, minW
, minH
); 
 376 #include "../common/framecmn.cpp"