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 // For compilers that support precompilation, includes "wx.h". 
  20 #include "wx/wxprec.h" 
  29     #include "wx/menuitem.h" 
  30     #include "wx/dcclient.h" 
  34     #include "wx/toolbar.h" 
  37     #include "wx/statusbr.h" 
  40 // ---------------------------------------------------------------------------- 
  42 // ---------------------------------------------------------------------------- 
  44 #if wxUSE_MENUS && wxUSE_STATUSBAR 
  46 BEGIN_EVENT_TABLE(wxFrameBase
, wxTopLevelWindow
) 
  47     EVT_MENU_OPEN(wxFrameBase::OnMenuOpen
) 
  48     EVT_MENU_CLOSE(wxFrameBase::OnMenuClose
) 
  50     EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight
) 
  53 #endif // wxUSE_MENUS && wxUSE_STATUSBAR 
  55 // ============================================================================ 
  57 // ============================================================================ 
  59 // ---------------------------------------------------------------------------- 
  60 // construction/destruction 
  61 // ---------------------------------------------------------------------------- 
  63 wxFrameBase::wxFrameBase() 
  66     m_frameMenuBar 
= NULL
; 
  70     m_frameToolBar 
= NULL
; 
  71 #endif // wxUSE_TOOLBAR 
  74     m_frameStatusBar 
= NULL
; 
  75 #endif // wxUSE_STATUSBAR 
  80 wxFrameBase::~wxFrameBase() 
  82     // this destructor is required for Darwin 
  85 wxFrame 
*wxFrameBase::New(wxWindow 
*parent
, 
  87                           const wxString
& title
, 
  93     return new wxFrame(parent
, id
, title
, pos
, size
, style
, name
); 
  96 void wxFrameBase::DeleteAllBars() 
 101         delete m_frameMenuBar
; 
 102         m_frameMenuBar 
= (wxMenuBar 
*) NULL
; 
 104 #endif // wxUSE_MENUS 
 107     if ( m_frameStatusBar 
) 
 109         delete m_frameStatusBar
; 
 110         m_frameStatusBar 
= (wxStatusBar 
*) NULL
; 
 112 #endif // wxUSE_STATUSBAR 
 115     if ( m_frameToolBar 
) 
 117         delete m_frameToolBar
; 
 118         m_frameToolBar 
= (wxToolBar 
*) NULL
; 
 120 #endif // wxUSE_TOOLBAR 
 123 bool wxFrameBase::IsOneOfBars(const wxWindow 
*win
) const 
 126     if ( win 
== GetMenuBar() ) 
 128 #endif // wxUSE_MENUS 
 131     if ( win 
== GetStatusBar() ) 
 133 #endif // wxUSE_STATUSBAR 
 136     if ( win 
== GetToolBar() ) 
 138 #endif // wxUSE_TOOLBAR 
 143 // ---------------------------------------------------------------------------- 
 144 // wxFrame size management: we exclude the areas taken by menu/status/toolbars 
 145 // from the client area, so the client area is what's really available for the 
 147 // ---------------------------------------------------------------------------- 
 149 // get the origin of the client area in the client coordinates 
 150 wxPoint 
wxFrameBase::GetClientAreaOrigin() const 
 152     wxPoint pt 
= wxTopLevelWindow::GetClientAreaOrigin(); 
 154 #if wxUSE_TOOLBAR && !defined(__WXUNIVERSAL__) 
 155     wxToolBar 
*toolbar 
= GetToolBar(); 
 156     if ( toolbar 
&& toolbar
->IsShown() ) 
 159         toolbar
->GetSize(&w
, &h
); 
 161         if ( toolbar
->GetWindowStyleFlag() & wxTB_VERTICAL 
) 
 170 #endif // wxUSE_TOOLBAR 
 176 void wxFrameBase::SendSizeEvent() 
 178     wxSizeEvent 
event( GetSize(), GetId() ); 
 179     event
.SetEventObject( this ); 
 180     GetEventHandler()->AddPendingEvent( event 
); 
 184 // ---------------------------------------------------------------------------- 
 186 // ---------------------------------------------------------------------------- 
 188 bool wxFrameBase::ProcessCommand(int id
) 
 191     wxMenuBar 
*bar 
= GetMenuBar(); 
 195     wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
); 
 196     commandEvent
.SetEventObject(this); 
 198     wxMenuItem 
*item 
= bar
->FindItem(id
); 
 201         if (!item
->IsEnabled()) 
 204         if ((item
->GetKind() == wxITEM_RADIO
) && item
->IsChecked() ) 
 207         if (item
->IsCheckable()) 
 212             commandEvent
