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