]> git.saurik.com Git - wxWidgets.git/blob - src/common/framecmn.cpp
ensure that GetItemRect() returns the real rect and not 0 even if it's called before...
[wxWidgets.git] / src / common / framecmn.cpp
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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
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
48 BEGIN_EVENT_TABLE(wxFrameBase, wxTopLevelWindow)
49 #if wxUSE_MENUS && !wxUSE_IDLEMENUUPDATES
50 EVT_MENU_OPEN(wxFrameBase::OnMenuOpen)
51 #endif
52 EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight)
53 END_EVENT_TABLE()
54
55 // ============================================================================
56 // implementation
57 // ============================================================================
58
59 // ----------------------------------------------------------------------------
60 // construction/destruction
61 // ----------------------------------------------------------------------------
62
63 wxFrameBase::wxFrameBase()
64 {
65 #if wxUSE_MENUS
66 m_frameMenuBar = NULL;
67 #endif // wxUSE_MENUS
68
69 #if wxUSE_TOOLBAR
70 m_frameToolBar = NULL;
71 #endif // wxUSE_TOOLBAR
72
73 #if wxUSE_STATUSBAR
74 m_frameStatusBar = NULL;
75 #endif // wxUSE_STATUSBAR
76
77 m_statusBarPane = 0;
78 }
79
80 wxFrameBase::~wxFrameBase()
81 {
82 // this destructor is required for Darwin
83 }
84
85 wxFrame *wxFrameBase::New(wxWindow *parent,
86 wxWindowID id,
87 const wxString& title,
88 const wxPoint& pos,
89 const wxSize& size,
90 long style,
91 const wxString& name)
92 {
93 return new wxFrame(parent, id, title, pos, size, style, name);
94 }
95
96 void wxFrameBase::DeleteAllBars()
97 {
98 #if wxUSE_MENUS
99 if ( m_frameMenuBar )
100 {
101 delete m_frameMenuBar;
102 m_frameMenuBar = (wxMenuBar *) NULL;
103 }
104 #endif // wxUSE_MENUS
105
106 #if wxUSE_STATUSBAR
107 if ( m_frameStatusBar )
108 {
109 delete m_frameStatusBar;
110 m_frameStatusBar = (wxStatusBar *) NULL;
111 }
112 #endif // wxUSE_STATUSBAR
113
114 #if wxUSE_TOOLBAR
115 if ( m_frameToolBar )
116 {
117 delete m_frameToolBar;
118 m_frameToolBar = (wxToolBar *) NULL;
119 }
120 #endif // wxUSE_TOOLBAR
121 }
122
123 bool wxFrameBase::IsOneOfBars(const wxWindow *win) const
124 {
125 #if wxUSE_MENUS
126 if ( win == GetMenuBar() )
127 return TRUE;
128 #endif // wxUSE_MENUS
129
130 #if wxUSE_STATUSBAR
131 if ( win == GetStatusBar() )
132 return TRUE;
133 #endif // wxUSE_STATUSBAR
134
135 #if wxUSE_TOOLBAR
136 if ( win == GetToolBar() )
137 return TRUE;
138 #endif // wxUSE_TOOLBAR
139
140 return FALSE;
141 }
142
143 // ----------------------------------------------------------------------------
144 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
145 // from the client area, so the client area is what's really available for the
146 // frame contents
147 // ----------------------------------------------------------------------------
148
149 // get the origin of the client area in the client coordinates
150 wxPoint wxFrameBase::GetClientAreaOrigin() const
151 {
152 wxPoint pt = wxTopLevelWindow::GetClientAreaOrigin();
153
154 #if wxUSE_TOOLBAR && !defined(__WXUNIVERSAL__) && !defined(__WXWINCE__)
155 wxToolBar *toolbar = GetToolBar();
156 if ( toolbar && toolbar->IsShown() )
157 {
158 int w, h;
159 toolbar->GetSize(&w, &h);
160
161 if ( toolbar->GetWindowStyleFlag() & wxTB_VERTICAL )
162 {
163 pt.x += w;
164 }
165 else
166 {
167 pt.y += h;
168 }
169 }
170 #endif // wxUSE_TOOLBAR
171
172 return pt;
173 }
174
175 // ----------------------------------------------------------------------------
176 // misc
177 // ----------------------------------------------------------------------------
178
179 bool wxFrameBase::ProcessCommand(int id)
180 {
181 #if wxUSE_MENUS
182 wxMenuBar *bar = GetMenuBar();
183 if ( !bar )
184 return FALSE;
185
186 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
187 commandEvent.SetEventObject(this);
188
189 wxMenuItem *item = bar->FindItem(id);
190 if (item)
191 {
192 if (!item->IsEnabled())
193 return TRUE;
194
195 if (item->IsCheckable())
196 {
197 item->Toggle();
198
199 // use the new value
200 commandEvent.SetInt(item->IsChecked());
201 }
202 }
203
204 GetEventHandler()->ProcessEvent(commandEvent);
205 return TRUE;
206 #else // !wxUSE_MENUS
207 return FALSE;
208 #endif // wxUSE_MENUS/!wxUSE_MENUS
209 }
210
211 // Do the UI update processing for this window. This is
212 // provided for the application to call if it wants to
213 // force a UI update, particularly for the menus and toolbar.
214 void wxFrameBase::UpdateWindowUI(long flags)
215 {
216 wxWindowBase::UpdateWindowUI(flags);
217
218 #if wxUSE_TOOLBAR
219 if (GetToolBar())
220 GetToolBar()->UpdateWindowUI(flags);
221 #endif
222
223 #if wxUSE_MENUS
224 if (GetMenuBar())
225 {
226 if ((flags & wxUPDATE_UI_FROMIDLE) && !wxUSE_IDLEMENUUPDATES)
227 {
228 // If coming from an idle event, we only
229 // want to update the menus if we're
230 // in the wxUSE_IDLEMENUUPDATES configuration:
231 // so if we're not, do nothing
232 }
233 else
234 DoMenuUpdates();
235 }
236 #endif
237 }
238
239 // ----------------------------------------------------------------------------
240 // event handlers
241 // ----------------------------------------------------------------------------
242
243 void wxFrameBase::OnMenuHighlight(wxMenuEvent& event)
244 {
245 #if wxUSE_STATUSBAR
246 (void)ShowMenuHelp(GetStatusBar(), event.GetMenuId());
247 #endif // wxUSE_STATUSBAR
248 }
249
250 // Implement internal behaviour (menu updating on some platforms)
251 void wxFrameBase::OnInternalIdle()
252 {
253 wxTopLevelWindow::OnInternalIdle();
254
255 #if wxUSE_MENUS && wxUSE_IDLEMENUUPDATES
256 if (wxUpdateUIEvent::CanUpdate(this))
257 DoMenuUpdates();
258 #endif
259 }
260
261 void wxFrameBase::OnMenuOpen(wxMenuEvent& event)
262 {
263 #if wxUSE_MENUS && !wxUSE_IDLEMENUUPDATES
264 DoMenuUpdates(event.GetMenu());
265 #endif
266 }
267
268 // ----------------------------------------------------------------------------
269 // status bar stuff
270 // ----------------------------------------------------------------------------
271
272 #if wxUSE_STATUSBAR
273
274 wxStatusBar* wxFrameBase::CreateStatusBar(int number,
275 long style,
276 wxWindowID id,
277 const wxString& name)
278 {
279 // the main status bar can only be created once (or else it should be
280 // deleted before calling CreateStatusBar() again)
281 wxCHECK_MSG( !m_frameStatusBar, (wxStatusBar *)NULL,
282 wxT("recreating status bar in wxFrame") );
283
284 m_frameStatusBar = OnCreateStatusBar( number, style, id, name );
285 if ( m_frameStatusBar )
286 PositionStatusBar();
287
288 return m_frameStatusBar;
289 }
290
291 wxStatusBar *wxFrameBase::OnCreateStatusBar(int number,
292 long style,
293 wxWindowID id,
294 const wxString& name)
295 {
296 wxStatusBar *statusBar = new wxStatusBar(this, id, style, name);
297
298 statusBar->SetFieldsCount(number);
299
300 return statusBar;
301 }
302
303 void wxFrameBase::SetStatusText(const wxString& text, int number)
304 {
305 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set text for") );
306
307 m_frameStatusBar->SetStatusText(text, number);
308 }
309
310 void wxFrameBase::SetStatusWidths(int n, const int widths_field[] )
311 {
312 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set widths for") );
313
314 m_frameStatusBar->SetStatusWidths(n, widths_field);
315
316 PositionStatusBar();
317 }
318
319 void wxFrameBase::PushStatusText(const wxString& text, int number)
320 {
321 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set text for") );
322
323 m_frameStatusBar->PushStatusText(text, number);
324 }
325
326 void wxFrameBase::PopStatusText(int number)
327 {
328 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set text for") );
329
330 m_frameStatusBar->PopStatusText(number);
331 }
332
333 bool wxFrameBase::ShowMenuHelp(wxStatusBar *WXUNUSED(statbar), int menuId)
334 {
335 #if wxUSE_MENUS
336 // if no help string found, we will clear the status bar text
337 wxString helpString;
338 bool show = menuId != wxID_SEPARATOR && menuId != -2 /* wxID_TITLE */;
339
340 if ( show )
341 {
342 wxMenuBar *menuBar = GetMenuBar();
343 if ( menuBar )
344 {
345 // it's ok if we don't find the item because it might belong
346 // to the popup menu
347 wxMenuItem *item = menuBar->FindItem(menuId);
348 if ( item )
349 helpString = item->GetHelp();
350 }
351 }
352
353 DoGiveHelp(helpString, show);
354
355 return !helpString.IsEmpty();
356 #else // !wxUSE_MENUS
357 return FALSE;
358 #endif // wxUSE_MENUS/!wxUSE_MENUS
359 }
360
361 #endif // wxUSE_STATUSBAR
362
363 void wxFrameBase::DoGiveHelp(const wxString& text, bool show)
364 {
365 #if wxUSE_STATUSBAR
366 if ( m_statusBarPane < 0 ) return;
367 wxStatusBar* statbar = GetStatusBar();
368 if ( !statbar ) return;
369
370 wxString help = show ? text : wxString();
371 statbar->SetStatusText( help, m_statusBarPane );
372 #endif // wxUSE_STATUSBAR
373 }
374
375
376 // ----------------------------------------------------------------------------
377 // toolbar stuff
378 // ----------------------------------------------------------------------------
379
380 #if wxUSE_TOOLBAR
381
382 wxToolBar* wxFrameBase::CreateToolBar(long style,
383 wxWindowID id,
384 const wxString& name)
385 {
386 // the main toolbar can't be recreated (unless it was explicitly deeleted
387 // before)
388 wxCHECK_MSG( !m_frameToolBar, (wxToolBar *)NULL,
389 wxT("recreating toolbar in wxFrame") );
390
391 if ( style == -1 )
392 {
393 // use default style
394 //
395 // NB: we don't specify the default value in the method declaration
396 // because
397 // a) this allows us to have different defaults for different
398 // platforms (even if we don't have them right now)
399 // b) we don't need to include wx/toolbar.h in the header then
400 style = wxBORDER_NONE | wxTB_HORIZONTAL | wxTB_FLAT;
401 }
402
403 m_frameToolBar = OnCreateToolBar(style, id, name);
404
405 return m_frameToolBar;
406 }
407
408 wxToolBar* wxFrameBase::OnCreateToolBar(long style,
409 wxWindowID id,
410 const wxString& name)
411 {
412 return new wxToolBar(this, id,
413 wxDefaultPosition, wxDefaultSize,
414 style, name);
415 }
416
417 #endif // wxUSE_TOOLBAR
418
419 // ----------------------------------------------------------------------------
420 // menus
421 // ----------------------------------------------------------------------------
422
423 #if wxUSE_MENUS
424
425 // update all menus
426 void wxFrameBase::DoMenuUpdates(wxMenu* menu)
427 {
428 wxEvtHandler* source = GetEventHandler();
429 wxMenuBar* bar = GetMenuBar();
430
431 if (menu)
432 menu->UpdateUI(source);
433 else if ( bar != NULL )
434 {
435 int nCount = bar->GetMenuCount();
436 for (int n = 0; n < nCount; n++)
437 bar->GetMenu(n)->UpdateUI(source);
438 }
439 }
440
441 void wxFrameBase::DetachMenuBar()
442 {
443 if ( m_frameMenuBar )
444 {
445 m_frameMenuBar->Detach();
446 m_frameMenuBar = NULL;
447 }
448 }
449
450 void wxFrameBase::AttachMenuBar(wxMenuBar *menubar)
451 {
452 if ( menubar )
453 {
454 menubar->Attach((wxFrame *)this);
455 m_frameMenuBar = menubar;
456 }
457 }
458
459 void wxFrameBase::SetMenuBar(wxMenuBar *menubar)
460 {
461 if ( menubar == GetMenuBar() )
462 {
463 // nothing to do
464 return;
465 }
466
467 DetachMenuBar();
468
469 AttachMenuBar(menubar);
470 }
471
472 #endif // wxUSE_MENUS