1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        common/framecmn.cpp 
   3 // Purpose:     common (for all platforms) wxFrame functions 
   4 // Author:      Julian Smart, Vadim Zeitlin 
   7 // Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  11 // ============================================================================ 
  13 // ============================================================================ 
  15 // ---------------------------------------------------------------------------- 
  17 // ---------------------------------------------------------------------------- 
  20     #pragma implementation "framebase.h" 
  23 // For compilers that support precompilation, includes "wx.h". 
  24 #include "wx/wxprec.h" 
  32 #include "wx/menuitem.h" 
  33 #include "wx/dcclient.h" 
  36     #include "wx/toolbar.h" 
  39     #include "wx/statusbr.h" 
  42 // ---------------------------------------------------------------------------- 
  44 // ---------------------------------------------------------------------------- 
  46 BEGIN_EVENT_TABLE(wxFrameBase
, wxWindow
) 
  47     EVT_IDLE(wxFrameBase::OnIdle
) 
  48     EVT_CLOSE(wxFrameBase::OnCloseWindow
) 
  49     EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight
) 
  50     EVT_SIZE(wxFrameBase::OnSize
) 
  53 // ============================================================================ 
  55 // ============================================================================ 
  57 // ---------------------------------------------------------------------------- 
  58 // construction/destruction 
  59 // ---------------------------------------------------------------------------- 
  61 wxFrameBase::wxFrameBase() 
  63     m_frameMenuBar 
= NULL
; 
  66     m_frameToolBar 
= NULL
; 
  67 #endif // wxUSE_TOOLBAR 
  70     m_frameStatusBar 
= NULL
; 
  71 #endif // wxUSE_STATUSBAR 
  74 bool wxFrameBase::Destroy() 
  76     // delayed destruction: the frame will be deleted during the next idle 
  78     if ( !wxPendingDelete
.Member(this) ) 
  79         wxPendingDelete
.Append(this); 
  84 wxFrame 
*wxFrameBase::New(wxWindow 
*parent
, 
  86                           const wxString
& title
, 
  92     return new wxFrame(parent
, id
, title
, pos
, size
, style
, name
); 
  95 void wxFrameBase::DeleteAllBars() 
  99         delete m_frameMenuBar
; 
 100         m_frameMenuBar 
= (wxMenuBar 
*) NULL
; 
 104     if ( m_frameStatusBar 
) 
 106         delete m_frameStatusBar
; 
 107         m_frameStatusBar 
= (wxStatusBar 
*) NULL
; 
 109 #endif // wxUSE_STATUSBAR 
 112     if ( m_frameToolBar 
) 
 114         delete m_frameToolBar
; 
 115         m_frameToolBar 
= (wxToolBar 
*) NULL
; 
 117 #endif // wxUSE_TOOLBAR 
 120 // ---------------------------------------------------------------------------- 
 121 // wxFrame size management: we exclude the areas taken by menu/status/toolbars 
 122 // from the client area, so the client area is what's really available for the 
 124 // ---------------------------------------------------------------------------- 
 126 // get the origin of the client area in the client coordinates 
 127 wxPoint 
wxFrameBase::GetClientAreaOrigin() const 
 135         GetToolBar()->GetSize(& w
, & h
); 
 137         if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL 
) 
 146 #endif // wxUSE_TOOLBAR 
 151 void wxFrameBase::DoScreenToClient(int *x
, int *y
) const 
 153     wxWindow::DoScreenToClient(x
, y
); 
 155     // We may be faking the client origin. 
 156     // So a window that's really at (0, 30) may appear 
 157     // (to wxWin apps) to be at (0, 0). 
 158     wxPoint 
pt(GetClientAreaOrigin()); 
 163 void wxFrameBase::DoClientToScreen(int *x
, int *y
) const 
 165     // We may be faking the client origin. 
 166     // So a window that's really at (0, 30) may appear 
 167     // (to wxWin apps) to be at (0, 0). 
 168     wxPoint 
