]> git.saurik.com Git - wxWidgets.git/blame - src/common/framecmn.cpp
made SetFirstItem() work again (patch 1445170)
[wxWidgets.git] / src / common / framecmn.cpp
CommitLineData
63fec618 1/////////////////////////////////////////////////////////////////////////////
7c0ea335 2// Name: common/framecmn.cpp
63fec618
VZ
3// Purpose: common (for all platforms) wxFrame functions
4// Author: Julian Smart, Vadim Zeitlin
5// Created: 01/02/97
439b3bf1 6// Id: $Id$
55d99c7a 7// Copyright: (c) 1998 Robert Roebling and Julian Smart
65571936 8// Licence: wxWindows licence
63fec618
VZ
9/////////////////////////////////////////////////////////////////////////////
10
7c0ea335
VZ
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
f701d7ab
JS
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
7c0ea335 23 #pragma hdrstop
f701d7ab
JS
24#endif
25
1e6feb95
VZ
26#ifndef WX_PRECOMP
27 #include "wx/frame.h"
28 #include "wx/menu.h"
29 #include "wx/menuitem.h"
30 #include "wx/dcclient.h"
31#endif // WX_PRECOMP
7c0ea335
VZ
32
33#if wxUSE_TOOLBAR
34 #include "wx/toolbar.h"
35#endif
36#if wxUSE_STATUSBAR
37 #include "wx/statusbr.h"
38#endif
39
40// ----------------------------------------------------------------------------
41// event table
42// ----------------------------------------------------------------------------
43
96ac065f
VZ
44#if wxUSE_MENUS && wxUSE_STATUSBAR
45
7d9f12f3 46BEGIN_EVENT_TABLE(wxFrameBase, wxTopLevelWindow)
0b30bb0b 47 EVT_MENU_OPEN(wxFrameBase::OnMenuOpen)
96ac065f
VZ
48 EVT_MENU_CLOSE(wxFrameBase::OnMenuClose)
49
7c0ea335 50 EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight)
7c0ea335
VZ
51END_EVENT_TABLE()
52
96ac065f
VZ
53#endif // wxUSE_MENUS && wxUSE_STATUSBAR
54
7c0ea335
VZ
55// ============================================================================
56// implementation
57// ============================================================================
58
59// ----------------------------------------------------------------------------
60// construction/destruction
61// ----------------------------------------------------------------------------
62
63wxFrameBase::wxFrameBase()
64{
1e6feb95 65#if wxUSE_MENUS
7c0ea335 66 m_frameMenuBar = NULL;
1e6feb95 67#endif // wxUSE_MENUS
7c0ea335
VZ
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
1f361cdd
MB
76
77 m_statusBarPane = 0;
7c0ea335
VZ
78}
79
799ea011
GD
80wxFrameBase::~wxFrameBase()
81{
82 // this destructor is required for Darwin
83}
84
7c0ea335
VZ
85wxFrame *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
96void wxFrameBase::DeleteAllBars()
97{
1e6feb95 98#if wxUSE_MENUS
7c0ea335
VZ
99 if ( m_frameMenuBar )
100 {
101 delete m_frameMenuBar;
102 m_frameMenuBar = (wxMenuBar *) NULL;
103 }
1e6feb95 104#endif // wxUSE_MENUS
7c0ea335
VZ
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
1e6feb95
VZ
123bool wxFrameBase::IsOneOfBars(const wxWindow *win) const
124{
125#if wxUSE_MENUS
126 if ( win == GetMenuBar() )
d1b20379 127 return true;
1e6feb95
VZ
128#endif // wxUSE_MENUS
129
130#if wxUSE_STATUSBAR
131 if ( win == GetStatusBar() )
d1b20379 132 return true;
1e6feb95
VZ
133#endif // wxUSE_STATUSBAR
134
135#if wxUSE_TOOLBAR
136 if ( win == GetToolBar() )
d1b20379 137 return true;
1e6feb95
VZ
138#endif // wxUSE_TOOLBAR
139
d1b20379 140 return false;
1e6feb95
VZ
141}
142
1c4f8f8d
VZ
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
150wxPoint wxFrameBase::GetClientAreaOrigin() const
151{
7d9f12f3 152 wxPoint pt = wxTopLevelWindow::GetClientAreaOrigin();
1c4f8f8d 153
a9928e9d 154#if wxUSE_TOOLBAR && !defined(__WXUNIVERSAL__)
d4597e13
VZ
155 wxToolBar *toolbar = GetToolBar();
156 if ( toolbar && toolbar->IsShown() )
1c4f8f8d
VZ
157 {
158 int w, h;
d4597e13 159 toolbar->GetSize(&w, &h);
1c4f8f8d 160
d4597e13 161 if ( toolbar->GetWindowStyleFlag() & wxTB_VERTICAL )
1c4f8f8d
VZ
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
2b022169
RD
175
176void wxFrameBase::SendSizeEvent()
177{
178 wxSizeEvent event( GetSize(), GetId() );
179 event.SetEventObject( this );
180 GetEventHandler()->AddPendingEvent( event );
181}
182
183
7c0ea335
VZ
184// ----------------------------------------------------------------------------
185// misc
186// ----------------------------------------------------------------------------
187
7c0ea335
VZ
188bool wxFrameBase::ProcessCommand(int id)
189{
1e6feb95 190#if wxUSE_MENUS
7c0ea335
VZ
191 wxMenuBar *bar = GetMenuBar();
192 if ( !bar )
d1b20379 193 return false;
7c0ea335 194
3ca6a5f0
BP
195 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
196 commandEvent.SetEventObject(this);
197
7c0ea335 198 wxMenuItem *item = bar->FindItem(id);
84f7908b 199 if (item)
7c0ea335 200 {
84f7908b 201 if (!item->IsEnabled())
d1b20379 202 return true;
d4597e13 203
26c36d75
WS
204 if ((item->GetKind() == wxITEM_RADIO) && item->IsChecked() )
205 return true;
206
84f7908b
RR
207 if (item->IsCheckable())
208 {
209 item->Toggle();
0472ece7 210
84f7908b
RR
211 // use the new value
212 commandEvent.SetInt(item->IsChecked());
213 }
3ca6a5f0 214 }
7c0ea335 215
a01fe3d6 216 GetEventHandler()->ProcessEvent(commandEvent);
d1b20379 217 return true;
1e6feb95 218#else // !wxUSE_MENUS
d1b20379 219 return false;
1e6feb95 220#endif // wxUSE_MENUS/!wxUSE_MENUS
7c0ea335
VZ
221}
222
e39af974
JS
223// Do the UI update processing for this window. This is
224// provided for the application to call if it wants to
225// force a UI update, particularly for the menus and toolbar.
226void wxFrameBase::UpdateWindowUI(long flags)
227{
228 wxWindowBase::UpdateWindowUI(flags);
a62848fd 229
e39af974
JS
230#if wxUSE_TOOLBAR
231 if (GetToolBar())
232 GetToolBar()->UpdateWindowUI(flags);
233#endif
234
235#if wxUSE_MENUS
236 if (GetMenuBar())
237 {
238 if ((flags & wxUPDATE_UI_FROMIDLE) && !wxUSE_IDLEMENUUPDATES)
239 {
240 // If coming from an idle event, we only
241 // want to update the menus if we're
242 // in the wxUSE_IDLEMENUUPDATES configuration:
243 // so if we're not, do nothing
244 }
245 else
246 DoMenuUpdates();
247 }
96ac065f 248#endif // wxUSE_MENUS
e39af974
JS
249}
250
7c0ea335 251// ----------------------------------------------------------------------------
96ac065f 252// event handlers for status bar updates from menus
7c0ea335
VZ
253// ----------------------------------------------------------------------------
254
96ac065f
VZ
255#if wxUSE_MENUS && wxUSE_STATUSBAR
256
7c0ea335
VZ
257void wxFrameBase::OnMenuHighlight(wxMenuEvent& event)
258{
259#if wxUSE_STATUSBAR
f6bcfd97 260 (void)ShowMenuHelp(GetStatusBar(), event.GetMenuId());
7c0ea335
VZ
261#endif // wxUSE_STATUSBAR
262}
263
d1b20379 264#if !wxUSE_IDLEMENUUPDATES
96ac065f 265void wxFrameBase::OnMenuOpen(wxMenuEvent& event)
d1b20379
DS
266#else
267void wxFrameBase::OnMenuOpen(wxMenuEvent& WXUNUSED(event))
268#endif
96ac065f
VZ
269{
270#if !wxUSE_IDLEMENUUPDATES
271 DoMenuUpdates(event.GetMenu());
272#endif // !wxUSE_IDLEMENUUPDATES
273}
274
275void wxFrameBase::OnMenuClose(wxMenuEvent& WXUNUSED(event))
276{
277 // do we have real status text to restore?
adbc621d 278 if ( !m_oldStatusText.empty() )
96ac065f
VZ
279 {
280 if ( m_statusBarPane >= 0 )
281 {
282 wxStatusBar *statbar = GetStatusBar();
283 if ( statbar )
284 statbar->SetStatusText(m_oldStatusText, m_statusBarPane);
285 }
286
287 m_oldStatusText.clear();
288 }
289}
290
291#endif // wxUSE_MENUS && wxUSE_STATUSBAR
292
e39af974
JS
293// Implement internal behaviour (menu updating on some platforms)
294void wxFrameBase::OnInternalIdle()
6522713c 295{
e2b6d07d 296 wxTopLevelWindow::OnInternalIdle();
a62848fd 297
0b30bb0b 298#if wxUSE_MENUS && wxUSE_IDLEMENUUPDATES
e39af974 299 if (wxUpdateUIEvent::CanUpdate(this))
0b30bb0b
JS
300 DoMenuUpdates();
301#endif
302}
303
7c0ea335
VZ
304// ----------------------------------------------------------------------------
305// status bar stuff
306// ----------------------------------------------------------------------------
307
308#if wxUSE_STATUSBAR
309
310wxStatusBar* wxFrameBase::CreateStatusBar(int number,
311 long style,
312 wxWindowID id,
313 const wxString& name)
314{
315 // the main status bar can only be created once (or else it should be
316 // deleted before calling CreateStatusBar() again)
317 wxCHECK_MSG( !m_frameStatusBar, (wxStatusBar *)NULL,
318 wxT("recreating status bar in wxFrame") );
319
a4f01f05 320 SetStatusBar(OnCreateStatusBar(number, style, id, name));
7c0ea335
VZ
321
322 return m_frameStatusBar;
323}
324
325wxStatusBar *wxFrameBase::OnCreateStatusBar(int number,
326 long style,
327 wxWindowID id,
328 const wxString& name)
329{
ed791986 330 wxStatusBar *statusBar = new wxStatusBar(this, id, style, name);
7c0ea335 331
7c0ea335
VZ
332 statusBar->SetFieldsCount(number);
333
334 return statusBar;
335}
336
337void wxFrameBase::SetStatusText(const wxString& text, int number)
338{
7c0ea335
VZ
339 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set text for") );
340
341 m_frameStatusBar->SetStatusText(text, number);
342}
343
344void wxFrameBase::SetStatusWidths(int n, const int widths_field[] )
345{
7c0ea335
VZ
346 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set widths for") );
347
348 m_frameStatusBar->SetStatusWidths(n, widths_field);
349
350 PositionStatusBar();
351}
352
1f361cdd 353void wxFrameBase::PushStatusText(const wxString& text, int number)
f6bcfd97 354{
1f361cdd
MB
355 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set text for") );
356
357 m_frameStatusBar->PushStatusText(text, number);
358}
f6bcfd97 359
1f361cdd
MB
360void wxFrameBase::PopStatusText(int number)
361{
362 wxCHECK_RET( m_frameStatusBar != NULL, wxT("no statusbar to set text for") );
363
364 m_frameStatusBar->PopStatusText(number);
365}
366
1f361cdd
MB
367bool wxFrameBase::ShowMenuHelp(wxStatusBar *WXUNUSED(statbar), int menuId)
368{
369#if wxUSE_MENUS
f6bcfd97
BP
370 // if no help string found, we will clear the status bar text
371 wxString helpString;
1f361cdd 372 bool show = menuId != wxID_SEPARATOR && menuId != -2 /* wxID_TITLE */;
f6bcfd97 373
1f361cdd 374 if ( show )
f6bcfd97
BP
375 {
376 wxMenuBar *menuBar = GetMenuBar();
377 if ( menuBar )
378 {
379 // it's ok if we don't find the item because it might belong
380 // to the popup menu
381 wxMenuItem *item = menuBar->FindItem(menuId);
382 if ( item )
383 helpString = item->GetHelp();
384 }
385 }
386
1f361cdd 387 DoGiveHelp(helpString, show);
f6bcfd97 388
1729813a 389 return !helpString.empty();
3379ed37 390#else // !wxUSE_MENUS
d1b20379 391 return false;
3379ed37 392#endif // wxUSE_MENUS/!wxUSE_MENUS
f6bcfd97
BP
393}
394
a4f01f05
VZ
395void wxFrameBase::SetStatusBar(wxStatusBar *statBar)
396{
397 bool hadBar = m_frameStatusBar != NULL;
398 m_frameStatusBar = statBar;
399
400 if ( (m_frameStatusBar != NULL) != hadBar )
401 {
402 PositionStatusBar();
403
404 DoLayout();
405 }
406}
407
7c0ea335
VZ
408#endif // wxUSE_STATUSBAR
409
c60a36d5
VZ
410void wxFrameBase::DoGiveHelp(const wxString& text, bool show)
411{
412#if wxUSE_STATUSBAR
96ac065f
VZ
413 if ( m_statusBarPane < 0 )
414 {
415 // status bar messages disabled
416 return;
417 }
418
419 wxStatusBar *statbar = GetStatusBar();
420 if ( !statbar )
421 return;
422
423 wxString help;
424 if ( show )
425 help = text;
426
427 // remember the old status bar text if this is the first time we're called
428 // since the menu has been opened as we're going to overwrite it in our
429 // DoGiveHelp() and we want to restore it when the menu is closed
430 //
431 // note that it would be logical to do this in OnMenuOpen() but under MSW
432 // we get an EVT_MENU_HIGHLIGHT before EVT_MENU_OPEN, strangely enough, and
433 // so this doesn't work and instead we use the ugly trick with using
434 // special m_oldStatusText value as "menu opened" (but it is arguably
435 // better than adding yet another member variable to wxFrame on all
436 // platforms)
437 if ( m_oldStatusText.empty() )
438 {
439 m_oldStatusText = statbar->GetStatusText(m_statusBarPane);
440 if ( m_oldStatusText.empty() )
441 {
442 // use special value to prevent us from doing this the next time
443 m_oldStatusText += _T('\0');
444 }
445 }
c60a36d5 446
96ac065f 447 statbar->SetStatusText(help, m_statusBarPane);
f428e6c5
WS
448#else
449 wxUnusedVar(text);
450 wxUnusedVar(show);
c60a36d5
VZ
451#endif // wxUSE_STATUSBAR
452}
453
454
7c0ea335
VZ
455// ----------------------------------------------------------------------------
456// toolbar stuff
457// ----------------------------------------------------------------------------
458
459#if wxUSE_TOOLBAR
460
461wxToolBar* wxFrameBase::CreateToolBar(long style,
462 wxWindowID id,
463 const wxString& name)
464{
465 // the main toolbar can't be recreated (unless it was explicitly deeleted
466 // before)
467 wxCHECK_MSG( !m_frameToolBar, (wxToolBar *)NULL,
468 wxT("recreating toolbar in wxFrame") );
469
f9dae779
VZ
470 if ( style == -1 )
471 {
472 // use default style
473 //
474 // NB: we don't specify the default value in the method declaration
475 // because
476 // a) this allows us to have different defaults for different
477 // platforms (even if we don't have them right now)
478 // b) we don't need to include wx/toolbar.h in the header then
479 style = wxBORDER_NONE | wxTB_HORIZONTAL | wxTB_FLAT;
480 }
481
a4f01f05 482 SetToolBar(OnCreateToolBar(style, id, name));
7c0ea335
VZ
483
484 return m_frameToolBar;
485}
486
487wxToolBar* wxFrameBase::OnCreateToolBar(long style,
488 wxWindowID id,
489 const wxString& name)
490{
a9102b36
JS
491#if defined(__WXWINCE__) && defined(__POCKETPC__)
492 return new wxToolMenuBar(this, id,
493 wxDefaultPosition, wxDefaultSize,
494 style, name);
495#else
7c0ea335
VZ
496 return new wxToolBar(this, id,
497 wxDefaultPosition, wxDefaultSize,
498 style, name);
a9102b36 499#endif
7c0ea335
VZ
500}
501
a4f01f05
VZ
502void wxFrameBase::SetToolBar(wxToolBar *toolbar)
503{
504 bool hadBar = m_frameToolBar != NULL;
505 m_frameToolBar = toolbar;
506
507 if ( (m_frameToolBar != NULL) != hadBar )
508 {
509 PositionToolBar();
510
511 DoLayout();
512 }
513}
514
7c0ea335
VZ
515#endif // wxUSE_TOOLBAR
516
517// ----------------------------------------------------------------------------
6522713c 518// menus
7c0ea335
VZ
519// ----------------------------------------------------------------------------
520
1e6feb95
VZ
521#if wxUSE_MENUS
522
63fec618 523// update all menus
92f1a59c 524void wxFrameBase::DoMenuUpdates(wxMenu* menu)
63fec618 525{
92f1a59c 526 if (menu)
4d538595
DS
527 {
528 wxEvtHandler* source = GetEventHandler();
92f1a59c 529 menu->UpdateUI(source);
4d538595
DS
530 }
531 else
54517652 532 {
4d538595
DS
533 wxMenuBar* bar = GetMenuBar();
534 if (bar != NULL)
535 bar->UpdateMenus();
63fec618 536 }
63fec618 537}
1e6feb95 538
6522713c
VZ
539void wxFrameBase::DetachMenuBar()
540{
541 if ( m_frameMenuBar )
542 {
543 m_frameMenuBar->Detach();
544 m_frameMenuBar = NULL;
545 }
546}
547
548void wxFrameBase::AttachMenuBar(wxMenuBar *menubar)
549{
550 if ( menubar )
551 {
6522713c 552 menubar->Attach((wxFrame *)this);
3dbe38c3 553 m_frameMenuBar = menubar;
6522713c
VZ
554 }
555}
556
557void wxFrameBase::SetMenuBar(wxMenuBar *menubar)
558{
559 if ( menubar == GetMenuBar() )
560 {
561 // nothing to do
562 return;
563 }
564
565 DetachMenuBar();
566
a96b4743 567 this->AttachMenuBar(menubar);
6522713c
VZ
568}
569
1e6feb95 570#endif // wxUSE_MENUS