]> git.saurik.com Git - wxWidgets.git/blob - src/stubs/frame.cpp
Changed wxMenu::GetTitle to return a wxString.
[wxWidgets.git] / src / stubs / frame.cpp
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"
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"
25
26 extern wxList wxModelessWindows;
27 extern wxList wxPendingDelete;
28
29 #if !USE_SHARED_LIBRARY
30 BEGIN_EVENT_TABLE(wxFrame, wxWindow)
31 EVT_SIZE(wxFrame::OnSize)
32 EVT_ACTIVATE(wxFrame::OnActivate)
33 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight)
34 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
35 EVT_IDLE(wxFrame::OnIdle)
36 EVT_CLOSE(wxFrame::OnCloseWindow)
37 END_EVENT_TABLE()
38
39 IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
40 #endif
41
42 #if USE_NATIVE_STATUSBAR
43 bool wxFrame::m_useNativeStatusBar = TRUE;
44 #else
45 bool wxFrame::m_useNativeStatusBar = FALSE;
46 #endif
47
48 wxFrame::wxFrame()
49 {
50 m_frameToolBar = NULL ;
51 m_frameMenuBar = NULL;
52 m_frameStatusBar = NULL;
53
54 m_windowParent = NULL;
55 m_iconized = FALSE;
56 }
57
58 bool wxFrame::Create(wxWindow *parent,
59 wxWindowID id,
60 const wxString& title,
61 const wxPoint& pos,
62 const wxSize& size,
63 long style,
64 const wxString& name)
65 {
66 if (!parent)
67 wxTopLevelWindows.Append(this);
68
69 SetName(name);
70 m_windowStyle = style;
71 m_frameMenuBar = NULL;
72 m_frameToolBar = NULL ;
73 m_frameStatusBar = NULL;
74
75 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
76
77 if ( id > -1 )
78 m_windowId = id;
79 else
80 m_windowId = (int)NewControlId();
81
82 if (parent) parent->AddChild(this);
83
84 wxModelessWindows.Append(this);
85
86 // TODO: create frame.
87
88 return FALSE;
89 }
90
91 wxFrame::~wxFrame()
92 {
93 wxTopLevelWindows.DeleteObject(this);
94
95 if (m_frameStatusBar)
96 delete m_frameStatusBar;
97 if (m_frameMenuBar)
98 delete m_frameMenuBar;
99
100 /* Check if it's the last top-level window */
101
102 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
103 {
104 wxTheApp->SetTopWindow(NULL);
105
106 if (wxTheApp->GetExitOnFrameDelete())
107 {
108 // TODO signal to the app that we're going to close
109 }
110 }
111
112 wxModelessWindows.DeleteObject(this);
113 }
114
115 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
116 void wxFrame::GetClientSize(int *x, int *y) const
117 {
118 // TODO
119 }
120
121 // Set the client size (i.e. leave the calculation of borders etc.
122 // to wxWindows)
123 void wxFrame::SetClientSize(int width, int height)
124 {
125 // TODO
126 }
127
128 void wxFrame::GetSize(int *width, int *height) const
129 {
130 // TODO
131 }
132
133 void wxFrame::GetPosition(int *x, int *y) const
134 {
135 // TODO
136 }
137
138 void wxFrame::SetSize(int x, int y, int width, int height, int sizeFlags)
139 {
140 // TODO
141 }
142
143 bool wxFrame::Show(bool show)
144 {
145 // TODO
146 return FALSE;
147 }
148
149 void wxFrame::Iconize(bool iconize)
150 {
151 // TODO
152 }
153
154 // Equivalent to maximize/restore in Windows
155 void wxFrame::Maximize(bool maximize)
156 {
157 // TODO
158 }
159
160 bool wxFrame::IsIconized() const
161 {
162 // TODO
163 return FALSE;
164 }
165
166 void wxFrame::SetTitle(const wxString& title)
167 {
168 // TODO
169 }
170
171 wxString wxFrame::GetTitle() const
172 {
173 // TODO
174 return wxString("");
175 }
176
177 void wxFrame::SetIcon(const wxIcon& icon)
178 {
179 m_icon = icon;
180 // TODO
181 }
182
183 void wxFrame::SetAcceleratorTable(const wxAcceleratorTable& accel)
184 {
185 m_acceleratorTable = accel;
186 }
187
188 wxStatusBar *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);
198 dc.SetFont(* statusBar->GetFont());
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
211 wxStatusBar* 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
229 void 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
236 void 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
244 void 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
256 void 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
269 void wxFrame::Fit()
270 {
271 // Work out max. size
272 wxNode *node = GetChildren()->First();
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.
299 void 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
317 void wxFrame::OnSize(wxSizeEvent& event)
318 {
319 // if we're using constraints - do use them
320 #if USE_CONSTRAINTS
321 if ( GetAutoLayout() ) {
322 Layout();
323 return;
324 }
325 #endif
326
327 // do we have _exactly_ one child?
328 wxWindow *child = NULL;
329 for ( wxNode *node = GetChildren()->First(); node; node = node->Next() )
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.
357 void wxFrame::OnActivate(wxActivateEvent& event)
358 {
359 for(wxNode *node = GetChildren()->First(); node; node = node->Next())
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 {
366 #if WXDEBUG > 1
367 wxDebugMsg("wxFrame::OnActivate: about to set the child's focus.\n");
368 #endif
369 child->SetFocus();
370 return;
371 }
372 }
373 }
374
375 // The default implementation for the close window event - calls
376 // OnClose for backward compatibility.
377
378 void wxFrame::OnCloseWindow(wxCloseEvent& event)
379 {
380 // Compatibility
381 if ( GetEventHandler()->OnClose() || event.GetForce())
382 {
383 this->Destroy();
384 }
385 }
386
387 bool wxFrame::OnClose()
388 {
389 return TRUE;
390 }
391
392 // Destroy the window (delayed, if a managed window)
393 bool wxFrame::Destroy()
394 {
395 if (!wxPendingDelete.Member(this))
396 wxPendingDelete.Append(this);
397 return TRUE;
398 }
399
400 // Default menu selection behaviour - display a help string
401 void wxFrame::OnMenuHighlight(wxMenuEvent& event)
402 {
403 if (GetStatusBar())
404 {
405 if (event.GetMenuId() == -1)
406 SetStatusText("");
407 else
408 {
409 wxMenuBar *menuBar = GetMenuBar();
410 if (menuBar)
411 {
412 wxString helpString(menuBar->GetHelpString(event.GetMenuId()));
413 if (helpString != "")
414 SetStatusText(helpString);
415 }
416 }
417 }
418 }
419
420 wxMenuBar *wxFrame::GetMenuBar() const
421 {
422 return m_frameMenuBar;
423 }
424
425 void wxFrame::Centre(int direction)
426 {
427 int display_width, display_height, width, height, x, y;
428 wxDisplaySize(&display_width, &display_height);
429
430 GetSize(&width, &height);
431 GetPosition(&x, &y);
432
433 if (direction & wxHORIZONTAL)
434 x = (int)((display_width - width)/2);
435 if (direction & wxVERTICAL)
436 y = (int)((display_height - height)/2);
437
438 SetSize(x, y, width, height);
439 }
440
441 // Call this to simulate a menu command
442 void wxFrame::Command(int id)
443 {
444 ProcessCommand(id);
445 }
446
447 void wxFrame::ProcessCommand(int id)
448 {
449 wxCommandEvent commandEvent(wxEVENT_TYPE_MENU_COMMAND, id);
450 commandEvent.SetInt( id );
451 commandEvent.SetEventObject( this );
452
453 wxMenuBar *bar = GetMenuBar() ;
454 if (!bar)
455 return;
456
457 /* TODO: check the menu item if required
458 wxMenuItem *item = bar->FindItemForId(id) ;
459 if (item && item->IsCheckable())
460 {
461 bar->Check(id,!bar->Checked(id)) ;
462 }
463 */
464
465 GetEventHandler()->ProcessEvent(commandEvent);
466 }
467
468 // Checks if there is a toolbar, and returns the first free client position
469 wxPoint wxFrame::GetClientAreaOrigin() const
470 {
471 wxPoint pt(0, 0);
472 if (GetToolBar())
473 {
474 int w, h;
475 GetToolBar()->GetSize(& w, & h);
476
477 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
478 {
479 pt.x += w;
480 }
481 else
482 {
483 pt.y += h;
484 }
485 }
486 return pt;
487 }
488
489 wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
490 {
491 wxCHECK_MSG( m_frameToolBar == NULL, FALSE,
492 "recreating toolbar in wxFrame" );
493
494 wxToolBar* toolBar = OnCreateToolBar(style, id, name);
495 if (toolBar)
496 {
497 SetToolBar(toolBar);
498 PositionToolBar();
499 return toolBar;
500 }
501 else
502 {
503 return NULL;
504 }
505 }
506
507 wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& name)
508 {
509 return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name);
510 }
511
512 void wxFrame::PositionToolBar()
513 {
514 int cw, ch;
515
516 // TODO: we actually need to use the low-level client size, before
517 // the toolbar/status bar were added.
518 // So DEFINITELY replace the line below with something appropriate.
519
520 GetClientSize(& cw, &ch);
521
522 if ( GetStatusBar() )
523 {
524 int statusX, statusY;
525 GetStatusBar()->GetClientSize(&statusX, &statusY);
526 ch -= statusY;
527 }
528
529 if (GetToolBar())
530 {
531 int tw, th;
532 GetToolBar()->GetSize(& tw, & th);
533
534 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
535 {
536 // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS
537 // means, pretend we don't have toolbar/status bar, so we
538 // have the original client size.
539 GetToolBar()->SetSize(0, 0, tw, ch, wxSIZE_NO_ADJUSTMENTS);
540 }
541 else
542 {
543 // Use the 'real' position
544 GetToolBar()->SetSize(0, 0, cw, th, wxSIZE_NO_ADJUSTMENTS);
545 }
546 }
547 }
548