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