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