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 and Julian Smart 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  11 // ============================================================================ 
  13 // ============================================================================ 
  15 // ---------------------------------------------------------------------------- 
  17 // ---------------------------------------------------------------------------- 
  19 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  20     #pragma implementation "framebase.h" 
  23 // For compilers that support precompilation, includes "wx.h". 
  24 #include "wx/wxprec.h" 
  33     #include "wx/menuitem.h" 
  34     #include "wx/dcclient.h" 
  38     #include "wx/toolbar.h" 
  41     #include "wx/statusbr.h" 
  44 // ---------------------------------------------------------------------------- 
  46 // ---------------------------------------------------------------------------- 
  48 #if wxUSE_MENUS && wxUSE_STATUSBAR 
  50 BEGIN_EVENT_TABLE(wxFrameBase
, wxTopLevelWindow
) 
  51     EVT_MENU_OPEN(wxFrameBase::OnMenuOpen
) 
  52     EVT_MENU_CLOSE(wxFrameBase::OnMenuClose
) 
  54     EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight
) 
  57 #endif // wxUSE_MENUS && wxUSE_STATUSBAR 
  59 // ============================================================================ 
  61 // ============================================================================ 
  63 // ---------------------------------------------------------------------------- 
  64 // construction/destruction 
  65 // ---------------------------------------------------------------------------- 
  67 wxFrameBase::wxFrameBase() 
  70     m_frameMenuBar 
= NULL
; 
  74     m_frameToolBar 
= NULL
; 
  75 #endif // wxUSE_TOOLBAR 
  78     m_frameStatusBar 
= NULL
; 
  79 #endif // wxUSE_STATUSBAR 
  84 wxFrameBase::~wxFrameBase() 
  86     // this destructor is required for Darwin 
  89 wxFrame 
*wxFrameBase::New(wxWindow 
*parent
, 
  91                           const wxString
& title
, 
  97     return new wxFrame(parent
, id
, title
, pos
, size
, style
, name
); 
 100 void wxFrameBase::DeleteAllBars() 
 103     if ( m_frameMenuBar 
) 
 105         delete m_frameMenuBar
; 
 106         m_frameMenuBar 
= (wxMenuBar 
*) NULL
; 
 108 #endif // wxUSE_MENUS 
 111     if ( m_frameStatusBar 
) 
 113         delete m_frameStatusBar
; 
 114         m_frameStatusBar 
= (wxStatusBar 
*) NULL
; 
 116 #endif // wxUSE_STATUSBAR 
 119     if ( m_frameToolBar 
) 
 121         delete m_frameToolBar
; 
 122         m_frameToolBar 
= (wxToolBar 
*) NULL
; 
 124 #endif // wxUSE_TOOLBAR 
 127 bool wxFrameBase::IsOneOfBars(const wxWindow 
*win
) const 
 130     if ( win 
== GetMenuBar() ) 
 132 #endif // wxUSE_MENUS 
 135     if ( win 
== GetStatusBar() ) 
 137 #endif // wxUSE_STATUSBAR 
 140     if ( win 
== GetToolBar() ) 
 142 #endif // wxUSE_TOOLBAR 
 147 // ---------------------------------------------------------------------------- 
 148 // wxFrame size management: we exclude the areas taken by menu/status/toolbars 
 149 // from the client area, so the client area is what's really available for the 
 151 // ---------------------------------------------------------------------------- 
 153 // get the origin of the client area in the client coordinates 
 154 wxPoint 
wxFrameBase::GetClientAreaOrigin() const 
 156     wxPoint pt 
= wxTopLevelWindow::GetClientAreaOrigin(); 
 158 #if wxUSE_TOOLBAR && !defined(__WXUNIVERSAL__) && !defined(__WXWINCE__) 
 159     wxToolBar 
*toolbar 
= GetToolBar(); 
 160     if ( toolbar 
&& toolbar
->IsShown() ) 
 163         toolbar
->GetSize(&w
, &h
); 
 165         if ( toolbar
->GetWindowStyleFlag() & wxTB_VERTICAL 
) 
 174 #endif // wxUSE_TOOLBAR 
 179 // ---------------------------------------------------------------------------- 
 181 // ---------------------------------------------------------------------------- 
 183 bool wxFrameBase::ProcessCommand(int id
) 
 186     wxMenuBar 
*bar 
= GetMenuBar(); 
 190     wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
); 
 191     commandEvent
.SetEventObject(this); 
 193     wxMenuItem 
*item 
= bar
->FindItem(id
); 
 196         if (!item
->IsEnabled()) 
 199         if (item
->IsCheckable()) 
 204             commandEvent
