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"
32 #include "wx/toolbar.h"
33 #include "wx/statusbr.h"
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 #if wxUSE_MENUS && wxUSE_STATUSBAR
42 BEGIN_EVENT_TABLE(wxFrameBase
, wxTopLevelWindow
)
43 EVT_MENU_OPEN(wxFrameBase::OnMenuOpen
)
44 EVT_MENU_CLOSE(wxFrameBase::OnMenuClose
)
46 EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight
)
49 #endif // wxUSE_MENUS && wxUSE_STATUSBAR
51 // ============================================================================
53 // ============================================================================
55 // ----------------------------------------------------------------------------
56 // construction/destruction
57 // ----------------------------------------------------------------------------
59 wxFrameBase::wxFrameBase()
62 m_frameMenuBar
= NULL
;
66 m_frameToolBar
= NULL
;
67 #endif // wxUSE_TOOLBAR
70 m_frameStatusBar
= NULL
;
71 #endif // wxUSE_STATUSBAR
76 wxFrameBase::~wxFrameBase()
78 // this destructor is required for Darwin
81 wxFrame
*wxFrameBase::New(wxWindow
*parent
,
83 const wxString
& title
,
89 return new wxFrame(parent
, id
, title
, pos
, size
, style
, name
);
92 void wxFrameBase::DeleteAllBars()
97 delete m_frameMenuBar
;
98 m_frameMenuBar
= (wxMenuBar
*) NULL
;
100 #endif // wxUSE_MENUS
103 if ( m_frameStatusBar
)
105 delete m_frameStatusBar
;
106 m_frameStatusBar
= (wxStatusBar
*) NULL
;
108 #endif // wxUSE_STATUSBAR
111 if ( m_frameToolBar
)
113 delete m_frameToolBar
;
114 m_frameToolBar
= (wxToolBar
*) NULL
;
116 #endif // wxUSE_TOOLBAR
119 bool wxFrameBase::IsOneOfBars(const wxWindow
*win
) const
122 if ( win
== GetMenuBar() )
124 #endif // wxUSE_MENUS
127 if ( win
== GetStatusBar() )
129 #endif // wxUSE_STATUSBAR
132 if ( win
== GetToolBar() )
134 #endif // wxUSE_TOOLBAR
139 // ----------------------------------------------------------------------------
140 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
141 // from the client area, so the client area is what's really available for the
143 // ----------------------------------------------------------------------------
145 // get the origin of the client area in the client coordinates
146 wxPoint
wxFrameBase::GetClientAreaOrigin() const
148 wxPoint pt
= wxTopLevelWindow::GetClientAreaOrigin();
150 #if wxUSE_TOOLBAR && !defined(__WXUNIVERSAL__)
151 wxToolBar
*toolbar
= GetToolBar();
152 if ( toolbar
&& toolbar
->IsShown() )
155 toolbar
->GetSize(&w
, &h
);
157 if ( toolbar
->GetWindowStyleFlag() & wxTB_VERTICAL
)
166 #endif // wxUSE_TOOLBAR
172 void wxFrameBase::SendSizeEvent()
174 wxSizeEvent
event( GetSize(), GetId() );
175 event
.SetEventObject( this );
176 GetEventHandler()->AddPendingEvent( event
);
180 // ----------------------------------------------------------------------------
182 // ----------------------------------------------------------------------------
184 bool wxFrameBase::ProcessCommand(int id
)
187 wxMenuBar
*bar
= GetMenuBar();
191 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
192 commandEvent
.SetEventObject(this);
194 wxMenuItem
*item
= bar
->FindItem(id
);
197 if (!item
->IsEnabled())
200 if ((item
->GetKind() == wxITEM_RADIO
) && item
->IsChecked() )
203 if (item
->IsCheckable())
208 commandEvent
.SetInt(item
->IsChecked());
212 GetEventHandler()->ProcessEvent(commandEvent
);
214 #else // !wxUSE_MENUS
216 #endif // wxUSE_MENUS/!wxUSE_MENUS
219 // Do the UI update processing for this window. This is
220 // provided for the application to call if it wants to
221 // force a UI update, particularly for the menus and toolbar.
222 void wxFrameBase::UpdateWindowUI(long flags
)
224 wxWindowBase::UpdateWindowUI(flags
);
228 GetToolBar()->UpdateWindowUI(flags
);
234 if ((flags
& wxUPDATE_UI_FROMIDLE
) && !wxUSE_IDLEMENUUPDATES
)
236 // If coming from an idle event, we only
237 // want to update the menus if we're
238 // in the wxUSE_IDLEMENUUPDATES configuration:
239 // so if we're not, do nothing
244 #endif // wxUSE_MENUS
247 // ----------------------------------------------------------------------------
248 // event handlers for status bar updates from menus
249 // ----------------------------------------------------------------------------
251 #if wxUSE_MENUS && wxUSE_STATUSBAR
253 void wxFrameBase::OnMenuHighlight(wxMenuEvent
& event
)
256 (void)ShowMenuHelp(GetStatusBar(), event
.GetMenuId());
257 #endif // wxUSE_STATUSBAR
260 #if !wxUSE_IDLEMENUUPDATES
261 void wxFrameBase::OnMenuOpen(wxMenuEvent
& event
)
263 void wxFrameBase::OnMenuOpen(wxMenuEvent
& WXUNUSED(event
))
266 #if !wxUSE_IDLEMENUUPDATES
267 DoMenuUpdates(event
.GetMenu());
268 #endif // !wxUSE_IDLEMENUUPDATES
271 void wxFrameBase::OnMenuClose(wxMenuEvent
& WXUNUSED(event
))
273 // do we have real status text to restore?
274 if ( !m_oldStatusText
.empty() )
276 if ( m_statusBarPane
>= 0 )
278 wxStatusBar
*statbar
= GetStatusBar();
280 statbar
->SetStatusText(m_oldStatusText
, m_statusBarPane
);
283 m_oldStatusText
.clear();
287 #endif // wxUSE_MENUS && wxUSE_STATUSBAR
289 // Implement internal behaviour (menu updating on some platforms)
290 void wxFrameBase::OnInternalIdle()
292 wxTopLevelWindow::OnInternalIdle();
294 #if wxUSE_MENUS && wxUSE_IDLEMENUUPDATES
295 if (wxUpdateUIEvent::CanUpdate(this))
300 // ----------------------------------------------------------------------------
302 // ----------------------------------------------------------------------------
306 wxStatusBar
* wxFrameBase::CreateStatusBar(int number
,
309 const wxString
& name
)
311 // the main status bar can only be created once (or else it should be
312 // deleted before calling CreateStatusBar() again)
313 wxCHECK_MSG( !m_frameStatusBar
, (wxStatusBar
*)NULL
,
314 wxT("recreating status bar in wxFrame") );
316 SetStatusBar(OnCreateStatusBar(number
, style
, id
, name
));
318 return m_frameStatusBar
;
321 wxStatusBar
*wxFrameBase::OnCreateStatusBar(int number
,
324 const wxString
& name
)
326 wxStatusBar
*statusBar
= new wxStatusBar(this, id
, style
, name
);
328 statusBar
->SetFieldsCount(number
);
333 void wxFrameBase::SetStatusText(const wxString
& text
, int number
)
335 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
337 m_frameStatusBar
->SetStatusText(text
, number
);
340 void wxFrameBase::SetStatusWidths(int n
, const int widths_field
[] )
342 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
344 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
349 void wxFrameBase::PushStatusText(const wxString
& text
, int number
)
351 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
353 m_frameStatusBar
->PushStatusText(text
, number
);
356 void wxFrameBase::PopStatusText(int number
)
358 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
360 m_frameStatusBar
->PopStatusText(number
);
363 bool wxFrameBase::ShowMenuHelp(wxStatusBar
*WXUNUSED(statbar
), int menuId
)
366 // if no help string found, we will clear the status bar text
368 bool show
= menuId
!= wxID_SEPARATOR
&& menuId
!= -2 /* wxID_TITLE */;
372 wxMenuBar
*menuBar
= GetMenuBar();
375 // it's ok if we don't find the item because it might belong
377 wxMenuItem
*item
= menuBar
->FindItem(menuId
);
379 helpString
= item
->GetHelp();
383 DoGiveHelp(helpString
, show
);
385 return !helpString
.empty();
386 #else // !wxUSE_MENUS
388 #endif // wxUSE_MENUS/!wxUSE_MENUS
391 void wxFrameBase::SetStatusBar(wxStatusBar
*statBar
)
393 bool hadBar
= m_frameStatusBar
!= NULL
;
394 m_frameStatusBar
= statBar
;
396 if ( (m_frameStatusBar
!= NULL
) != hadBar
)
404 #endif // wxUSE_STATUSBAR
406 #if wxUSE_MENUS || wxUSE_TOOLBAR
407 void wxFrameBase::DoGiveHelp(const wxString
& text
, bool show
)
410 if ( m_statusBarPane
< 0 )
412 // status bar messages disabled
416 wxStatusBar
*statbar
= GetStatusBar();
425 // remember the old status bar text if this is the first time we're
426 // called since the menu has been opened as we're going to overwrite it
427 // in our DoGiveHelp() and we want to restore it when the menu is
430 // note that it would be logical to do this in OnMenuOpen() but under
431 // MSW we get an EVT_MENU_HIGHLIGHT before EVT_MENU_OPEN, strangely
432 // enough, and so this doesn't work and instead we use the ugly trick
433 // with using special m_oldStatusText value as "menu opened" (but it is
434 // arguably better than adding yet another member variable to wxFrame
436 if ( m_oldStatusText
.empty() )
438 m_oldStatusText
= statbar
->GetStatusText(m_statusBarPane
);
439 if ( m_oldStatusText
.empty() )
441 // use special value to prevent us from doing this the next time
442 m_oldStatusText
+= _T('\0');
446 else // hide the status bar text
448 // i.e. restore the old one
449 help
= m_oldStatusText
;
452 statbar
->SetStatusText(help
, m_statusBarPane
);
456 #endif // wxUSE_STATUSBAR
458 #endif // wxUSE_MENUS || wxUSE_TOOLBAR
461 // ----------------------------------------------------------------------------
463 // ----------------------------------------------------------------------------
467 wxToolBar
* wxFrameBase::CreateToolBar(long style
,
469 const wxString
& name
)
471 // the main toolbar can't be recreated (unless it was explicitly deleted
473 wxCHECK_MSG( !m_frameToolBar
, (wxToolBar
*)NULL
,
474 wxT("recreating toolbar in wxFrame") );
480 // NB: we don't specify the default value in the method declaration
482 // a) this allows us to have different defaults for different
483 // platforms (even if we don't have them right now)
484 // b) we don't need to include wx/toolbar.h in the header then
485 style
= wxBORDER_NONE
| wxTB_HORIZONTAL
| wxTB_FLAT
;
488 SetToolBar(OnCreateToolBar(style
, id
, name
));
490 return m_frameToolBar
;
493 wxToolBar
* wxFrameBase::OnCreateToolBar(long style
,
495 const wxString
& name
)
497 #if defined(__WXWINCE__) && defined(__POCKETPC__)
498 return new wxToolMenuBar(this, id
,
499 wxDefaultPosition
, wxDefaultSize
,
502 return new wxToolBar(this, id
,
503 wxDefaultPosition
, wxDefaultSize
,
508 void wxFrameBase::SetToolBar(wxToolBar
*toolbar
)
510 bool hadBar
= m_frameToolBar
!= NULL
;
511 m_frameToolBar
= toolbar
;
513 if ( (m_frameToolBar
!= NULL
) != hadBar
)
521 #endif // wxUSE_TOOLBAR
523 // ----------------------------------------------------------------------------
525 // ----------------------------------------------------------------------------
530 void wxFrameBase::DoMenuUpdates(wxMenu
* menu
)
534 wxEvtHandler
* source
= GetEventHandler();
535 menu
->UpdateUI(source
);
539 wxMenuBar
* bar
= GetMenuBar();
545 void wxFrameBase::DetachMenuBar()
547 if ( m_frameMenuBar
)
549 m_frameMenuBar
->Detach();
550 m_frameMenuBar
= NULL
;
554 void wxFrameBase::AttachMenuBar(wxMenuBar
*menubar
)
558 menubar
->Attach((wxFrame
*)this);
559 m_frameMenuBar
= menubar
;
563 void wxFrameBase::SetMenuBar(wxMenuBar
*menubar
)
565 if ( menubar
== GetMenuBar() )
573 this->AttachMenuBar(menubar
);
576 #endif // wxUSE_MENUS