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