]> git.saurik.com Git - wxWidgets.git/blame - src/common/framecmn.cpp
Mingw32 fixes
[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$
63fec618
VZ
7// Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
7c0ea335
VZ
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19#ifdef __GNUG__
20 #pragma implementation "framebase.h"
21#endif
22
f701d7ab
JS
23// For compilers that support precompilation, includes "wx.h".
24#include "wx/wxprec.h"
25
26#ifdef __BORLANDC__
7c0ea335 27 #pragma hdrstop
f701d7ab
JS
28#endif
29
439b3bf1 30#include "wx/frame.h"
f701d7ab 31#include "wx/menu.h"
e52f60e6 32#include "wx/menuitem.h"
7c0ea335
VZ
33#include "wx/dcclient.h"
34
35#if wxUSE_TOOLBAR
36 #include "wx/toolbar.h"
37#endif
38#if wxUSE_STATUSBAR
39 #include "wx/statusbr.h"
40#endif
41
42// ----------------------------------------------------------------------------
43// event table
44// ----------------------------------------------------------------------------
45
46BEGIN_EVENT_TABLE(wxFrameBase, wxWindow)
47 EVT_IDLE(wxFrameBase::OnIdle)
48 EVT_CLOSE(wxFrameBase::OnCloseWindow)
49 EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight)
50 EVT_SIZE(wxFrameBase::OnSize)
51END_EVENT_TABLE()
52
53// ============================================================================
54// implementation
55// ============================================================================
56
57// ----------------------------------------------------------------------------
58// construction/destruction
59// ----------------------------------------------------------------------------
60
61wxFrameBase::wxFrameBase()
62{
63 m_frameMenuBar = NULL;
64
65#if wxUSE_TOOLBAR
66 m_frameToolBar = NULL;
67#endif // wxUSE_TOOLBAR
68
69#if wxUSE_STATUSBAR
70 m_frameStatusBar = NULL;
71#endif // wxUSE_STATUSBAR
72}
73
74bool wxFrameBase::Destroy()
75{
76 // delayed destruction: the frame will be deleted during the next idle
77 // loop iteration
78 if ( !wxPendingDelete.Member(this) )
79 wxPendingDelete.Append(this);
80
81 return TRUE;
82}
83
84wxFrame *wxFrameBase::New(wxWindow *parent,
85 wxWindowID id,
86 const wxString& title,
87 const wxPoint& pos,
88 const wxSize& size,
89 long style,
90 const wxString& name)
91{
92 return new wxFrame(parent, id, title, pos, size, style, name);
93}
94
95void wxFrameBase::DeleteAllBars()
96{
97 if ( m_frameMenuBar )
98 {
99 delete m_frameMenuBar;
100 m_frameMenuBar = (wxMenuBar *) NULL;
101 }
102
103#if wxUSE_STATUSBAR
104 if ( m_frameStatusBar )
105 {
106 delete m_frameStatusBar;
107 m_frameStatusBar = (wxStatusBar *) NULL;
108 }
109#endif // wxUSE_STATUSBAR
110
111#if wxUSE_TOOLBAR
112 if ( m_frameToolBar )
113 {
114 delete m_frameToolBar;
115 m_frameToolBar = (wxToolBar *) NULL;
116 }
117#endif // wxUSE_TOOLBAR
118}
119
1c4f8f8d
VZ
120// ----------------------------------------------------------------------------
121// wxFrame size management: we exclude the areas taken by menu/status/toolbars
122// from the client area, so the client area is what's really available for the
123// frame contents
124// ----------------------------------------------------------------------------
125
126// get the origin of the client area in the client coordinates
127wxPoint wxFrameBase::GetClientAreaOrigin() const
128{
129 wxPoint pt(0, 0);
130
131#if wxUSE_TOOLBAR
3e0b743f 132 if ( GetToolBar() && GetToolBar()->IsShown() )
1c4f8f8d
VZ
133 {
134 int w, h;
135 GetToolBar()->GetSize(& w, & h);
136
137 if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL )
138 {
139 pt.x += w;
140 }
141 else
142 {
143 pt.y += h;
144 }
145 }
146#endif // wxUSE_TOOLBAR
147
148 return pt;
149}
150
151void wxFrameBase::DoScreenToClient(int *x, int *y) const
152{
153 wxWindow::DoScreenToClient(x, y);
154
155 // We may be faking the client origin.
156 // So a window that's really at (0, 30) may appear
157 // (to wxWin apps) to be at (0, 0).
158 wxPoint pt(GetClientAreaOrigin());
159 *x -= pt.x;
160 *y -= pt.y;
161}
162
163void wxFrameBase::DoClientToScreen(int *x, int *y) const
164{
165 // We may be faking the client origin.
166 // So a window that's really at (0, 30) may appear
167 // (to wxWin apps) to be at (0, 0).
168 wxPoint pt1(GetClientAreaOrigin());
169 *x += pt1.x;
170 *y += pt1.y;
171
172 wxWindow::DoClientToScreen(x, y);
173}
174
7c0ea335
VZ
175// ----------------------------------------------------------------------------
176// misc
177// ----------------------------------------------------------------------------
178
179// make the window modal (all other windows unresponsive)
180void wxFrameBase::MakeModal(bool modal)
181{
182 if ( modal )
183 {
184 wxEnableTopLevelWindows(FALSE);
185 Enable(TRUE); // keep this window enabled
186 }
187 else
188 {
189 wxEnableTopLevelWindows(TRUE);
190 }
191}
192
193bool wxFrameBase::ProcessCommand(int id)
194{
195 wxMenuBar *bar = GetMenuBar();
196 if ( !bar )
197 return FALSE;
198
199 wxMenuItem *item = bar->FindItem(id);
200 if ( item && item->IsCheckable() )
201 {
202 item->Toggle();
203 }
204
205 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
206 commandEvent.SetInt(id);
207 commandEvent.SetEventObject(this);
208
209 return GetEventHandler()->ProcessEvent(commandEvent);
210}
211
212// ----------------------------------------------------------------------------
213// event handlers
214// ----------------------------------------------------------------------------
215
216// default resizing behaviour - if only ONE subwindow, resize to fill the
217// whole client area
3ed2e7ce 218void wxFrameBase::OnSize(wxSizeEvent& WXUNUSED(event))
7c0ea335
VZ
219{
220 // if we're using constraints - do use them
221#if wxUSE_CONSTRAINTS
222 if ( GetAutoLayout() )
223 {
224 Layout();
225 }
226 else
227#endif
228 {
229 // do we have _exactly_ one child?
230 wxWindow *child = (wxWindow *)NULL;
231 for ( wxWindowList::Node *node = GetChildren().GetFirst();
232 node;
233 node = node->GetNext() )
234 {
235 wxWindow *win = node->GetData();
236
237 // exclude top level and managed windows (status bar isn't
238 // currently in the children list except under wxMac anyhow, but
239 // it makes no harm to test for it)
240 if ( !win->IsTopLevel()
241#if wxUSE_STATUSBAR
242 && (win != GetStatusBar())
243#endif // wxUSE_STATUSBAR
244#if wxUSE_TOOLBAR
245 && (win != GetToolBar())
246#endif // wxUSE_TOOLBAR
247 )
248 {
249 if ( child )
250 {
251 return; // it's our second subwindow - nothing to do
252 }
253
254 child = win;
255 }
256 }
e6688c3f 257
7c0ea335
VZ
258 // do we have any children at all?
259 if ( child )
260 {
261 // exactly one child - set it's size to fill the whole frame
262 int clientW, clientH;
263 DoGetClientSize(&clientW, &clientH);
264
265 // for whatever reasons, wxGTK wants to have a small offset - it
266 // probably looks better with it?
267#ifdef __WXGTK__
7c0ea335 268 static const int ofs = 1;
405e126c
VZ
269#else
270 static const int ofs = 0;
7c0ea335
VZ
271#endif
272
273 child->SetSize(ofs, ofs, clientW - 2*ofs, clientH - 2*ofs);
274 }
275 }
276}
277
278// The default implementation for the close window event.
3ed2e7ce 279void wxFrameBase::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
7c0ea335
VZ
280{
281 Destroy();
282}
283
284void wxFrameBase::OnMenuHighlight(wxMenuEvent& event)
285{
286#if wxUSE_STATUSBAR
f6bcfd97 287 (void)ShowMenuHelp(GetStatusBar(), event.GetMenuId());
7c0ea335
VZ
288#endif // wxUSE_STATUSBAR
289}
290
291// ----------------------------------------------------------------------------
292// status bar stuff
293// ----------------------------------------------------------------------------
294
295#if wxUSE_STATUSBAR
296
297wxStatusBar* wxFrameBase::CreateStatusBar(int number,
298 long style,
299 wxWindowID id,
300 const wxString& name)
301{
302 // the main status bar can only be created once (or else it should be
303 // deleted before calling CreateStatusBar() again)
304 wxCHECK_MSG( !m_frameStatusBar, (wxStatusBar *)NULL,
305 wxT("recreating status bar in wxFrame") );
306
307 m_frameStatusBar = OnCreateStatusBar( number, style, id, name );
308 if ( m_frameStatusBar )
309 PositionStatusBar();
310
311 return m_frameStatusBar;
312}
313
314wxStatusBar *wxFrameBase::OnCreateStatusBar(int number,
315 long style,
316 wxWindowID id,
317 const wxString& name)
318{
ed791986 319 wxStatusBar *statusBar = new wxStatusBar(this, id, style, name);
7c0ea335
VZ
320
321 // Set the height according to the font and the border size
322 wxClientDC dc(statusBar);
323 dc.SetFont(statusBar->GetFont());
324
ed791986 325 wxCoord y;
7c0ea335
VZ
326 dc.GetTextExtent( "X", NULL, &y );
327
328 int height = (int)( (11*y)/10 + 2*statusBar->GetBorderY());
329
ed791986 330 statusBar->SetSize( -1, -1, -1, height );
7c0ea335
VZ
331
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
f6bcfd97
BP
353bool wxFrameBase::ShowMenuHelp(wxStatusBar *statbar, int menuId)
354{
355 if ( !statbar )
356 return FALSE;
357
358 // if no help string found, we will clear the status bar text
359 wxString helpString;
360
361 if ( menuId != wxID_SEPARATOR && menuId != -2 /* wxID_TITLE */ )
362 {
363 wxMenuBar *menuBar = GetMenuBar();
364 if ( menuBar )
365 {
366 // it's ok if we don't find the item because it might belong
367 // to the popup menu
368 wxMenuItem *item = menuBar->FindItem(menuId);
369 if ( item )
370 helpString = item->GetHelp();
371 }
372 }
373
374 // set status text even if the string is empty - this will at least
375 // remove the string from the item which was previously selected
376 statbar->SetStatusText(helpString);
377
378 return !helpString.IsEmpty();
379}
380
7c0ea335
VZ
381#endif // wxUSE_STATUSBAR
382
383// ----------------------------------------------------------------------------
384// toolbar stuff
385// ----------------------------------------------------------------------------
386
387#if wxUSE_TOOLBAR
388
389wxToolBar* wxFrameBase::CreateToolBar(long style,
390 wxWindowID id,
391 const wxString& name)
392{
393 // the main toolbar can't be recreated (unless it was explicitly deeleted
394 // before)
395 wxCHECK_MSG( !m_frameToolBar, (wxToolBar *)NULL,
396 wxT("recreating toolbar in wxFrame") );
397
398 m_frameToolBar = OnCreateToolBar(style, id, name);
399
400 return m_frameToolBar;
401}
402
403wxToolBar* wxFrameBase::OnCreateToolBar(long style,
404 wxWindowID id,
405 const wxString& name)
406{
407 return new wxToolBar(this, id,
408 wxDefaultPosition, wxDefaultSize,
409 style, name);
410}
411
412#endif // wxUSE_TOOLBAR
413
414// ----------------------------------------------------------------------------
415// Menu UI updating
416// ----------------------------------------------------------------------------
417
418void wxFrameBase::OnIdle(wxIdleEvent& WXUNUSED(event) )
63fec618 419{
54517652 420 DoMenuUpdates();
63fec618
VZ
421}
422
423// update all menus
7c0ea335 424void wxFrameBase::DoMenuUpdates()
63fec618 425{
54517652 426 wxMenuBar* bar = GetMenuBar();
e702ff0f 427
7c0ea335 428 if ( bar != NULL )
54517652
RR
429 {
430 int nCount = bar->GetMenuCount();
431 for (int n = 0; n < nCount; n++)
432 DoMenuUpdates(bar->GetMenu(n), (wxWindow*) NULL);
433 }
63fec618
VZ
434}
435
436// update a menu and all submenus recursively
7c0ea335
VZ
437void wxFrameBase::DoMenuUpdates(wxMenu* menu, wxWindow* WXUNUSED(focusWin))
438{
439 wxEvtHandler* evtHandler = GetEventHandler();
440 wxMenuItemList::Node* node = menu->GetMenuItems().GetFirst();
441 while (node)
63fec618 442 {
7c0ea335
VZ
443 wxMenuItem* item = node->GetData();
444 if ( !item->IsSeparator() )
445 {
446 wxWindowID id = item->GetId();
447 wxUpdateUIEvent event(id);
448 event.SetEventObject( this );
449
450 if (evtHandler->ProcessEvent(event))
451 {
452 if (event.GetSetText())
453 menu->SetLabel(id, event.GetText());
454 if (event.GetSetChecked())
455 menu->Check(id, event.GetChecked());
456 if (event.GetSetEnabled())
457 menu->Enable(id, event.GetEnabled());
458 }
459
460 if (item->GetSubMenu())
461 DoMenuUpdates(item->GetSubMenu(), (wxWindow*) NULL);
462 }
463 node = node->GetNext();
63fec618 464 }
63fec618 465}