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__) 
 159     wxToolBar 
*toolbar 
= GetToolBar(); 
 160     if ( toolbar 
&& toolbar
->IsShown() ) 
 163         toolbar
->GetSize(&w
, &h
); 
 165         if ( toolbar
->GetWindowStyleFlag() & wxTB_VERTICAL 
) 
 174 #endif // wxUSE_TOOLBAR 
 180 void wxFrameBase::SendSizeEvent() 
 182     wxSizeEvent 
event( GetSize(), GetId() ); 
 183     event
.SetEventObject( this ); 
 184     GetEventHandler()->AddPendingEvent( event 
); 
 188 // ---------------------------------------------------------------------------- 
 190 // ---------------------------------------------------------------------------- 
 192 bool wxFrameBase::ProcessCommand(int id
) 
 195     wxMenuBar 
*bar 
= GetMenuBar(); 
 199     wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
); 
 200     commandEvent
.SetEventObject(this); 
 202     wxMenuItem 
*item 
= bar
->FindItem(id
); 
 205         if (!item
->IsEnabled()) 
 208         if (item
->IsCheckable()) 
 213             commandEvent
.SetInt(item
->IsChecked()); 
 217     GetEventHandler()->ProcessEvent(commandEvent
); 
 219 #else // !wxUSE_MENUS 
 221 #endif // wxUSE_MENUS/!wxUSE_MENUS 
 224 // Do the UI update processing for this window. This is 
 225 // provided for the application to call if it wants to 
 226 // force a UI update, particularly for the menus and toolbar. 
 227 void wxFrameBase::UpdateWindowUI(long flags
) 
 229     wxWindowBase::UpdateWindowUI(flags
); 
 233         GetToolBar()->UpdateWindowUI(flags
); 
 239         if ((flags 
& wxUPDATE_UI_FROMIDLE
) && !wxUSE_IDLEMENUUPDATES
) 
 241             // If coming from an idle event, we only 
 242             // want to update the menus if we're 
 243             // in the wxUSE_IDLEMENUUPDATES configuration: 
 244             // so if we're not, do nothing 
 249 #endif // wxUSE_MENUS 
 252 // ---------------------------------------------------------------------------- 
 253 // event handlers for status bar updates from menus 
 254 // ---------------------------------------------------------------------------- 
 256 #if wxUSE_MENUS && wxUSE_STATUSBAR 
 258 void wxFrameBase::OnMenuHighlight(wxMenuEvent
& event
) 
 261     (void)ShowMenuHelp(GetStatusBar(), event
.GetMenuId()); 
 262 #endif // wxUSE_STATUSBAR 
 265 #if !wxUSE_IDLEMENUUPDATES 
 266 void wxFrameBase::OnMenuOpen(wxMenuEvent
& event
) 
 268 void wxFrameBase::OnMenuOpen(wxMenuEvent
& WXUNUSED(event
)) 
 271 #if !wxUSE_IDLEMENUUPDATES 
 272     DoMenuUpdates(event
.GetMenu()); 
 273 #endif // !wxUSE_IDLEMENUUPDATES 
 276 void wxFrameBase::OnMenuClose(wxMenuEvent
& WXUNUSED(event
)) 
 278     // do we have real status text to restore? 
 279     if ( !m_oldStatusText
.empty() ) 
 281         if ( m_statusBarPane 
>= 0 ) 
 283             wxStatusBar 
*statbar 
= GetStatusBar(); 
 285                 statbar
->SetStatusText(m_oldStatusText
, m_statusBarPane
); 
 288         m_oldStatusText
.clear(); 
 292 #endif // wxUSE_MENUS && wxUSE_STATUSBAR 
 294 // Implement internal behaviour (menu updating on some platforms) 
 295 void wxFrameBase::OnInternalIdle() 
 297     wxTopLevelWindow::OnInternalIdle(); 
 299 #if wxUSE_MENUS && wxUSE_IDLEMENUUPDATES 
 300     if (wxUpdateUIEvent::CanUpdate(this)) 
 305 // ---------------------------------------------------------------------------- 
 307 // ---------------------------------------------------------------------------- 
 311 wxStatusBar
* wxFrameBase::CreateStatusBar(int number
, 
 314                                           const wxString
& name
) 
 316     // the main status bar can only be created once (or else it should be 
 317     // deleted before calling CreateStatusBar() again) 
 318     wxCHECK_MSG( !m_frameStatusBar
, (wxStatusBar 
*)NULL
, 
 319                  wxT("recreating status bar in wxFrame") ); 
 321     SetStatusBar(OnCreateStatusBar(number
, style
, id
, name
)); 
 323     return m_frameStatusBar
; 
 326 wxStatusBar 
*wxFrameBase::OnCreateStatusBar(int number
, 
 329                                             const wxString
& name
) 
 331     wxStatusBar 
*statusBar 
= new wxStatusBar(this, id
, style
, name
); 
 333     statusBar
->SetFieldsCount(number
); 
 338 void wxFrameBase::SetStatusText(const wxString
& text
, int number
) 
 340     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set text for") ); 
 342     m_frameStatusBar
->SetStatusText(text
, number
); 
 345 void wxFrameBase::SetStatusWidths(int n
, const int widths_field
[] ) 
 347     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set widths for") ); 
 349     m_frameStatusBar
->SetStatusWidths(n
, widths_field
); 
 354 void wxFrameBase::PushStatusText(const wxString
& text
, int number
) 
 356     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set text for") ); 
 358     m_frameStatusBar
->PushStatusText(text
, number
); 
 361 void wxFrameBase::PopStatusText(int number
) 
 363     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set text for") ); 
 365     m_frameStatusBar
