1 ///////////////////////////////////////////////////////////////////////////// 
   8 // Copyright:   (c) AUTHOR 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "frame.h" 
  17 #include "wx/statusbr.h" 
  18 #include "wx/toolbar.h" 
  19 #include "wx/menuitem.h" 
  21 extern wxList wxModelessWindows
; 
  22 extern wxList wxPendingDelete
; 
  24 BEGIN_EVENT_TABLE(wxFrame
, wxWindow
) 
  25   EVT_SIZE(wxFrame::OnSize
) 
  26   EVT_ACTIVATE(wxFrame::OnActivate
) 
  27   EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight
) 
  28   EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged
) 
  29   EVT_IDLE(wxFrame::OnIdle
) 
  30   EVT_CLOSE(wxFrame::OnCloseWindow
) 
  33 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxWindow
) 
  35 #if wxUSE_NATIVE_STATUSBAR 
  36 bool wxFrame::m_useNativeStatusBar 
= TRUE
; 
  38 bool wxFrame::m_useNativeStatusBar 
= FALSE
; 
  43   m_frameToolBar 
= NULL 
; 
  44   m_frameMenuBar 
= NULL
; 
  45   m_frameStatusBar 
= NULL
; 
  47   m_windowParent 
= NULL
; 
  51 bool wxFrame::Create(wxWindow 
*parent
, 
  53            const wxString
& title
, 
  60     wxTopLevelWindows
.Append(this); 
  63   m_windowStyle 
= style
; 
  64   m_frameMenuBar 
= NULL
; 
  65   m_frameToolBar 
= NULL 
; 
  66   m_frameStatusBar 
= NULL
; 
  68   SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
)); 
  73     m_windowId 
= (int)NewControlId(); 
  75   if (parent
) parent
->AddChild(this); 
  77   wxModelessWindows
.Append(this); 
  79   // TODO: create frame. 
  86   wxTopLevelWindows
.DeleteObject(this); 
  89     delete m_frameStatusBar
; 
  91     delete m_frameMenuBar
; 
  93 /* Check if it's the last top-level window */ 
  95   if (wxTheApp 
&& (wxTopLevelWindows
.Number() == 0)) 
  97     wxTheApp
->SetTopWindow(NULL
); 
  99     if (wxTheApp
->GetExitOnFrameDelete()) 
 101        // TODO signal to the app that we're going to close 
 105   wxModelessWindows
.DeleteObject(this); 
 108 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc. 
 109 void wxFrame::GetClientSize(int *x
, int *y
) const 
 114 // Set the client size (i.e. leave the calculation of borders etc. 
 116 void wxFrame::SetClientSize(int width
, int height
) 
 121 void wxFrame::GetSize(int *width
, int *height
) const 
 126 void wxFrame::GetPosition(int *x
, int *y
) const 
 131 void wxFrame::SetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
 136 bool wxFrame::Show(bool show
) 
 142 void wxFrame::Iconize(bool iconize
) 
 147 // Equivalent to maximize/restore in Windows 
 148 void wxFrame::Maximize(bool maximize
) 
 153 bool wxFrame::IsIconized() const 
 159 void wxFrame::SetTitle(const wxString
& title
) 
 164 wxString 
wxFrame::GetTitle() const 
 170 void wxFrame::SetIcon(const wxIcon
& icon
) 
 176 void wxFrame::SetAcceleratorTable(const wxAcceleratorTable
& accel
) 
 178     m_acceleratorTable 
= accel
; 
 181 wxStatusBar 
*wxFrame::OnCreateStatusBar(int number
, long style
, wxWindowID id
, 
 182     const wxString
& name
) 
 184     wxStatusBar 
*statusBar 
= NULL
; 
 186     statusBar 
