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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
20 #pragma implementation "framebase.h"
23 // For compilers that support precompilation, includes "wx.h".
24 #include "wx/wxprec.h"
33 #include "wx/menuitem.h"
34 #include "wx/dcclient.h"
38 #include "wx/toolbar.h"
41 #include "wx/statusbr.h"
44 // ----------------------------------------------------------------------------
46 // ----------------------------------------------------------------------------
48 #if wxUSE_MENUS && wxUSE_STATUSBAR
50 BEGIN_EVENT_TABLE(wxFrameBase
, wxTopLevelWindow
)
51 EVT_MENU_OPEN(wxFrameBase::OnMenuOpen
)
52 EVT_MENU_CLOSE(wxFrameBase::OnMenuClose
)
54 EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight
)
57 #endif // wxUSE_MENUS && wxUSE_STATUSBAR
59 // ============================================================================
61 // ============================================================================
63 // ----------------------------------------------------------------------------
64 // construction/destruction
65 // ----------------------------------------------------------------------------
67 wxFrameBase::wxFrameBase()
70 m_frameMenuBar
= NULL
;
74 m_frameToolBar
= NULL
;
75 #endif // wxUSE_TOOLBAR
78 m_frameStatusBar
= NULL
;
79 #endif // wxUSE_STATUSBAR
84 wxFrameBase::~wxFrameBase()
86 // this destructor is required for Darwin
89 wxFrame
*wxFrameBase::New(wxWindow
*parent
,
91 const wxString
& title
,
97 return new wxFrame(parent
, id
, title
, pos
, size
, style
, name
);
100 void wxFrameBase::DeleteAllBars()
103 if ( m_frameMenuBar
)
105 delete m_frameMenuBar
;
106 m_frameMenuBar
= (wxMenuBar
*) NULL
;
108 #endif // wxUSE_MENUS
111 if ( m_frameStatusBar
)
113 delete m_frameStatusBar
;
114 m_frameStatusBar
= (wxStatusBar
*) NULL
;
116 #endif // wxUSE_STATUSBAR
119 if ( m_frameToolBar
)
121 delete m_frameToolBar
;
122 m_frameToolBar
= (wxToolBar
*) NULL
;
124 #endif // wxUSE_TOOLBAR
127 bool wxFrameBase::IsOneOfBars(const wxWindow
*win
) const
130 if ( win
== GetMenuBar() )
132 #endif // wxUSE_MENUS
135 if ( win
== GetStatusBar() )
137 #endif // wxUSE_STATUSBAR
140 if ( win
== GetToolBar() )
142 #endif // wxUSE_TOOLBAR
147 // ----------------------------------------------------------------------------
148 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
149 // from the client area, so the client area is what's really available for the
151 // ----------------------------------------------------------------------------
153 // get the origin of the client area in the client coordinates
154 wxPoint
wxFrameBase::GetClientAreaOrigin() const
156 wxPoint pt
= wxTopLevelWindow::GetClientAreaOrigin();
158 #if wxUSE_TOOLBAR && !defined(__WXUNIVERSAL__) && \
159 (!defined(__WXWINCE__) || (_WIN32_WCE >= 400 && !defined(WIN32_PLATFORM_PSPC) && !defined(WIN32_PLATFORM_WFSP)))
160 wxToolBar
*toolbar
= GetToolBar();
161 if ( toolbar
&& toolbar
->IsShown() )
164 toolbar
->GetSize(&w
, &h
);
166 if ( toolbar
->GetWindowStyleFlag() & wxTB_VERTICAL
)
175 #endif // wxUSE_TOOLBAR
177 #if defined(__WXWINCE__) && defined(WCE_PLATFORM_STANDARDSDK)
178 if (GetMenuBar() && GetMenuBar()->GetCommandBar())
181 ::GetWindowRect((HWND
) GetMenuBar()->GetCommandBar(), &rect
);
182 pt
.y
+= (rect
.bottom
- rect
.top
);
189 // ----------------------------------------------------------------------------
191 // ----------------------------------------------------------------------------
193 bool wxFrameBase::ProcessCommand(int id
)
196 wxMenuBar
*bar
= GetMenuBar();
200 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, id
);
201 commandEvent
.SetEventObject(this);
203 wxMenuItem
*item
= bar
->FindItem(id
);
206 if (!item
->IsEnabled())
209 if (item
->IsCheckable())
214 commandEvent
.SetInt(item
->IsChecked());
218 GetEventHandler()->ProcessEvent(commandEvent
);
220 #else // !wxUSE_MENUS
222 #endif // wxUSE_MENUS/!wxUSE_MENUS
225 // Do the UI update processing for this window. This is
226 // provided for the application to call if it wants to
227 // force a UI update, particularly for the menus and toolbar.
228 void wxFrameBase::UpdateWindowUI(long flags
)
230 wxWindowBase::UpdateWindowUI(flags
);
234 GetToolBar()->UpdateWindowUI(flags
);
240 if ((flags
& wxUPDATE_UI_FROMIDLE
) && !wxUSE_IDLEMENUUPDATES
)
242 // If coming from an idle event, we only
243 // want to update the menus if we're
244 // in the wxUSE_IDLEMENUUPDATES configuration:
245 // so if we're not, do nothing
250 #endif // wxUSE_MENUS
253 // ----------------------------------------------------------------------------
254 // event handlers for status bar updates from menus
255 // ----------------------------------------------------------------------------
257 #if wxUSE_MENUS && wxUSE_STATUSBAR
259 void wxFrameBase::OnMenuHighlight(wxMenuEvent
& event
)
262 (void)ShowMenuHelp(GetStatusBar(), event
.GetMenuId());
263 #endif // wxUSE_STATUSBAR
266 #if !wxUSE_IDLEMENUUPDATES
267 void wxFrameBase::OnMenuOpen(wxMenuEvent
& event
)
269 void wxFrameBase::OnMenuOpen(wxMenuEvent
& WXUNUSED(event
))
272 #if !wxUSE_IDLEMENUUPDATES
273 DoMenuUpdates(event
.GetMenu());
274 #endif // !wxUSE_IDLEMENUUPDATES
277 void wxFrameBase::OnMenuClose(wxMenuEvent
& WXUNUSED(event
))
279 // do we have real status text to restore?
280 if ( m_oldStatusText
.length() > 1 || m_oldStatusText
[0u] )
282 if ( m_statusBarPane
>= 0 )
284 wxStatusBar
*statbar
= GetStatusBar();
286 statbar
->SetStatusText(m_oldStatusText
, m_statusBarPane
);
289 m_oldStatusText
.clear();
293 #endif // wxUSE_MENUS && wxUSE_STATUSBAR
295 // Implement internal behaviour (menu updating on some platforms)
296 void wxFrameBase::OnInternalIdle()
298 wxTopLevelWindow::OnInternalIdle();
300 #if wxUSE_MENUS && wxUSE_IDLEMENUUPDATES
301 if (wxUpdateUIEvent::CanUpdate(this))
306 // ----------------------------------------------------------------------------
308 // ----------------------------------------------------------------------------
312 wxStatusBar
* wxFrameBase::CreateStatusBar(int number
,
315 const wxString
& name
)
317 // the main status bar can only be created once (or else it should be
318 // deleted before calling CreateStatusBar() again)
319 wxCHECK_MSG( !m_frameStatusBar
, (wxStatusBar
*)NULL
,
320 wxT("recreating status bar in wxFrame") );
322 m_frameStatusBar
= OnCreateStatusBar( number
, style
, id
, name
);
323 if ( m_frameStatusBar
)
326 return m_frameStatusBar
;
329 wxStatusBar
*wxFrameBase::OnCreateStatusBar(int number
,
332 const wxString
& name
)
334 wxStatusBar
*statusBar
= new wxStatusBar(this, id
, style
, name
);
336 statusBar
->SetFieldsCount(number
);
341 void wxFrameBase::SetStatusText(const wxString
& text
, int number
)
343 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
345 m_frameStatusBar
->SetStatusText(text
, number
);
348 void wxFrameBase::SetStatusWidths(int n
, const int widths_field
[] )
350 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set widths for") );
352 m_frameStatusBar
->SetStatusWidths(n
, widths_field
);
357 void wxFrameBase::PushStatusText(const wxString
& text
, int number
)
359 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
361 m_frameStatusBar
->PushStatusText(text
, number
);
364 void wxFrameBase::PopStatusText(int number
)
366 wxCHECK_RET( m_frameStatusBar
!= NULL
, wxT("no statusbar to set text for") );
368 m_frameStatusBar
->PopStatusText(number
);
371 bool wxFrameBase::ShowMenuHelp(wxStatusBar
*WXUNUSED(statbar
), int menuId
)
374 // if no help string found, we will clear the status bar text
376 bool show
= menuId
!= wxID_SEPARATOR
&& menuId
!= -2 /* wxID_TITLE */;
380 wxMenuBar
*menuBar
= GetMenuBar();
383 // it's ok if we don't find the item because it might belong
385 wxMenuItem
*item
= menuBar
->FindItem(menuId
);
387 helpString
= item
->GetHelp();
391 DoGiveHelp(helpString
, show
);
393 return !helpString
.IsEmpty();
394 #else // !wxUSE_MENUS
396 #endif // wxUSE_MENUS/!wxUSE_MENUS
399 #endif // wxUSE_STATUSBAR
401 void wxFrameBase::DoGiveHelp(const wxString
& text
, bool show
)
404 if ( m_statusBarPane
< 0 )
406 // status bar messages disabled
410 wxStatusBar
*statbar
= GetStatusBar();
418 // remember the old status bar text if this is the first time we're called
419 // since the menu has been opened as we're going to overwrite it in our
420 // DoGiveHelp() and we want to restore it when the menu is closed
422 // note that it would be logical to do this in OnMenuOpen() but under MSW
423 // we get an EVT_MENU_HIGHLIGHT before EVT_MENU_OPEN, strangely enough, and
424 // so this doesn't work and instead we use the ugly trick with using
425 // special m_oldStatusText value as "menu opened" (but it is arguably
426 // better than adding yet another member variable to wxFrame on all
428 if ( m_oldStatusText
.empty() )
430 m_oldStatusText
= statbar
->GetStatusText(m_statusBarPane
);
431 if ( m_oldStatusText
.empty() )
433 // use special value to prevent us from doing this the next time
434 m_oldStatusText
+= _T('\0');
438 statbar
->SetStatusText(help
, m_statusBarPane
);
439 #endif // wxUSE_STATUSBAR
443 // ----------------------------------------------------------------------------
445 // ----------------------------------------------------------------------------
449 wxToolBar
* wxFrameBase::CreateToolBar(long style
,
451 const wxString
& name
)
453 // the main toolbar can't be recreated (unless it was explicitly deeleted
455 wxCHECK_MSG( !m_frameToolBar
, (wxToolBar
*)NULL
,
456 wxT("recreating toolbar in wxFrame") );
462 // NB: we don't specify the default value in the method declaration
464 // a) this allows us to have different defaults for different
465 // platforms (even if we don't have them right now)
466 // b) we don't need to include wx/toolbar.h in the header then
467 style
= wxBORDER_NONE
| wxTB_HORIZONTAL
| wxTB_FLAT
;
470 m_frameToolBar
= OnCreateToolBar(style
, id
, name
);
472 return m_frameToolBar
;
475 wxToolBar
* wxFrameBase::OnCreateToolBar(long style
,
477 const wxString
& name
)
479 return new wxToolBar(this, id
,
480 wxDefaultPosition
, wxDefaultSize
,
484 #endif // wxUSE_TOOLBAR
486 // ----------------------------------------------------------------------------
488 // ----------------------------------------------------------------------------
493 void wxFrameBase::DoMenuUpdates(wxMenu
* menu
)
495 wxEvtHandler
* source
= GetEventHandler();
496 wxMenuBar
* bar
= GetMenuBar();
499 menu
->UpdateUI(source
);
500 else if ( bar
!= NULL
)
502 int nCount
= bar
->GetMenuCount();
503 for (int n
= 0; n
< nCount
; n
++)
504 bar
->GetMenu(n
)->UpdateUI(source
);
508 void wxFrameBase::DetachMenuBar()
510 if ( m_frameMenuBar
)
512 m_frameMenuBar
->Detach();
513 m_frameMenuBar
= NULL
;
517 void wxFrameBase::AttachMenuBar(wxMenuBar
*menubar
)
521 menubar
->Attach((wxFrame
*)this);
522 m_frameMenuBar
= menubar
;
526 void wxFrameBase::SetMenuBar(wxMenuBar
*menubar
)
528 if ( menubar
== GetMenuBar() )
536 this->AttachMenuBar(menubar
);
539 #endif // wxUSE_MENUS