]> git.saurik.com Git - wxWidgets.git/blame - src/qt/frame.cpp
fixed (rare but fatal) bug in wxWindowDisabler
[wxWidgets.git] / src / qt / frame.cpp
CommitLineData
7c78e7c7
RR
1/////////////////////////////////////////////////////////////////////////////
2// Name: frame.cpp
01b2eeec
KB
3// Purpose: wxFrame
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
7c78e7c7
RR
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "frame.h"
14#endif
15
16#include "wx/frame.h"
7c78e7c7 17#include "wx/statusbr.h"
01b2eeec
KB
18#include "wx/toolbar.h"
19#include "wx/menuitem.h"
7c78e7c7 20
01b2eeec 21extern wxList wxModelessWindows;
7c78e7c7
RR
22extern wxList wxPendingDelete;
23
7c78e7c7
RR
24BEGIN_EVENT_TABLE(wxFrame, wxWindow)
25 EVT_SIZE(wxFrame::OnSize)
01b2eeec
KB
26 EVT_ACTIVATE(wxFrame::OnActivate)
27 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight)
28 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
7c78e7c7 29 EVT_IDLE(wxFrame::OnIdle)
01b2eeec 30 EVT_CLOSE(wxFrame::OnCloseWindow)
7c78e7c7
RR
31END_EVENT_TABLE()
32
01b2eeec 33IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
01b2eeec 34
47d67540 35#if wxUSE_NATIVE_STATUSBAR
01b2eeec
KB
36bool wxFrame::m_useNativeStatusBar = TRUE;
37#else
38bool wxFrame::m_useNativeStatusBar = FALSE;
39#endif
7c78e7c7
RR
40
41wxFrame::wxFrame()
42{
01b2eeec
KB
43 m_frameToolBar = NULL ;
44 m_frameMenuBar = NULL;
45 m_frameStatusBar = NULL;
7c78e7c7 46
01b2eeec
KB
47 m_windowParent = NULL;
48 m_iconized = FALSE;
49}
7c78e7c7 50
01b2eeec
KB
51bool wxFrame::Create(wxWindow *parent,
52 wxWindowID id,
53 const wxString& title,
54 const wxPoint& pos,
55 const wxSize& size,
56 long style,
57 const wxString& name)
7c78e7c7 58{
01b2eeec
KB
59 if (!parent)
60 wxTopLevelWindows.Append(this);
7c78e7c7 61
01b2eeec
KB
62 SetName(name);
63 m_windowStyle = style;
64 m_frameMenuBar = NULL;
65 m_frameToolBar = NULL ;
66 m_frameStatusBar = NULL;
67
68 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
69
70 if ( id > -1 )
71 m_windowId = id;
72 else
73 m_windowId = (int)NewControlId();
74
75 if (parent) parent->AddChild(this);
76
77 wxModelessWindows.Append(this);
78
79 // TODO: create frame.
80
81 return FALSE;
82}
7c78e7c7
RR
83
84wxFrame::~wxFrame()
85{
01b2eeec
KB
86 wxTopLevelWindows.DeleteObject(this);
87
88 if (m_frameStatusBar)
89 delete m_frameStatusBar;
90 if (m_frameMenuBar)
91 delete m_frameMenuBar;
92
93/* Check if it's the last top-level window */
94
95 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
96 {
97 wxTheApp->SetTopWindow(NULL);
98
99 if (wxTheApp->GetExitOnFrameDelete())
100 {
101 // TODO signal to the app that we're going to close
102 }
103 }
104
105 wxModelessWindows.DeleteObject(this);
106}
107
108// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
109void wxFrame::GetClientSize(int *x, int *y) const
110{
111 // TODO
112}
7c78e7c7 113
01b2eeec
KB
114// Set the client size (i.e. leave the calculation of borders etc.
115// to wxWindows)
116void wxFrame::SetClientSize(int width, int height)
117{
118 // TODO
119}
120
121void wxFrame::GetSize(int *width, int *height) const
122{
123 // TODO
124}
125
126void wxFrame::GetPosition(int *x, int *y) const
127{
128 // TODO
129}
130
131void wxFrame::SetSize(int x, int y, int width, int height, int sizeFlags)
132{
133 // TODO
134}
7c78e7c7 135
01b2eeec 136bool wxFrame::Show(bool show)
7c78e7c7 137{
01b2eeec
KB
138 // TODO
139 return FALSE;
140}
141
142void wxFrame::Iconize(bool iconize)
143{
144 // TODO
145}
146
147// Equivalent to maximize/restore in Windows
148void wxFrame::Maximize(bool maximize)
149{
150 // TODO
151}
152
153bool wxFrame::IsIconized() const
154{
155 // TODO
156 return FALSE;
157}
158
159void wxFrame::SetTitle(const wxString& title)
160{
161 // TODO
162}
163
164wxString wxFrame::GetTitle() const
165{
166 // TODO
167 return wxString("");
168}
169
170void wxFrame::SetIcon(const wxIcon& icon)
171{
172 m_icon = icon;
173 // TODO
174}
175
176void wxFrame::SetAcceleratorTable(const wxAcceleratorTable& accel)
177{
178 m_acceleratorTable = accel;
179}
180
181wxStatusBar *wxFrame::OnCreateStatusBar(int number, long style, wxWindowID id,
182 const wxString& name)
183{
184 wxStatusBar *statusBar = NULL;
185
186 statusBar = new wxStatusBar(this, id, wxPoint(0, 0), wxSize(100, 20),
187 style, name);
188
189 // Set the height according to the font and the border size
190 wxClientDC dc(statusBar);
191 dc.SetFont(* statusBar->GetFont());
192
193 long x, y;
194 dc.GetTextExtent("X", &x, &y);
195
196 int height = (int)( (y * 1.1) + 2* statusBar->GetBorderY());
197
198 statusBar->SetSize(-1, -1, 100, height);
199
200 statusBar->SetFieldsCount(number);
201 return statusBar;
202}
203
204wxStatusBar* wxFrame::CreateStatusBar(int number, long style, wxWindowID id,
205 const wxString& name)
206{
207 // Calling CreateStatusBar twice is an error.
208 wxCHECK_MSG( m_frameStatusBar == NULL, FALSE,
209 "recreating status bar in wxFrame" );
210
211 m_frameStatusBar = OnCreateStatusBar(number, style, id,
212 name);
213 if ( m_frameStatusBar )
7c78e7c7 214 {
01b2eeec
KB
215 PositionStatusBar();
216 return m_frameStatusBar;
217 }
218 else
219 return NULL;
220}
7c78e7c7 221
01b2eeec 222void wxFrame::SetStatusText(const wxString& text, int number)
7c78e7c7 223{
01b2eeec 224 wxCHECK_RET( m_frameStatusBar != NULL, "no statusbar to set text for" );
7c78e7c7 225
01b2eeec
KB
226 m_frameStatusBar->SetStatusText(text, number);
227}
228
229void wxFrame::SetStatusWidths(int n, const int widths_field[])
7c78e7c7 230{
01b2eeec
KB
231 wxCHECK_RET( m_frameStatusBar != NULL, "no statusbar to set widths for" );
232
233 m_frameStatusBar->SetStatusWidths(n, widths_field);
234 PositionStatusBar();
235}
236
237void wxFrame::PositionStatusBar()
238{
239 int w, h;
240 GetClientSize(&w, &h);
241 int sw, sh;
242 m_frameStatusBar->GetSize(&sw, &sh);
243
244 // Since we wish the status bar to be directly under the client area,
245 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
246 m_frameStatusBar->SetSize(0, h, w, sh);
247}
248
249void wxFrame::SetMenuBar(wxMenuBar *menuBar)
250{
251 if (!menuBar)
7c78e7c7 252 {
01b2eeec
KB
253 m_frameMenuBar = NULL;
254 return;
7c78e7c7 255 }
01b2eeec
KB
256
257 m_frameMenuBar = menuBar;
7c78e7c7 258
01b2eeec
KB
259 // TODO
260}
261
262void wxFrame::Fit()
7c78e7c7 263{
01b2eeec
KB
264 // Work out max. size
265 wxNode *node = GetChildren()->First();
266 int max_width = 0;
267 int max_height = 0;
268 while (node)
269 {
270 // Find a child that's a subwindow, but not a dialog box.
271 wxWindow *win = (wxWindow *)node->Data();
7c78e7c7 272
01b2eeec
KB
273 if (!win->IsKindOf(CLASSINFO(wxFrame)) &&
274 !win->IsKindOf(CLASSINFO(wxDialog)))
275 {
276 int width, height;
277 int x, y;
278 win->GetSize(&width, &height);
279 win->GetPosition(&x, &y);
280
281 if ((x + width) > max_width)
282 max_width = x + width;
283 if ((y + height) > max_height)
284 max_height = y + height;
285 }
286 node = node->Next();
287 }
288 SetClientSize(max_width, max_height);
7c78e7c7
RR
289}
290
01b2eeec
KB
291// Responds to colour changes, and passes event on to children.
292void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
7c78e7c7 293{
01b2eeec
KB
294 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
295 Refresh();
296
297 if ( m_frameStatusBar )
7c78e7c7 298 {
01b2eeec
KB
299 wxSysColourChangedEvent event2;
300 event2.SetEventObject( m_frameStatusBar );
301 m_frameStatusBar->ProcessEvent(event2);
7c78e7c7 302 }
7c78e7c7 303
01b2eeec
KB
304 // Propagate the event to the non-top-level children
305 wxWindow::OnSysColourChanged(event);
306}
7c78e7c7 307
01b2eeec
KB
308// Default resizing behaviour - if only ONE subwindow,
309// resize to client rectangle size
310void wxFrame::OnSize(wxSizeEvent& event)
7c78e7c7 311{
01b2eeec 312 // if we're using constraints - do use them
47d67540 313 #if wxUSE_CONSTRAINTS
01b2eeec
KB
314 if ( GetAutoLayout() ) {
315 Layout();
7c78e7c7 316 return;
01b2eeec
KB
317 }
318 #endif
319
320 // do we have _exactly_ one child?
321 wxWindow *child = NULL;
322 for ( wxNode *node = GetChildren()->First(); node; node = node->Next() )
323 {
324 wxWindow *win = (wxWindow *)node->Data();
325 if ( !win->IsKindOf(CLASSINFO(wxFrame)) &&
326 !win->IsKindOf(CLASSINFO(wxDialog)) &&
327 (win != GetStatusBar()) &&
328 (win != GetToolBar()) )
7c78e7c7 329 {
01b2eeec
KB
330 if ( child )
331 return; // it's our second subwindow - nothing to do
332 child = win;
333 }
334 }
7c78e7c7 335
01b2eeec
KB
336 if ( child ) {
337 // we have exactly one child - set it's size to fill the whole frame
338 int clientW, clientH;
339 GetClientSize(&clientW, &clientH);
7c78e7c7 340
01b2eeec
KB
341 int x = 0;
342 int y = 0;
343
344 child->SetSize(x, y, clientW, clientH);
7c78e7c7 345 }
01b2eeec 346}
7c78e7c7 347
01b2eeec
KB
348// Default activation behaviour - set the focus for the first child
349// subwindow found.
350void wxFrame::OnActivate(wxActivateEvent& event)
7c78e7c7 351{
01b2eeec 352 for(wxNode *node = GetChildren()->First(); node; node = node->Next())
7c78e7c7 353 {
01b2eeec
KB
354 // Find a child that's a subwindow, but not a dialog box.
355 wxWindow *child = (wxWindow *)node->Data();
356 if (!child->IsKindOf(CLASSINFO(wxFrame)) &&
357 !child->IsKindOf(CLASSINFO(wxDialog)))
358 {
359#if WXDEBUG > 1
360 wxDebugMsg("wxFrame::OnActivate: about to set the child's focus.\n");
361#endif
362 child->SetFocus();
363 return;
364 }
365 }
366}
367
e3065973 368// The default implementation for the close window event.
01b2eeec 369void wxFrame::OnCloseWindow(wxCloseEvent& event)
7c78e7c7 370{
e3065973 371 this->Destroy();
01b2eeec
KB
372}
373
374// Destroy the window (delayed, if a managed window)
375bool wxFrame::Destroy()
376{
377 if (!wxPendingDelete.Member(this))
378 wxPendingDelete.Append(this);
379 return TRUE;
380}
381
382// Default menu selection behaviour - display a help string
383void wxFrame::OnMenuHighlight(wxMenuEvent& event)
384{
385 if (GetStatusBar())
7c78e7c7 386 {
01b2eeec
KB
387 if (event.GetMenuId() == -1)
388 SetStatusText("");
389 else
7c78e7c7 390 {
01b2eeec
KB
391 wxMenuBar *menuBar = GetMenuBar();
392 if (menuBar)
7c78e7c7 393 {
01b2eeec
KB
394 wxString helpString(menuBar->GetHelpString(event.GetMenuId()));
395 if (helpString != "")
396 SetStatusText(helpString);
397 }
7c78e7c7
RR
398 }
399 }
01b2eeec 400}
7c78e7c7 401
01b2eeec 402wxMenuBar *wxFrame::GetMenuBar() const
7c78e7c7
RR
403{
404 return m_frameMenuBar;
01b2eeec 405}
7c78e7c7 406
01b2eeec 407void wxFrame::Centre(int direction)
7c78e7c7 408{
01b2eeec
KB
409 int display_width, display_height, width, height, x, y;
410 wxDisplaySize(&display_width, &display_height);
411
412 GetSize(&width, &height);
413 GetPosition(&x, &y);
414
415 if (direction & wxHORIZONTAL)
416 x = (int)((display_width - width)/2);
417 if (direction & wxVERTICAL)
418 y = (int)((display_height - height)/2);
419
420 SetSize(x, y, width, height);
421}
7c78e7c7 422
01b2eeec
KB
423// Call this to simulate a menu command
424void wxFrame::Command(int id)
7c78e7c7 425{
01b2eeec
KB
426 ProcessCommand(id);
427}
7c78e7c7 428
01b2eeec 429void wxFrame::ProcessCommand(int id)
7c78e7c7 430{
01b2eeec
KB
431 wxCommandEvent commandEvent(wxEVENT_TYPE_MENU_COMMAND, id);
432 commandEvent.SetInt( id );
433 commandEvent.SetEventObject( this );
7c78e7c7 434
01b2eeec
KB
435 wxMenuBar *bar = GetMenuBar() ;
436 if (!bar)
437 return;
7c78e7c7 438
01b2eeec
KB
439/* TODO: check the menu item if required
440 wxMenuItem *item = bar->FindItemForId(id) ;
441 if (item && item->IsCheckable())
442 {
443 bar->Check(id,!bar->Checked(id)) ;
444 }
445*/
7c78e7c7 446
01b2eeec
KB
447 GetEventHandler()->ProcessEvent(commandEvent);
448}
7c78e7c7 449
01b2eeec
KB
450// Checks if there is a toolbar, and returns the first free client position
451wxPoint wxFrame::GetClientAreaOrigin() const
7c78e7c7 452{
01b2eeec
KB
453 wxPoint pt(0, 0);
454 if (GetToolBar())
455 {
456 int w, h;
457 GetToolBar()->GetSize(& w, & h);
458
459 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
460 {
461 pt.x += w;
462 }
463 else
464 {
465 pt.y += h;
466 }
467 }
468 return pt;
469}
7c78e7c7 470
01b2eeec 471wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
7c78e7c7 472{
01b2eeec
KB
473 wxCHECK_MSG( m_frameToolBar == NULL, FALSE,
474 "recreating toolbar in wxFrame" );
7c78e7c7 475
01b2eeec
KB
476 wxToolBar* toolBar = OnCreateToolBar(style, id, name);
477 if (toolBar)
478 {
479 SetToolBar(toolBar);
480 PositionToolBar();
481 return toolBar;
482 }
483 else
484 {
485 return NULL;
486 }
487}
7c78e7c7 488
01b2eeec 489wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& name)
7c78e7c7 490{
01b2eeec 491 return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name);
7c78e7c7
RR
492}
493
01b2eeec 494void wxFrame::PositionToolBar()
7c78e7c7 495{
01b2eeec
KB
496 int cw, ch;
497
498 // TODO: we actually need to use the low-level client size, before
499 // the toolbar/status bar were added.
500 // So DEFINITELY replace the line below with something appropriate.
501
502 wxCHECK_MSG( TRUE, FALSE,
503 "PositionToolBar not implemented properly, see frame.cpp" );
504
505 GetClientSize(& cw, &ch);
506
507 if ( GetStatusBar() )
508 {
509 int statusX, statusY;
510 GetStatusBar()->GetClientSize(&statusX, &statusY);
511 ch -= statusY;
512 }
513
514 if (GetToolBar())
515 {
516 int tw, th;
517 GetToolBar()->GetSize(& tw, & th);
518
519 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
520 {
521 // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS
522 // means, pretend we don't have toolbar/status bar, so we
523 // have the original client size.
524 GetToolBar()->SetSize(0, 0, tw, ch, wxSIZE_NO_ADJUSTMENTS);
525 }
526 else
527 {
528 // Use the 'real' position
529 GetToolBar()->SetSize(0, 0, cw, th, wxSIZE_NO_ADJUSTMENTS);
530 }
531 }
7c78e7c7
RR
532}
533