1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/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 // For compilers that support precompilation, includes "wx.h". 
  20 #include "wx/wxprec.h" 
  30     #include "wx/menuitem.h" 
  31     #include "wx/dcclient.h" 
  35     #include "wx/toolbar.h" 
  38     #include "wx/statusbr.h" 
  41 // ---------------------------------------------------------------------------- 
  43 // ---------------------------------------------------------------------------- 
  45 #if wxUSE_MENUS && wxUSE_STATUSBAR 
  47 BEGIN_EVENT_TABLE(wxFrameBase
, wxTopLevelWindow
) 
  48     EVT_MENU_OPEN(wxFrameBase::OnMenuOpen
) 
  49     EVT_MENU_CLOSE(wxFrameBase::OnMenuClose
) 
  51     EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight
) 
  54 #endif // wxUSE_MENUS && wxUSE_STATUSBAR 
  56 // ============================================================================ 
  58 // ============================================================================ 
  60 // ---------------------------------------------------------------------------- 
  61 // construction/destruction 
  62 // ---------------------------------------------------------------------------- 
  64 wxFrameBase::wxFrameBase() 
  67     m_frameMenuBar 
= NULL
; 
  71     m_frameToolBar 
= NULL
; 
  72 #endif // wxUSE_TOOLBAR 
  75     m_frameStatusBar 
= NULL
; 
  76 #endif // wxUSE_STATUSBAR 
  81 wxFrameBase::~wxFrameBase() 
  83     // this destructor is required for Darwin 
  86 wxFrame 
*wxFrameBase::New(wxWindow 
*parent
, 
  88                           const wxString
& title
, 
  94     return new wxFrame(parent
, id
, title
, pos
, size
, style
, name
); 
  97 void wxFrameBase::DeleteAllBars() 
 100     if ( m_frameMenuBar 
) 
 102         delete m_frameMenuBar
; 
 103         m_frameMenuBar 
= (wxMenuBar 
*) NULL
; 
 105 #endif // wxUSE_MENUS 
 108     if ( m_frameStatusBar 
) 
 110         delete m_frameStatusBar
; 
 111         m_frameStatusBar 
= (wxStatusBar 
*) NULL
; 
 113 #endif // wxUSE_STATUSBAR 
 116     if ( m_frameToolBar 
) 
 118         delete m_frameToolBar
; 
 119         m_frameToolBar 
= (wxToolBar 
*) NULL
; 
 121 #endif // wxUSE_TOOLBAR 
 124 bool wxFrameBase::IsOneOfBars(const wxWindow 
*win
) const 
 127     if ( win 
== GetMenuBar() ) 
 129 #endif // wxUSE_MENUS 
 132     if ( win 
== GetStatusBar() ) 
 134 #endif // wxUSE_STATUSBAR 
 137     if ( win 
== GetToolBar() ) 
 139 #endif // wxUSE_TOOLBAR 
 144 // ---------------------------------------------------------------------------- 
 145 // wxFrame size management: we exclude the areas taken by menu/status/toolbars 
 146 // from the client area, so the client area is what's really available for the 
 148 // ---------------------------------------------------------------------------- 
 150 // get the origin of the client area in the client coordinates 
 151 wxPoint 
wxFrameBase::GetClientAreaOrigin() const 
 153     wxPoint pt 
= wxTopLevelWindow::GetClientAreaOrigin(); 
 155 #if wxUSE_TOOLBAR && !defined(__WXUNIVERSAL__) 
 156     wxToolBar 
*toolbar 
= GetToolBar(); 
 157     if ( toolbar 
&& toolbar
->IsShown() ) 
 160         toolbar
->GetSize(&w
, &h
); 
 162         if ( toolbar
->GetWindowStyleFlag() & wxTB_VERTICAL 
) 
 171 #endif // wxUSE_TOOLBAR 
 177 void wxFrameBase::SendSizeEvent() 
 179     wxSizeEvent 
event( GetSize(), GetId() ); 
 180     event
.SetEventObject( this ); 
 181     GetEventHandler()->AddPendingEvent( event 
); 
 185 // ---------------------------------------------------------------------------- 
 187 // ---------------------------------------------------------------------------- 
 189 bool wxFrameBase::ProcessCommand(int id
) 
 192     wxMenuBar 
*bar 
= GetMenuBar(); 
 196     wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
); 
 197     commandEvent
.SetEventObject(this); 
 199     wxMenuItem 
*item 
= bar
->FindItem(id
); 
 202         if (!item
->IsEnabled()) 
 205         if ((item
->GetKind() == wxITEM_RADIO
) && item
->IsChecked() ) 
 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
) 
 529         wxEvtHandler
* source 
= GetEventHandler(); 
 530         menu
->UpdateUI(source
); 
 534         wxMenuBar
* bar 
= GetMenuBar(); 
 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