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