]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/framecmn.cpp
Allow for multiple CHM controllers in app (don't leak dynamic libs)
[wxWidgets.git] / src / common / framecmn.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: common/framecmn.cpp
3// Purpose: common (for all platforms) wxFrame functions
4// Author: Julian Smart, Vadim Zeitlin
5// Created: 01/02/97
6// Id: $Id$
7// Copyright: (c) 1998 Robert Roebling and Julian Smart
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19#ifdef __GNUG__
20 #pragma implementation "framebase.h"
21#endif
22
23// For compilers that support precompilation, includes "wx.h".
24#include "wx/wxprec.h"
25
26#ifdef __BORLANDC__
27 #pragma hdrstop
28#endif
29
30#ifndef WX_PRECOMP
31 #include "wx/frame.h"
32 #include "wx/menu.h"
33 #include "wx/menuitem.h"
34 #include "wx/dcclient.h"
35#endif // WX_PRECOMP
36
37#if wxUSE_TOOLBAR
38 #include "wx/toolbar.h"
39#endif
40#if wxUSE_STATUSBAR
41 #include "wx/statusbr.h"
42#endif
43
44// ----------------------------------------------------------------------------
45// event table
46// ----------------------------------------------------------------------------
47
48BEGIN_EVENT_TABLE(wxFrameBase, wxTopLevelWindow)
49 EVT_IDLE(wxFrameBase::OnIdle)
50 EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight)
51END_EVENT_TABLE()
52
53// ============================================================================
54// implementation
55// ============================================================================
56
57// ----------------------------------------------------------------------------
58// construction/destruction
59// ----------------------------------------------------------------------------
60
61wxFrameBase::wxFrameBase()
62{
63#if wxUSE_MENUS
64 m_frameMenuBar = NULL;
65#endif // wxUSE_MENUS
66
67#if wxUSE_TOOLBAR
68 m_frameToolBar = NULL;
69#endif // wxUSE_TOOLBAR
70
71#if wxUSE_STATUSBAR
72 m_frameStatusBar = NULL;
73#endif // wxUSE_STATUSBAR
74
75 m_statusBarPane = 0;
76}
77
78wxFrameBase::~wxFrameBase()
79{
80 // this destructor is required for Darwin
81}
82
83wxFrame *wxFrameBase::New(wxWindow *parent,
84 wxWindowID id,
85 const wxString& title,
86 const wxPoint& pos,
87 const wxSize& size,
88 long style,
89 const wxString& name)
90{
91 return new wxFrame(parent, id, title, pos, size, style, name);
92}
93
94void wxFrameBase::DeleteAllBars()
95{
96#if wxUSE_MENUS
97 if ( m_frameMenuBar )
98 {
99 delete m_frameMenuBar;
100 m_frameMenuBar = (wxMenuBar *) NULL;
101 }
102#endif // wxUSE_MENUS
103
104#if wxUSE_STATUSBAR
105 if ( m_frameStatusBar )
106 {
107 delete m_frameStatusBar;
108 m_frameStatusBar = (wxStatusBar *) NULL;
109 }
110#endif // wxUSE_STATUSBAR
111
112#if wxUSE_TOOLBAR
113 if ( m_frameToolBar )
114 {
115 delete m_frameToolBar;
116 m_frameToolBar = (wxToolBar *) NULL;
117 }
118#endif // wxUSE_TOOLBAR
119}
120
121bool wxFrameBase::IsOneOfBars(const wxWindow *win) const
122{
123#if wxUSE_MENUS
124 if ( win == GetMenuBar() )
125 return TRUE;
126#endif // wxUSE_MENUS
127
128#if wxUSE_STATUSBAR
129 if ( win == GetStatusBar() )
130 return TRUE;
131#endif // wxUSE_STATUSBAR
132
133#if wxUSE_TOOLBAR
134 if ( win == GetToolBar() )
135 return TRUE;
136#endif // wxUSE_TOOLBAR
137
138 return FALSE;
139}
140
141// ----------------------------------------------------------------------------
142// wxFrame size management: we exclude the areas taken by menu/status/toolbars
143// from the client area, so the client area is what's really available for the
144// frame contents
145// ----------------------------------------------------------------------------
146
147// get the origin of the client area in the client coordinates
148wxPoint wxFrameBase::GetClientAreaOrigin() const
149{
150 wxPoint pt = wxTopLevelWindow::GetClientAreaOrigin();
151
152#if wxUSE_TOOLBAR && !defined(__WXUNIVERSAL__)
153 wxToolBar *toolbar = GetToolBar();
154 if ( toolbar && toolbar->IsShown() )
155 {
156 int w, h;
157 toolbar->GetSize(&w, &h);
158
159 if ( toolbar->GetWindowStyleFlag() & wxTB_VERTICAL )
160 {
161 pt.x += w;
162 }
163 else
164 {
165 pt.y += h;
166 }
167 }
168#endif // wxUSE_TOOLBAR
169
170 return pt;
171}
172
173// ----------------------------------------------------------------------------
174// misc
175// ----------------------------------------------------------------------------
176
177bool wxFrameBase::ProcessCommand(int id)
178{
179#if wxUSE_MENUS
180 wxMenuBar *bar = GetMenuBar();
181 if ( !bar )
182 return FALSE;
183
184 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
185 commandEvent.SetEventObject(this);
186
187 wxMenuItem *item = bar->FindItem(id);
188 if (item)
189 {
190 if (!item->IsEnabled())
191 return TRUE;
192
193 if (item->IsCheckable())
194 {
195 item->Toggle();
196
197 // use the new value
198 commandEvent.SetInt(item->IsChecked());
199 }
200 }
201
202 GetEventHandler()->ProcessEvent(commandEvent);
203 return TRUE;
204#else // !wxUSE_MENUS
205 return FALSE;
206#endif // wxUSE_MENUS/!wxUSE_MENUS
207}
208
209// ----------------------------------------------------------------------------
210// event handlers
211// ----------------------------------------------------------------------------
212
213void wxFrameBase::OnMenuHighlight(wxMenuEvent& event)
214{
215#if wxUSE_STATUSBAR
216 (void)ShowMenuHelp(GetStatusBar(), event.GetMenuId());
217#endif // wxUSE_STATUSBAR
218}
219
220void wxFrameBase::OnIdle(wxIdleEvent& WXUNUSED(event) )
221{
222#if wxUSE_MENUS
223 DoMenuUpdates();
224#endif // wxUSE_MENUS
225}
226
227// ----------------------------------------------------------------------------
228// status bar stuff
229// ----------------------------------------------------------------------------
230
231#if wxUSE_STATUSBAR
232
233wxStatusBar* wxFrameBase::CreateStatusBar(int number,
234 long style,
235 wxWindowID id,
236 const wxString& name)
237{
238 // the main status bar can only be created once (or else it should be
239 // deleted before calling CreateStatusBar() again)
240 wxCHECK_MSG( !m_frameStatusBar, (wxStatusBar *)NULL,
241 wxT("recreating status bar in wxFrame") );
242
243 m_frameStatusBar = OnCreateStatusBar( number, style, id, name );
244 if ( m_frameStatusBar )
245 PositionStatusBar();
246
247 return m_frameStatusBar;
248}
249
250wxStatusBar *wxFrameBase::OnCreateStatusBar(int number,
251 long style,
252 wxWindowID id,
253 const wxString& name)
254{
255 wxStatusBar *statusBar = new wxStatusBar(this, id, style, name);
256
257 statusBar->SetFieldsCount(number);
258
259 return statusBar;
260}
261
262void wxFrameBase::SetStatusText(const wxString& text, int number)
263{
264 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set text for") );
265
266 m_frameStatusBar->SetStatusText(text, number);
267}
268
269void wxFrameBase::SetStatusWidths(int n, const int widths_field[] )
270{
271 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set widths for") );
272
273 m_frameStatusBar->SetStatusWidths(n, widths_field);
274
275 PositionStatusBar();
276}
277
278void wxFrameBase::PushStatusText(const wxString& text, int number)
279{
280 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set text for") );
281
282 m_frameStatusBar->PushStatusText(text, number);
283}
284
285void wxFrameBase::PopStatusText(int number)
286{
287 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set text for") );
288
289 m_frameStatusBar->PopStatusText(number);
290}
291
292bool wxFrameBase::ShowMenuHelp(wxStatusBar *WXUNUSED(statbar), int menuId)
293{
294#if wxUSE_MENUS
295 // if no help string found, we will clear the status bar text
296 wxString helpString;
297 bool show = menuId != wxID_SEPARATOR && menuId != -2 /* wxID_TITLE */;
298
299 if ( show )
300 {
301 wxMenuBar *menuBar = GetMenuBar();
302 if ( menuBar )
303 {
304 // it's ok if we don't find the item because it might belong
305 // to the popup menu
306 wxMenuItem *item = menuBar->FindItem(menuId);
307 if ( item )
308 helpString = item->GetHelp();
309 }
310 }
311
312 DoGiveHelp(helpString, show);
313
314 return !helpString.IsEmpty();
315#else // !wxUSE_MENUS
316 return FALSE;
317#endif // wxUSE_MENUS/!wxUSE_MENUS
318}
319
320#endif // wxUSE_STATUSBAR
321
322void wxFrameBase::DoGiveHelp(const wxString& text, bool show)
323{
324#if wxUSE_STATUSBAR
325 if ( m_statusBarPane < 0 ) return;
326 wxStatusBar* statbar = GetStatusBar();
327 if ( !statbar ) return;
328
329 wxString help = show ? text : wxString();
330 statbar->SetStatusText( help, m_statusBarPane );
331#endif // wxUSE_STATUSBAR
332}
333
334
335// ----------------------------------------------------------------------------
336// toolbar stuff
337// ----------------------------------------------------------------------------
338
339#if wxUSE_TOOLBAR
340
341wxToolBar* wxFrameBase::CreateToolBar(long style,
342 wxWindowID id,
343 const wxString& name)
344{
345 // the main toolbar can't be recreated (unless it was explicitly deeleted
346 // before)
347 wxCHECK_MSG( !m_frameToolBar, (wxToolBar *)NULL,
348 wxT("recreating toolbar in wxFrame") );
349
350 m_frameToolBar = OnCreateToolBar(style, id, name);
351
352 return m_frameToolBar;
353}
354
355wxToolBar* wxFrameBase::OnCreateToolBar(long style,
356 wxWindowID id,
357 const wxString& name)
358{
359 return new wxToolBar(this, id,
360 wxDefaultPosition, wxDefaultSize,
361 style, name);
362}
363
364#endif // wxUSE_TOOLBAR
365
366// ----------------------------------------------------------------------------
367// menus
368// ----------------------------------------------------------------------------
369
370#if wxUSE_MENUS
371
372// update all menus
373void wxFrameBase::DoMenuUpdates()
374{
375 wxMenuBar* bar = GetMenuBar();
376
377#ifdef __WXMSW__
378 wxWindow* focusWin = wxFindFocusDescendant((wxWindow*) this);
379#else
380 wxWindow* focusWin = (wxWindow*) NULL;
381#endif
382 if ( bar != NULL )
383 {
384 int nCount = bar->GetMenuCount();
385 for (int n = 0; n < nCount; n++)
386 DoMenuUpdates(bar->GetMenu(n), focusWin);
387 }
388}
389
390// update a menu and all submenus recursively
391void wxFrameBase::DoMenuUpdates(wxMenu* menu, wxWindow* focusWin)
392{
393 wxEvtHandler* evtHandler = focusWin ? focusWin->GetEventHandler() : GetEventHandler();
394 wxMenuItemList::Node* node = menu->GetMenuItems().GetFirst();
395 while (node)
396 {
397 wxMenuItem* item = node->GetData();
398 if ( !item->IsSeparator() )
399 {
400 wxWindowID id = item->GetId();
401 wxUpdateUIEvent event(id);
402 event.SetEventObject( this );
403
404 if (evtHandler->ProcessEvent(event))
405 {
406 if (event.GetSetText())
407 menu->SetLabel(id, event.GetText());
408 if (event.GetSetChecked())
409 menu->Check(id, event.GetChecked());
410 if (event.GetSetEnabled())
411 menu->Enable(id, event.GetEnabled());
412 }
413
414 if (item->GetSubMenu())
415 DoMenuUpdates(item->GetSubMenu(), focusWin);
416 }
417 node = node->GetNext();
418 }
419}
420
421void wxFrameBase::DetachMenuBar()
422{
423 if ( m_frameMenuBar )
424 {
425 m_frameMenuBar->Detach();
426 m_frameMenuBar = NULL;
427 }
428}
429
430void wxFrameBase::AttachMenuBar(wxMenuBar *menubar)
431{
432 if ( menubar )
433 {
434 menubar->Attach((wxFrame *)this);
435 m_frameMenuBar = menubar;
436 }
437}
438
439void wxFrameBase::SetMenuBar(wxMenuBar *menubar)
440{
441 if ( menubar == GetMenuBar() )
442 {
443 // nothing to do
444 return;
445 }
446
447 DetachMenuBar();
448
449 AttachMenuBar(menubar);
450}
451
452#endif // wxUSE_MENUS