= new wxStatusBar(this, id
, wxPoint(0, 0), wxSize(100, 20), 
 189     // Set the height according to the font and the border size 
 190     wxClientDC 
dc(statusBar
); 
 191     dc
.SetFont(* statusBar
->GetFont()); 
 194     dc
.GetTextExtent("X", &x
, &y
); 
 196     int height 
= (int)( (y  
* 1.1) + 2* statusBar
->GetBorderY()); 
 198     statusBar
->SetSize(-1, -1, 100, height
); 
 200     statusBar
->SetFieldsCount(number
); 
 204 wxStatusBar
* wxFrame::CreateStatusBar(int number
, long style
, wxWindowID id
, 
 205     const wxString
& name
) 
 207   // Calling CreateStatusBar twice is an error. 
 208   wxCHECK_MSG( m_frameStatusBar 
== NULL
, FALSE
,  
 209                "recreating status bar in wxFrame" ); 
 211   m_frameStatusBar 
= OnCreateStatusBar(number
, style
, id
, 
 213   if ( m_frameStatusBar 
) 
 216     return m_frameStatusBar
; 
 222 void wxFrame::SetStatusText(const wxString
& text
, int number
) 
 224   wxCHECK_RET( m_frameStatusBar 
!= NULL
, "no statusbar to set text for" ); 
 226   m_frameStatusBar
->SetStatusText(text
, number
); 
 229 void wxFrame::SetStatusWidths(int n
, const int widths_field
[]) 
 231   wxCHECK_RET( m_frameStatusBar 
!= NULL
, "no statusbar to set widths for" ); 
 233   m_frameStatusBar
->SetStatusWidths(n
, widths_field
); 
 237 void wxFrame::PositionStatusBar() 
 240     GetClientSize(&w
, &h
); 
 242     m_frameStatusBar
->GetSize(&sw
, &sh
); 
 244     // Since we wish the status bar to be directly under the client area, 
 245     // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS. 
 246     m_frameStatusBar
->SetSize(0, h
, w
, sh
); 
 249 void wxFrame::SetMenuBar(wxMenuBar 
*menuBar
) 
 253         m_frameMenuBar 
= NULL
; 
 257     m_frameMenuBar 
= menuBar
; 
 264   // Work out max. size 
 265   wxNode 
*node 
= GetChildren()->First(); 
 270     // Find a child that's a subwindow, but not a dialog box. 
 271     wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
 273     if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && 
 274          !win
->IsKindOf(CLASSINFO(wxDialog
))) 
 278       win
->GetSize(&width
, &height
); 
 279       win
->GetPosition(&x
, &y
); 
 281       if ((x 
+ width
) > max_width
) 
 282         max_width 
= x 
+ width
; 
 283       if ((y 
+ height
) > max_height
) 
 284         max_height 
= y 
+ height
; 
 288   SetClientSize(max_width
, max_height
); 
 291 // Responds to colour changes, and passes event on to children. 
 292 void wxFrame::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
 294     SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
)); 
 297     if ( m_frameStatusBar 
) 
 299         wxSysColourChangedEvent event2
; 
 300         event2
.SetEventObject( m_frameStatusBar 
); 
 301         m_frameStatusBar
->ProcessEvent(event2
); 
 304     // Propagate the event to the non-top-level children 
 305     wxWindow::OnSysColourChanged(event
); 
 308 // Default resizing behaviour - if only ONE subwindow, 
 309 // resize to client rectangle size 
 310 void wxFrame::OnSize(wxSizeEvent
& event
) 
 312   // if we're using constraints - do use them 
 313   #if wxUSE_CONSTRAINTS 
 314     if ( GetAutoLayout() ) { 
 320   // do we have _exactly_ one child? 
 321   wxWindow 
*child 
= NULL
; 
 322   for ( wxNode 
*node 
= GetChildren()->First(); node
; node 
= node
->Next() ) 
 324     wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
 325     if ( !win
->IsKindOf(CLASSINFO(wxFrame
))  && 
 326          !win
->IsKindOf(CLASSINFO(wxDialog
)) &&  
 327          (win 
!= GetStatusBar()) && 
 328          (win 
!= GetToolBar()) ) 
 331         return;     // it's our second subwindow - nothing to do 
 337     // we have exactly one child - set it's size to fill the whole frame 
 338     int clientW
, clientH
; 
 339     GetClientSize(&clientW
, &clientH
); 
 344     child
->SetSize(x
, y
, clientW
, clientH
); 
 348 // Default activation behaviour - set the focus for the first child 
 350 void wxFrame::OnActivate(wxActivateEvent
& event
) 
 352   for(wxNode 
*node 
= GetChildren()->First(); node
; node 
= node
->Next()) 
 354     // Find a child that's a subwindow, but not a dialog box. 
 355     wxWindow 
*child 
= (wxWindow 
*)node
->Data(); 
 356     if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && 
 357          !child
->IsKindOf(CLASSINFO(wxDialog
))) 
 360       wxDebugMsg("wxFrame::OnActivate: about to set the child's focus.\n"); 
 368 // The default implementation for the close window event. 
 369 void wxFrame::OnCloseWindow(wxCloseEvent
& event
) 
 374 // Destroy the window (delayed, if a managed window) 
 375 bool wxFrame::Destroy() 
 377   if (!wxPendingDelete
.Member(this)) 
 378     wxPendingDelete