pt1(GetClientAreaOrigin()); 
 172     wxWindow::DoClientToScreen(x
, y
); 
 175 // ---------------------------------------------------------------------------- 
 177 // ---------------------------------------------------------------------------- 
 179 // make the window modal (all other windows unresponsive) 
 180 void wxFrameBase::MakeModal(bool modal
) 
 184         wxEnableTopLevelWindows(FALSE
); 
 185         Enable(TRUE
);           // keep this window enabled 
 189         wxEnableTopLevelWindows(TRUE
); 
 193 bool wxFrameBase::ProcessCommand(int id
) 
 195     wxMenuBar 
*bar 
= GetMenuBar(); 
 199     wxMenuItem 
*item 
= bar
->FindItem(id
); 
 200     if ( item 
&& item
->IsCheckable() ) 
 205     wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
); 
 206     commandEvent
.SetInt(id
); 
 207     commandEvent
.SetEventObject(this); 
 209     return GetEventHandler()->ProcessEvent(commandEvent
); 
 212 // ---------------------------------------------------------------------------- 
 214 // ---------------------------------------------------------------------------- 
 216 // default resizing behaviour - if only ONE subwindow, resize to fill the 
 218 void wxFrameBase::OnSize(wxSizeEvent
& event
) 
 220     // if we're using constraints - do use them 
 221 #if wxUSE_CONSTRAINTS 
 222     if ( GetAutoLayout() ) 
 229         // do we have _exactly_ one child? 
 230         wxWindow 
*child 
= (wxWindow 
*)NULL
; 
 231         for ( wxWindowList::Node 
*node 
= GetChildren().GetFirst(); 
 233               node 
= node
->GetNext() ) 
 235             wxWindow 