.SetInt(item
->IsChecked()); 
 216     GetEventHandler()->ProcessEvent(commandEvent
); 
 218 #else // !wxUSE_MENUS 
 220 #endif // wxUSE_MENUS/!wxUSE_MENUS 
 223 // Do the UI update processing for this window. This is 
 224 // provided for the application to call if it wants to 
 225 // force a UI update, particularly for the menus and toolbar. 
 226 void wxFrameBase::UpdateWindowUI(long flags
) 
 228     wxWindowBase::UpdateWindowUI(flags
); 
 232         GetToolBar()->UpdateWindowUI(flags
); 
 238         if ((flags 
& wxUPDATE_UI_FROMIDLE
) && !wxUSE_IDLEMENUUPDATES
) 
 240             // If coming from an idle event, we only 
 241             // want to update the menus if we're 
 242             // in the wxUSE_IDLEMENUUPDATES configuration: 
 243             // so if we're not, do nothing 
 248 #endif // wxUSE_MENUS 
 251 // ---------------------------------------------------------------------------- 
 252 // event handlers for status bar updates from menus 
 253 // ---------------------------------------------------------------------------- 
 255 #if wxUSE_MENUS && wxUSE_STATUSBAR 
 257 void wxFrameBase::OnMenuHighlight(wxMenuEvent
& event
) 
 260     (void)ShowMenuHelp(GetStatusBar(), event
.GetMenuId()); 
 261 #endif // wxUSE_STATUSBAR 
 264 #if !wxUSE_IDLEMENUUPDATES 
 265 void wxFrameBase::OnMenuOpen(wxMenuEvent
& event
) 
 267 void wxFrameBase::OnMenuOpen(wxMenuEvent
& WXUNUSED(event
)) 
 270 #if !wxUSE_IDLEMENUUPDATES 
 271     DoMenuUpdates(event
.GetMenu()); 
 272 #endif // !wxUSE_IDLEMENUUPDATES 
 275 void wxFrameBase::OnMenuClose(wxMenuEvent
& WXUNUSED(event
)) 
 277     // do we have real status text to restore? 
 278     if ( !m_oldStatusText
.empty() ) 
 280         if ( m_statusBarPane 
>= 0 ) 
 282             wxStatusBar 
*statbar 
= GetStatusBar(); 
 284                 statbar
->SetStatusText(m_oldStatusText
, m_statusBarPane
); 
 287         m_oldStatusText
.clear(); 
 291 #endif // wxUSE_MENUS && wxUSE_STATUSBAR 
 293 // Implement internal behaviour (menu updating on some platforms) 
 294 void wxFrameBase::OnInternalIdle() 
 296     wxTopLevelWindow::OnInternalIdle(); 
 298 #if wxUSE_MENUS && wxUSE_IDLEMENUUPDATES 
 299     if (wxUpdateUIEvent::CanUpdate(this)) 
 304 // ---------------------------------------------------------------------------- 
 306 // ---------------------------------------------------------------------------- 
 310 wxStatusBar
* wxFrameBase::CreateStatusBar(int number
, 
 313                                           const wxString
& name
) 
 315     // the main status bar can only be created once (or else it should be 
 316     // deleted before calling CreateStatusBar() again) 
 317     wxCHECK_MSG( !m_frameStatusBar
, (wxStatusBar 
*)NULL
, 
 318                  wxT("recreating status bar in wxFrame") ); 
 320     SetStatusBar(OnCreateStatusBar(number
, style
, id
, name
)); 
 322     return m_frameStatusBar
; 
 325 wxStatusBar 
*wxFrameBase::OnCreateStatusBar(int number
, 
 328                                             const wxString
& name
) 
 330     wxStatusBar 
*statusBar 
= new wxStatusBar(this, id
, style
, name
); 
 332     statusBar
->SetFieldsCount(number
); 
 337 void wxFrameBase::SetStatusText(const wxString
& text
, int number
) 
 339     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set text for") ); 
 341     m_frameStatusBar
->SetStatusText(text
, number
); 
 344 void wxFrameBase::SetStatusWidths(int n
, const int widths_field
[] ) 
 346     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set widths for") ); 
 348     m_frameStatusBar
->SetStatusWidths(n
, widths_field
); 
 353 void wxFrameBase::PushStatusText(const wxString
& text
, int number
) 
 355     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set text for") ); 
 357     m_frameStatusBar
->PushStatusText(text
, number
); 
 360 void wxFrameBase::PopStatusText(int number
) 
 362     wxCHECK_RET( m_frameStatusBar 
!= NULL
, wxT("no statusbar to set text for") ); 
 364     m_frameStatusBar
->PopStatusText(number
); 
 367 bool wxFrameBase::ShowMenuHelp(wxStatusBar 
*WXUNUSED(statbar
), int menuId
) 
 370     // if no help string found, we will clear the status bar text 
 372     bool show 
= menuId 
!= wxID_SEPARATOR 
&& menuId 
!= -2 /* wxID_TITLE */; 
 376         wxMenuBar 
*menuBar 
= GetMenuBar(); 
 379             // it's ok if we don't find the item because it might belong 
 381             wxMenuItem 