->PopStatusText(number
); 
 368 bool wxFrameBase::ShowMenuHelp(wxStatusBar 
*WXUNUSED(statbar
), int menuId
) 
 371     // if no help string found, we will clear the status bar text 
 373     bool show 
= menuId 
!= wxID_SEPARATOR 
&& menuId 
!= -2 /* wxID_TITLE */; 
 377         wxMenuBar 
*menuBar 
= GetMenuBar(); 
 380             // it's ok if we don't find the item because it might belong 
 382             wxMenuItem 
*item 
= menuBar
->FindItem(menuId
); 
 384                 helpString 
= item
->GetHelp(); 
 388     DoGiveHelp(helpString
, show
); 
 390     return !helpString
.empty(); 
 391 #else // !wxUSE_MENUS 
 393 #endif // wxUSE_MENUS/!wxUSE_MENUS 
 396 void wxFrameBase::SetStatusBar(wxStatusBar 
*statBar
) 
 398     bool hadBar 
= m_frameStatusBar 
!= NULL
; 
 399     m_frameStatusBar 
= statBar
; 
 401     if ( (m_frameStatusBar 
!= NULL
) != hadBar 
) 
 409 #endif // wxUSE_STATUSBAR 
 411 void wxFrameBase::DoGiveHelp(const wxString
& text
, bool show
) 
 414     if ( m_statusBarPane 
< 0 ) 
 416         // status bar messages disabled 
 420     wxStatusBar 
*statbar 
= GetStatusBar(); 
 428     // remember the old status bar text if this is the first time we're called 
 429     // since the menu has been opened as we're going to overwrite it in our 
 430     // DoGiveHelp() and we want to restore it when the menu is closed 
 432     // note that it would be logical to do this in OnMenuOpen() but under MSW 
 433     // we get an EVT_MENU_HIGHLIGHT before EVT_MENU_OPEN, strangely enough, and 
 434     // so this doesn't work and instead we use the ugly trick with using 
 435     // special m_oldStatusText value as "menu opened" (but it is arguably 
 436     // better than adding yet another member variable to wxFrame on all 
 438     if ( m_oldStatusText
.empty() ) 
 440         m_oldStatusText 
= statbar
->GetStatusText(m_statusBarPane
); 
 441         if ( m_oldStatusText
.empty() ) 
 443             // use special value to prevent us from doing this the next time 
 444             m_oldStatusText 
+= _T('\0'); 
 448     statbar
->SetStatusText(help
, m_statusBarPane
); 
 452 #endif // wxUSE_STATUSBAR 
 456 // ---------------------------------------------------------------------------- 
 458 // ---------------------------------------------------------------------------- 
 462 wxToolBar
* wxFrameBase::CreateToolBar(long style
, 
 464                                       const wxString
& name
) 
 466     // the main toolbar can't be recreated (unless it was explicitly deeleted 
 468     wxCHECK_MSG( !m_frameToolBar
, (wxToolBar 
*)NULL
, 
 469                  wxT("recreating toolbar in wxFrame") ); 
 475         // NB: we don't specify the default value in the method declaration 
 477         //      a) this allows us to have different defaults for different 
 478         //         platforms (even if we don't have them right now) 
 479         //      b) we don't need to include wx/toolbar.h in the header then 
 480         style 
= wxBORDER_NONE 
| wxTB_HORIZONTAL 
| wxTB_FLAT
; 
 483     SetToolBar(OnCreateToolBar(style
, id
, name
)); 
 485     return m_frameToolBar
; 
 488 wxToolBar
* wxFrameBase::OnCreateToolBar(long style
, 
 490                                         const wxString
& name
) 
 492 #if defined(__WXWINCE__) && defined(__POCKETPC__) 
 493     return new wxToolMenuBar(this, id
, 
 494                          wxDefaultPosition
, wxDefaultSize
, 
 497     return new wxToolBar(this, id
, 
 498                          wxDefaultPosition
, wxDefaultSize
, 
 503 void wxFrameBase::SetToolBar(wxToolBar 
*toolbar
) 
 505     bool hadBar 
= m_frameToolBar 
!= NULL
; 
 506     m_frameToolBar 
= toolbar
; 
 508     if ( (m_frameToolBar 
!= NULL
) != hadBar 
) 
 516 #endif // wxUSE_TOOLBAR 
 518 // ---------------------------------------------------------------------------- 
 520 // ---------------------------------------------------------------------------- 
 525 void wxFrameBase::DoMenuUpdates(wxMenu
* menu
) 
 527     wxEvtHandler
* source 
= GetEventHandler(); 
 528     wxMenuBar
* bar 
= GetMenuBar(); 
 531         menu
->UpdateUI(source
); 
 532     else if ( bar 
!= NULL 
) 
 534         int nCount 
= bar
->GetMenuCount(); 
 535         for (int n 
= 0; n 
< nCount
; n
++) 
 536             bar
->GetMenu(n
)->UpdateUI(source
); 
 540 void wxFrameBase::DetachMenuBar() 
 542     if ( m_frameMenuBar 
) 
 544         m_frameMenuBar
->Detach(); 
 545         m_frameMenuBar 
= NULL
; 
 549 void wxFrameBase::AttachMenuBar(wxMenuBar 
*menubar
) 
 553         menubar
->Attach((wxFrame 
*)this); 
 554         m_frameMenuBar 
= menubar
; 
 558 void wxFrameBase::SetMenuBar(wxMenuBar 
*menubar
) 
 560     if ( menubar 
== GetMenuBar() ) 
 568     this->AttachMenuBar(menubar
); 
 571 #endif // wxUSE_MENUS 
 573 #if WXWIN_COMPATIBILITY_2_2 
 575 bool wxFrameBase::Command(int winid
) 
 577     return ProcessCommand(winid
); 
 580 #endif // WXWIN_COMPATIBILITY_2_2