.SetInt(item
->IsChecked()); 
 208     GetEventHandler()->ProcessEvent(commandEvent
); 
 210 #else // !wxUSE_MENUS 
 212 #endif // wxUSE_MENUS/!wxUSE_MENUS 
 215 // Do the UI update processing for this window. This is 
 216 // provided for the application to call if it wants to 
 217 // force a UI update, particularly for the menus and toolbar. 
 218 void wxFrameBase::UpdateWindowUI(long flags
) 
 220     wxWindowBase::UpdateWindowUI(flags
); 
 224         GetToolBar()->UpdateWindowUI(flags
); 
 230         if ((flags 
& wxUPDATE_UI_FROMIDLE
) && !wxUSE_IDLEMENUUPDATES
) 
 232             // If coming from an idle event, we only 
 233             // want to update the menus if we're 
 234             // in the wxUSE_IDLEMENUUPDATES configuration: 
 235             // so if we're not, do nothing 
 240 #endif // wxUSE_MENUS 
 243 // ---------------------------------------------------------------------------- 
 244 // event handlers for status bar updates from menus 
 245 // ---------------------------------------------------------------------------- 
 247 #if wxUSE_MENUS && wxUSE_STATUSBAR 
 249 void wxFrameBase::OnMenuHighlight(wxMenuEvent
& event
) 
 252     (void)ShowMenuHelp(GetStatusBar(), event
.GetMenuId()); 
 253 #endif // wxUSE_STATUSBAR 
 256 #if !wxUSE_IDLEMENUUPDATES 
 257 void wxFrameBase::OnMenuOpen(wxMenuEvent
& event
) 
 259 void wxFrameBase::OnMenuOpen(wxMenuEvent
& WXUNUSED(event
)) 
 262 #if !wxUSE_IDLEMENUUPDATES 
 263     DoMenuUpdates(event
.GetMenu()); 
 264 #endif // !wxUSE_IDLEMENUUPDATES 
 267 void wxFrameBase::OnMenuClose(wxMenuEvent
& WXUNUSED(event
)) 
 269     // do we have real status text to restore? 
 270     if ( m_oldStatusText
.length() > 1 || m_oldStatusText
[0u] ) 
 272         if ( m_statusBarPane 
>= 0 ) 
 274             wxStatusBar 
*statbar 
= GetStatusBar(); 
 276                 statbar
->SetStatusText(m_oldStatusText
, m_statusBarPane
); 
 279         m_oldStatusText
.clear(); 
 283 #endif // wxUSE_MENUS && wxUSE_STATUSBAR 
 285 // Implement internal behaviour (menu updating on some platforms) 
 286 void wxFrameBase::OnInternalIdle() 
 288     wxTopLevelWindow::OnInternalIdle(); 
 290 #if wxUSE_MENUS && wxUSE_IDLEMENUUPDATES 
 291     if (wxUpdateUIEvent::CanUpdate(this)) 
 296 // ---------------------------------------------------------------------------- 
 298 // ---------------------------------------------------------------------------- 
 302 wxStatusBar
* wxFrameBase::CreateStatusBar(int number
, 
 305                                           const wxString
& name
) 
 307     // the main status bar can only be created once (or else it should be 
 308     // deleted before calling CreateStatusBar() again) 
 309     wxCHECK_MSG( !m_frameStatusBar
, (wxStatusBar 
*)NULL
, 
 310                  wxT("recreating status bar in wxFrame") ); 
 312     m_frameStatusBar 
= OnCreateStatusBar( number
, style
, id
, name 
); 
 313     if ( m_frameStatusBar 
) 
 316     return m_frameStatusBar
; 
 319 wxStatusBar 
*wxFrameBase::OnCreateStatusBar(int number
, 
 322                                             const wxString
& name
) 
 324     wxStatusBar 
*statusBar 
= new wxStatusBar(this, id
, style
, name
); 
 326     statusBar
->SetFieldsCount(number
); 
 331 void wxFrameBase::SetStatusText(const wxString
& text
, int number
) 
 333     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set text for") ); 
 335     m_frameStatusBar
->SetStatusText(text
, number
); 
 338 void wxFrameBase::SetStatusWidths(int n
, const int widths_field
[] ) 
 340     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set widths for") ); 
 342     m_frameStatusBar
->SetStatusWidths(n
, widths_field
); 
 347 void wxFrameBase::PushStatusText(const wxString
& text
, int number
) 
 349     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set text for") ); 
 351     m_frameStatusBar
->PushStatusText(text
, number
); 
 354 void wxFrameBase::PopStatusText(int number
) 
 356     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set text for") ); 
 358     m_frameStatusBar
->PopStatusText(number
); 
 361 bool wxFrameBase::ShowMenuHelp(wxStatusBar 
*WXUNUSED(statbar
), int menuId
) 
 364     // if no help string found, we will clear the status bar text 
 366     bool show 