*item 
= menuBar
->FindItem(menuId
); 
 383                 helpString 
= item
->GetHelp(); 
 387     DoGiveHelp(helpString
, show
); 
 389     return !helpString
.empty(); 
 390 #else // !wxUSE_MENUS 
 392 #endif // wxUSE_MENUS/!wxUSE_MENUS 
 395 void wxFrameBase::SetStatusBar(wxStatusBar 
*statBar
) 
 397     bool hadBar 
= m_frameStatusBar 
!= NULL
; 
 398     m_frameStatusBar 
= statBar
; 
 400     if ( (m_frameStatusBar 
!= NULL
) != hadBar 
) 
 408 #endif // wxUSE_STATUSBAR 
 410 void wxFrameBase::DoGiveHelp(const wxString
& text
, bool show
) 
 413     if ( m_statusBarPane 
< 0 ) 
 415         // status bar messages disabled 
 419     wxStatusBar 
*statbar 
= GetStatusBar(); 
 427     // remember the old status bar text if this is the first time we're called 
 428     // since the menu has been opened as we're going to overwrite it in our 
 429     // DoGiveHelp() and we want to restore it when the menu is closed 
 431     // note that it would be logical to do this in OnMenuOpen() but under MSW 
 432     // we get an EVT_MENU_HIGHLIGHT before EVT_MENU_OPEN, strangely enough, and 
 433     // so this doesn't work and instead we use the ugly trick with using 
 434     // special m_oldStatusText value as "menu opened" (but it is arguably 
 435     // better than adding yet another member variable to wxFrame on all 
 437     if ( m_oldStatusText
.empty() ) 
 439         m_oldStatusText 
= statbar
->GetStatusText(m_statusBarPane
); 
 440         if ( m_oldStatusText
.empty() ) 
 442             // use special value to prevent us from doing this the next time 
 443             m_oldStatusText 
+= _T('\0'); 
 447     statbar
->SetStatusText(help
, m_statusBarPane
); 
 451 #endif // wxUSE_STATUSBAR 
 455 // ---------------------------------------------------------------------------- 
 457 // ---------------------------------------------------------------------------- 
 461 wxToolBar
* wxFrameBase::CreateToolBar(long style
, 
 463                                       const wxString
& name
) 
 465     // the main toolbar can't be recreated (unless it was explicitly deeleted 
 467     wxCHECK_MSG( !m_frameToolBar
, (wxToolBar 
*)NULL
, 
 468                  wxT("recreating toolbar in wxFrame") ); 
 474         // NB: we don't specify the default value in the method declaration 
 476         //      a) this allows us to have different defaults for different 
 477         //         platforms (even if we don't have them right now) 
 478         //      b) we don't need to include wx/toolbar.h in the header then 
 479         style 
= wxBORDER_NONE 
| wxTB_HORIZONTAL 
| wxTB_FLAT
; 
 482     SetToolBar(OnCreateToolBar(style
, id
, name
)); 
 484     return m_frameToolBar
; 
 487 wxToolBar
* wxFrameBase::OnCreateToolBar(long style
, 
 489                                         const wxString
& name
) 
 491 #if defined(__WXWINCE__) && defined(__POCKETPC__) 
 492     return new wxToolMenuBar(this, id
, 
 493                          wxDefaultPosition
, wxDefaultSize
, 
 496     return new wxToolBar(this, id
, 
 497                          wxDefaultPosition
, wxDefaultSize
, 
 502 void wxFrameBase::SetToolBar(wxToolBar 
*toolbar
) 
 504     bool hadBar 
= m_frameToolBar 
!= NULL
; 
 505     m_frameToolBar 
= toolbar
; 
 507     if ( (m_frameToolBar 
!= NULL
) != hadBar 
) 
 515 #endif // wxUSE_TOOLBAR 
 517 // ---------------------------------------------------------------------------- 
 519 // ---------------------------------------------------------------------------- 
 524 void wxFrameBase::DoMenuUpdates(wxMenu
* menu
) 
 528         wxEvtHandler
* source 
= GetEventHandler(); 
 529         menu
->UpdateUI(source
); 
 533         wxMenuBar
* bar 
= GetMenuBar(); 
 539 void wxFrameBase::DetachMenuBar() 
 541     if ( m_frameMenuBar 
) 
 543         m_frameMenuBar
->Detach(); 
 544         m_frameMenuBar 
= NULL
; 
 548 void wxFrameBase::AttachMenuBar(wxMenuBar 
*menubar
) 
 552         menubar
->Attach((wxFrame 
*)this); 
 553         m_frameMenuBar 
= menubar
; 
 557 void wxFrameBase::SetMenuBar(wxMenuBar 
*menubar
) 
 559     if ( menubar 
== GetMenuBar() ) 
 567     this->AttachMenuBar(menubar
); 
 570 #endif // wxUSE_MENUS