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