*win 
= node
->GetData(); 
 237             // exclude top level and managed windows (status bar isn't 
 238             // currently in the children list except under wxMac anyhow, but 
 239             // it makes no harm to test for it) 
 240             if ( !win
->IsTopLevel() 
 242                     && (win 
!= GetStatusBar()) 
 243 #endif // wxUSE_STATUSBAR 
 245                     && (win 
!= GetToolBar()) 
 246 #endif // wxUSE_TOOLBAR 
 251                     return;     // it's our second subwindow - nothing to do 
 258         // do we have any children at all? 
 261             // exactly one child - set it's size to fill the whole frame 
 262             int clientW
, clientH
; 
 263             DoGetClientSize(&clientW
, &clientH
); 
 265             // for whatever reasons, wxGTK wants to have a small offset - it 
 266             // probably looks better with it? 
 268             static const int ofs 
= 0; 
 270             static const int ofs 
= 1; 
 273             child
->SetSize(ofs
, ofs
, clientW 
- 2*ofs
, clientH 
- 2*ofs
); 
 278 // The default implementation for the close window event. 
 279 void wxFrameBase::OnCloseWindow(wxCloseEvent
& event
) 
 284 void wxFrameBase::OnMenuHighlight(wxMenuEvent
& event
) 
 287     if ( GetStatusBar() ) 
 289         // if no help string found, we will clear the status bar text 
 292         int menuId 
= event
.GetMenuId(); 
 293         if ( menuId 
!= wxID_SEPARATOR 
&& menuId 
!= -2 /* wxID_TITLE */ ) 
 295             wxMenuBar 
*menuBar 
= GetMenuBar(); 
 298                 // it's ok if we don't find the item because it might belong 
 300                 wxMenuItem 
*item 
= menuBar
->FindItem(menuId
); 
 302                     helpString 
= item
->GetHelp(); 
 306         // set status text even if the string is empty - this will at least 
 307         // remove the string from the item which was previously selected 
 308         SetStatusText(helpString
); 
 310 #endif // wxUSE_STATUSBAR 
 313 // ---------------------------------------------------------------------------- 
 315 // ---------------------------------------------------------------------------- 
 319 wxStatusBar
* wxFrameBase::CreateStatusBar(int number
, 
 322                                           const wxString
& name
) 
 324     // the main status bar can only be created once (or else it should be 
 325     // deleted before calling CreateStatusBar() again) 
 326     wxCHECK_MSG( !m_frameStatusBar
, (wxStatusBar 
*)NULL
, 
 327                  wxT("recreating status bar in wxFrame") ); 
 329     m_frameStatusBar 
= OnCreateStatusBar( number
, style
, id
, name 
); 
 330     if ( m_frameStatusBar 
) 
 333     return m_frameStatusBar
; 
 336 wxStatusBar 
*wxFrameBase::OnCreateStatusBar(int number
, 
 339                                             const wxString
& name
) 
 341     wxStatusBar 
*statusBar 
= new wxStatusBar(this, id
, 
 342                                              wxPoint(0, 0), wxSize(100, 20), 
 345     // Set the height according to the font and the border size 
 346     wxClientDC 
dc(statusBar
); 
 347     dc
.SetFont(statusBar
->GetFont()); 
 350     dc
.GetTextExtent( "X", NULL
, &y 
); 
 352     int height 
= (int)( (11*y
)/10 + 2*statusBar
->GetBorderY()); 
 354     statusBar
->SetSize( -1, -1, 100, height 
); 
 356     statusBar
->SetFieldsCount(number
); 
 361 void wxFrameBase::SetStatusText(const wxString
& text
, int number
) 
 363     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set text for") ); 
 365     m_frameStatusBar
->SetStatusText(text
, number
); 
 368 void wxFrameBase::SetStatusWidths(int n
, const int widths_field
[] ) 
 370     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set widths for") ); 
 372     m_frameStatusBar
->SetStatusWidths(n
, widths_field
); 
 377 #endif // wxUSE_STATUSBAR 
 379 // ---------------------------------------------------------------------------- 
 381 // ---------------------------------------------------------------------------- 
 385 wxToolBar
* wxFrameBase::CreateToolBar(long style
, 
 387                                       const wxString
& name
) 
 389     // the main toolbar can't be recreated (unless it was explicitly deeleted 
 391     wxCHECK_MSG( !m_frameToolBar
, (wxToolBar 
*)NULL
, 
 392                  wxT("recreating toolbar in wxFrame") ); 
 394     m_frameToolBar 
= OnCreateToolBar(style
, id
, name
); 
 396     return m_frameToolBar
; 
 399 wxToolBar
* wxFrameBase::OnCreateToolBar(long style
, 
 401                                         const wxString
& name
) 
 403     return new wxToolBar(this, id
, 
 404                          wxDefaultPosition
, wxDefaultSize
, 
 408 #endif // wxUSE_TOOLBAR 
 410 // ---------------------------------------------------------------------------- 
 412 // ---------------------------------------------------------------------------- 
 414 void wxFrameBase::OnIdle(wxIdleEvent
& WXUNUSED(event
) ) 
 420 void wxFrameBase::DoMenuUpdates() 
 422     wxMenuBar
* bar 
= GetMenuBar(); 
 426         int nCount 
= bar
->GetMenuCount(); 
 427         for (int n 
= 0; n 
< nCount
; n
++) 
 428             DoMenuUpdates(bar
->GetMenu(n
), (wxWindow
*) NULL
); 
 432 // update a menu and all submenus recursively 
 433 void wxFrameBase::DoMenuUpdates(wxMenu
* menu
, wxWindow
* WXUNUSED(focusWin
)) 
 435     wxEvtHandler
* evtHandler 
= GetEventHandler(); 
 436     wxMenuItemList::Node
* node 
= menu
->GetMenuItems().GetFirst(); 
 439         wxMenuItem
* item 
= node
->GetData(); 
 440         if ( !item
->IsSeparator() ) 
 442             wxWindowID id 
= item
->GetId(); 
 443             wxUpdateUIEvent 
event(id
); 
 444             event
.SetEventObject( this ); 
 446             if (evtHandler
->ProcessEvent(event
)) 
 448                 if (event
.GetSetText()) 
 449                     menu
->SetLabel(id
, event
.GetText()); 
 450                 if (event
.GetSetChecked()) 
 451                     menu
->Check(id
, event
.GetChecked()); 
 452                 if (event
.GetSetEnabled()) 
 453                     menu
->Enable(id
, event
.GetEnabled()); 
 456             if (item
->GetSubMenu()) 
 457                 DoMenuUpdates(item
->GetSubMenu(), (wxWindow
*) NULL
); 
 459         node 
= node
->GetNext();