.Append(this); 
 382 // Default menu selection behaviour - display a help string 
 383 void wxFrame::OnMenuHighlight(wxMenuEvent
& event
) 
 387     if (event
.GetMenuId() == -1) 
 391       wxMenuBar 
*menuBar 
= GetMenuBar(); 
 394         wxString 
helpString(menuBar
->GetHelpString(event
.GetMenuId())); 
 395         if (helpString 
!= "") 
 396           SetStatusText(helpString
); 
 402 wxMenuBar 
*wxFrame::GetMenuBar() const 
 404   return m_frameMenuBar
; 
 407 void wxFrame::Centre(int direction
) 
 409   int display_width
, display_height
, width
, height
, x
, y
; 
 410   wxDisplaySize(&display_width
, &display_height
); 
 412   GetSize(&width
, &height
); 
 415   if (direction 
& wxHORIZONTAL
) 
 416     x 
= (int)((display_width 
- width
)/2); 
 417   if (direction 
& wxVERTICAL
) 
 418     y 
= (int)((display_height 
- height
)/2); 
 420   SetSize(x
, y
, width
, height
); 
 423 // Call this to simulate a menu command 
 424 void wxFrame::Command(int id
) 
 429 void wxFrame::ProcessCommand(int id
) 
 431   wxCommandEvent 
commandEvent(wxEVENT_TYPE_MENU_COMMAND
, id
); 
 432   commandEvent
.SetInt( id 
); 
 433   commandEvent
.SetEventObject( this ); 
 435   wxMenuBar 
*bar 
= GetMenuBar() ; 
 439 /* TODO: check the menu item if required 
 440   wxMenuItem *item = bar->FindItemForId(id) ; 
 441   if (item && item->IsCheckable()) 
 443     bar->Check(id,!bar->Checked(id)) ; 
 447   GetEventHandler()->ProcessEvent(commandEvent
); 
 450 // Checks if there is a toolbar, and returns the first free client position 
 451 wxPoint 
wxFrame::GetClientAreaOrigin() const 
 457         GetToolBar()->GetSize(& w
, & h
); 
 459         if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
) 
 471 wxToolBar
* wxFrame::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
) 
 473     wxCHECK_MSG( m_frameToolBar 
== NULL
, FALSE
, 
 474                "recreating toolbar in wxFrame" ); 
 476     wxToolBar
* toolBar 
= OnCreateToolBar(style
, id
, name
); 
 489 wxToolBar
* wxFrame::OnCreateToolBar(long style
, wxWindowID id
, const wxString
& name
) 
 491     return new wxToolBar(this, id
, wxDefaultPosition
, wxDefaultSize
, style
, name
); 
 494 void wxFrame::PositionToolBar() 
 498     // TODO: we actually need to use the low-level client size, before 
 499     // the toolbar/status bar were added. 
 500     // So DEFINITELY replace the line below with something appropriate. 
 502     wxCHECK_MSG( TRUE
, FALSE
, 
 503                "PositionToolBar not implemented properly, see frame.cpp" ); 
 505     GetClientSize(& cw
, &ch
); 
 507     if ( GetStatusBar() ) 
 509       int statusX
, statusY
; 
 510       GetStatusBar()->GetClientSize(&statusX
, &statusY
); 
 517         GetToolBar()->GetSize(& tw
, & th
); 
 519         if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
) 
 521             // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS 
 522             // means, pretend we don't have toolbar/status bar, so we 
 523             // have the original client size. 
 524             GetToolBar()->SetSize(0, 0, tw
, ch
, wxSIZE_NO_ADJUSTMENTS
); 
 528             // Use the 'real' position 
 529             GetToolBar()->SetSize(0, 0, cw
, th
, wxSIZE_NO_ADJUSTMENTS
);