= menuId 
!= wxID_SEPARATOR 
&& menuId 
!= -2 /* wxID_TITLE */; 
 370         wxMenuBar 
*menuBar 
= GetMenuBar(); 
 373             // it's ok if we don't find the item because it might belong 
 375             wxMenuItem 
*item 
= menuBar
->FindItem(menuId
); 
 377                 helpString 
= item
->GetHelp(); 
 381     DoGiveHelp(helpString
, show
); 
 383     return !helpString
.IsEmpty(); 
 384 #else // !wxUSE_MENUS 
 386 #endif // wxUSE_MENUS/!wxUSE_MENUS 
 389 #endif // wxUSE_STATUSBAR 
 391 void wxFrameBase::DoGiveHelp(const wxString
& text
, bool show
) 
 394     if ( m_statusBarPane 
< 0 ) 
 396         // status bar messages disabled 
 400     wxStatusBar 
*statbar 
= GetStatusBar(); 
 408     // remember the old status bar text if this is the first time we're called 
 409     // since the menu has been opened as we're going to overwrite it in our 
 410     // DoGiveHelp() and we want to restore it when the menu is closed 
 412     // note that it would be logical to do this in OnMenuOpen() but under MSW 
 413     // we get an EVT_MENU_HIGHLIGHT before EVT_MENU_OPEN, strangely enough, and 
 414     // so this doesn't work and instead we use the ugly trick with using 
 415     // special m_oldStatusText value as "menu opened" (but it is arguably 
 416     // better than adding yet another member variable to wxFrame on all 
 418     if ( m_oldStatusText
.empty() ) 
 420         m_oldStatusText 
= statbar
->GetStatusText(m_statusBarPane
); 
 421         if ( m_oldStatusText
.empty() ) 
 423             // use special value to prevent us from doing this the next time 
 424             m_oldStatusText 
+= _T('\0'); 
 428     statbar
->SetStatusText(help
, m_statusBarPane
); 
 429 #endif // wxUSE_STATUSBAR 
 433 // ---------------------------------------------------------------------------- 
 435 // ---------------------------------------------------------------------------- 
 439 wxToolBar
* wxFrameBase::CreateToolBar(long style
, 
 441                                       const wxString
& name
) 
 443     // the main toolbar can't be recreated (unless it was explicitly deeleted 
 445     wxCHECK_MSG( !m_frameToolBar
, (wxToolBar 
*)NULL
, 
 446                  wxT("recreating toolbar in wxFrame") ); 
 452         // NB: we don't specify the default value in the method declaration 
 454         //      a) this allows us to have different defaults for different 
 455         //         platforms (even if we don't have them right now) 
 456         //      b) we don't need to include wx/toolbar.h in the header then 
 457         style 
= wxBORDER_NONE 
| wxTB_HORIZONTAL 
| wxTB_FLAT
; 
 460     m_frameToolBar 
= OnCreateToolBar(style
, id
, name
); 
 462     return m_frameToolBar
; 
 465 wxToolBar
* wxFrameBase::OnCreateToolBar(long style
, 
 467                                         const wxString
& name
) 
 469     return new wxToolBar(this, id
, 
 470                          wxDefaultPosition
, wxDefaultSize
, 
 474 #endif // wxUSE_TOOLBAR 
 476 // ---------------------------------------------------------------------------- 
 478 // ---------------------------------------------------------------------------- 
 483 void wxFrameBase::DoMenuUpdates(wxMenu
* menu
) 
 485     wxEvtHandler
* source 
= GetEventHandler(); 
 486     wxMenuBar
* bar 
= GetMenuBar(); 
 489         menu
->UpdateUI(source
); 
 490     else if ( bar 
!= NULL 
) 
 492         int nCount 
= bar
->GetMenuCount(); 
 493         for (int n 
= 0; n 
< nCount
; n
++) 
 494             bar
->GetMenu(n
)->UpdateUI(source
); 
 498 void wxFrameBase::DetachMenuBar() 
 500     if ( m_frameMenuBar 
) 
 502         m_frameMenuBar
->Detach(); 
 503         m_frameMenuBar 
= NULL
; 
 507 void wxFrameBase::AttachMenuBar(wxMenuBar 
*menubar
) 
 511         menubar
->Attach((wxFrame 
*)this); 
 512         m_frameMenuBar 
= menubar
; 
 516 void wxFrameBase::SetMenuBar(wxMenuBar 
*menubar
) 
 518     if ( menubar 
== GetMenuBar() ) 
 526     this->AttachMenuBar(menubar
); 
 529 #endif // wxUSE_MENUS