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"
36 #include "wx/statusbr.h"
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 #if wxUSE_MENUS && wxUSE_STATUSBAR
45 BEGIN_EVENT_TABLE(wxFrameBase
, wxTopLevelWindow
)
46 EVT_MENU_OPEN(wxFrameBase::OnMenuOpen
)
47 EVT_MENU_CLOSE(wxFrameBase::OnMenuClose
)
49 EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight
)
52 #endif // wxUSE_MENUS && wxUSE_STATUSBAR
54 // ============================================================================
56 // ============================================================================
58 // ----------------------------------------------------------------------------
59 // construction/destruction
60 // ----------------------------------------------------------------------------
62 wxFrameBase::wxFrameBase()
65 m_frameMenuBar
= NULL
;
69 m_frameToolBar
= NULL
;
70 #endif // wxUSE_TOOLBAR
73 m_frameStatusBar
= NULL
;
74 #endif // wxUSE_STATUSBAR
79 wxFrameBase::~wxFrameBase()
81 // this destructor is required for Darwin
84 wxFrame
*wxFrameBase::New(wxWindow
*parent
,
86 const wxString
& title
,
92 return new wxFrame(parent
, id
, title
, pos
, size
, style
, name
);
95 void wxFrameBase::DeleteAllBars()
100 delete m_frameMenuBar
;
101 m_frameMenuBar
= (wxMenuBar
*) NULL
;
103 #endif // wxUSE_MENUS
106 if ( m_frameStatusBar
)
108 delete m_frameStatusBar
;
109 m_frameStatusBar
= (wxStatusBar
*) NULL
;
111 #endif // wxUSE_STATUSBAR
114 if ( m_frameToolBar
)
116 delete m_frameToolBar
;
117 m_frameToolBar
= (wxToolBar
*) NULL
;
119 #endif // wxUSE_TOOLBAR
122 bool wxFrameBase::IsOneOfBars(const wxWindow
*win
) const
125 if ( win
== GetMenuBar() )
127 #endif // wxUSE_MENUS
130 if ( win
== GetStatusBar() )
132 #endif // wxUSE_STATUSBAR
135 if ( win
== GetToolBar() )
137 #endif // wxUSE_TOOLBAR
142 // ----------------------------------------------------------------------------
143 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
144 // from the client area, so the client area is what's really available for the
146 // ----------------------------------------------------------------------------
148 // get the origin of the client area in the client coordinates
149 wxPoint
wxFrameBase::GetClientAreaOrigin() const
151 wxPoint pt
= wxTopLevelWindow::GetClientAreaOrigin();
153 #if wxUSE_TOOLBAR && !defined(__WXUNIVERSAL__)
154 wxToolBar
*toolbar
= GetToolBar();
155 if ( toolbar
&& toolbar
->IsShown() )
158 toolbar
->GetSize(&w
, &h
);
160 if ( toolbar
->GetWindowStyleFlag() & wxTB_VERTICAL
)
169 #endif // wxUSE_TOOLBAR
175 void wxFrameBase::SendSizeEvent()
177 wxSizeEvent
event( GetSize(), GetId() );
178 event
.SetEventObject( this );
179 GetEventHandler()->AddPendingEvent( event
);
183 // ----------------------------------------------------------------------------
185 // ----------------------------------------------------------------------------
187 bool wxFrameBase::ProcessCommand(int id
)
190 wxMenuBar
*bar
= GetMenuBar();
194 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
195 commandEvent
.SetEventObject(this);
197 wxMenuItem
*item
= bar
->FindItem(id
);
200 if (!item
->IsEnabled())
203 if ((item
->GetKind() == wxITEM_RADIO
) && item
->IsChecked() )
206 if (item
->IsCheckable())
211 commandEvent
.SetInt(item
->IsChecked());
215 GetEventHandler()->ProcessEvent(commandEvent
);
217 #else // !wxUSE_MENUS
219 #endif // wxUSE_MENUS/!wxUSE_MENUS
222 // Do the UI update processing for this window. This is
223 // provided for the application to call if it wants to
224 // force a UI update, particularly for the menus and toolbar.
225 void wxFrameBase::UpdateWindowUI(long flags
)
227 wxWindowBase::UpdateWindowUI(flags
);
231 GetToolBar()->UpdateWindowUI(flags
);
237 if ((flags
& wxUPDATE_UI_FROMIDLE
) && !wxUSE_IDLEMENUUPDATES
)
239 // If coming from an idle event, we only
240 // want to update the menus if we're
241 // in the wxUSE_IDLEMENUUPDATES configuration:
242 // so if we're not, do nothing
247 #endif // wxUSE_MENUS
250 // ----------------------------------------------------------------------------
251 // event handlers for status bar updates from menus
252 // ----------------------------------------------------------------------------
254 #if wxUSE_MENUS && wxUSE_STATUSBAR
256 void wxFrameBase::OnMenuHighlight(wxMenuEvent
& event
)
259 (void)ShowMenuHelp(GetStatusBar(), event
.GetMenuId());
260 #endif // wxUSE_STATUSBAR
263 #if !wxUSE_IDLEMENUUPDATES
264 void wxFrameBase::OnMenuOpen(wxMenuEvent
& event
)
266 void wxFrameBase::OnMenuOpen(wxMenuEvent
& WXUNUSED(event
))
269 #if !wxUSE_IDLEMENUUPDATES
270 DoMenuUpdates(event
.GetMenu());
271 #endif // !wxUSE_IDLEMENUUPDATES
274 void wxFrameBase::OnMenuClose(wxMenuEvent
& WXUNUSED(event
))
276 // do we have real status text to restore?
277 if ( !m_oldStatusText
.empty() )
279 if ( m_statusBarPane
>= 0 )
281 wxStatusBar
*statbar
= GetStatusBar();
283 statbar
->SetStatusText(m_oldStatusText
, m_statusBarPane
);
286 m_oldStatusText
.clear();
290 #endif // wxUSE_MENUS && wxUSE_STATUSBAR
292 // Implement internal behaviour (menu updating on some platforms)
293 void wxFrameBase::OnInternalIdle()
295 wxTopLevelWindow::OnInternalIdle();
297 #if wxUSE_MENUS && wxUSE_IDLEMENUUPDATES
298 if (wxUpdateUIEvent::CanUpdate(this))
303 // ----------------------------------------------------------------------------
305 // ----------------------------------------------------------------------------
309 wxStatusBar
* wxFrameBase::CreateStatusBar(int number
,
312 const wxString
& name
)
314 // the main status bar can only be created once (or else it should be
315 // deleted before calling CreateStatusBar() again)
316 wxCHECK_MSG( !m_frameStatusBar
, (wxStatusBar
*)NULL
,
317 wxT("recreating status bar in wxFrame") );
319 SetStatusBar(OnCreateStatusBar(number
, style
, id
, name
));
321 return m_frameStatusBar
;
324 wxStatusBar
*wxFrameBase::OnCreateStatusBar(int number
,
327 const wxString
& name
)
329 wxStatusBar
*statusBar
= new wxStatusBar(this, id
, style
, name
);
331 statusBar
->SetFieldsCount(number
);
336 void wxFrameBase::SetStatusText(const wxString
& text
, int number
)
338 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
340 m_frameStatusBar
->SetStatusText(text
, number
);
343 void wxFrameBase::SetStatusWidths(int n
, const int widths_field
[] )
345 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
347 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
352 void wxFrameBase::PushStatusText(const wxString
& text
, int number
)
354 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
356 m_frameStatusBar
->PushStatusText(text
, number
);
359 void wxFrameBase::PopStatusText(int number
)
361 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
363 m_frameStatusBar
->PopStatusText(number
);
366 bool wxFrameBase::ShowMenuHelp(wxStatusBar
*WXUNUSED(statbar
), int menuId
)
369 // if no help string found, we will clear the status bar text
371 bool show
= menuId
!= wxID_SEPARATOR
&& menuId
!= -2 /* wxID_TITLE */;
375 wxMenuBar
*menuBar
= GetMenuBar();
378 // it's ok if we don't find the item because it might belong
380 wxMenuItem
*item
= menuBar
->FindItem(menuId
);
382 helpString
= item
->GetHelp();
386 DoGiveHelp(helpString
, show
);
388 return !helpString
.empty();
389 #else // !wxUSE_MENUS
391 #endif // wxUSE_MENUS/!wxUSE_MENUS
394 void wxFrameBase::SetStatusBar(wxStatusBar
*statBar
)
396 bool hadBar
= m_frameStatusBar
!= NULL
;
397 m_frameStatusBar
= statBar
;
399 if ( (m_frameStatusBar
!= NULL
) != hadBar
)
407 #endif // wxUSE_STATUSBAR
409 void wxFrameBase::DoGiveHelp(const wxString
& text
, bool show
)
412 if ( m_statusBarPane
< 0 )
414 // status bar messages disabled
418 wxStatusBar
*statbar
= GetStatusBar();
426 // remember the old status bar text if this is the first time we're called
427 // since the menu has been opened as we're going to overwrite it in our
428 // DoGiveHelp() and we want to restore it when the menu is closed
430 // note that it would be logical to do this in OnMenuOpen() but under MSW
431 // we get an EVT_MENU_HIGHLIGHT before EVT_MENU_OPEN, strangely enough, and
432 // so this doesn't work and instead we use the ugly trick with using
433 // special m_oldStatusText value as "menu opened" (but it is arguably
434 // better than adding yet another member variable to wxFrame on all
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 statbar
->SetStatusText(help
, m_statusBarPane
);
450 #endif // wxUSE_STATUSBAR
454 // ----------------------------------------------------------------------------
456 // ----------------------------------------------------------------------------
460 wxToolBar
* wxFrameBase::CreateToolBar(long style
,
462 const wxString
& name
)
464 // the main toolbar can't be recreated (unless it was explicitly deeleted
466 wxCHECK_MSG( !m_frameToolBar
, (wxToolBar
*)NULL
,
467 wxT("recreating toolbar in wxFrame") );
473 // NB: we don't specify the default value in the method declaration
475 // a) this allows us to have different defaults for different
476 // platforms (even if we don't have them right now)
477 // b) we don't need to include wx/toolbar.h in the header then
478 style
= wxBORDER_NONE
| wxTB_HORIZONTAL
| wxTB_FLAT
;
481 SetToolBar(OnCreateToolBar(style
, id
, name
));
483 return m_frameToolBar
;
486 wxToolBar
* wxFrameBase::OnCreateToolBar(long style
,
488 const wxString
& name
)
490 #if defined(__WXWINCE__) && defined(__POCKETPC__)
491 return new wxToolMenuBar(this, id
,
492 wxDefaultPosition
, wxDefaultSize
,
495 return new wxToolBar(this, id
,
496 wxDefaultPosition
, wxDefaultSize
,
501 void wxFrameBase::SetToolBar(wxToolBar
*toolbar
)
503 bool hadBar
= m_frameToolBar
!= NULL
;
504 m_frameToolBar
= toolbar
;
506 if ( (m_frameToolBar
!= NULL
) != hadBar
)
514 #endif // wxUSE_TOOLBAR
516 // ----------------------------------------------------------------------------
518 // ----------------------------------------------------------------------------
523 void wxFrameBase::DoMenuUpdates(wxMenu
* menu
)
527 wxEvtHandler
* source
= GetEventHandler();
528 menu
->UpdateUI(source
);
532 wxMenuBar
* bar
= GetMenuBar();
538 void wxFrameBase::DetachMenuBar()
540 if ( m_frameMenuBar
)
542 m_frameMenuBar
->Detach();
543 m_frameMenuBar
= NULL
;
547 void wxFrameBase::AttachMenuBar(wxMenuBar
*menubar
)
551 menubar
->Attach((wxFrame
*)this);
552 m_frameMenuBar
= menubar
;
556 void wxFrameBase::SetMenuBar(wxMenuBar
*menubar
)
558 if ( menubar
== GetMenuBar() )
566 this->AttachMenuBar(menubar
);
569 #endif // wxUSE_MENUS