]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/frame.cpp
cleanup and fix of double disposal (thanks to Steve Hartwell)
[wxWidgets.git] / src / mac / carbon / frame.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: frame.cpp
3 // Purpose: wxFrame
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
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 #include "wx/mac/uma.h"
27
28 extern wxWindowList wxModelessWindows;
29 extern wxList wxPendingDelete;
30
31 #if !USE_SHARED_LIBRARY
32 BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
33 EVT_ACTIVATE(wxFrame::OnActivate)
34 // EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight)
35 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
36 // EVT_IDLE(wxFrame::OnIdle)
37 // EVT_CLOSE(wxFrame::OnCloseWindow)
38 END_EVENT_TABLE()
39
40 IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxTopLevelWindow)
41 #endif
42
43 #define WX_MAC_STATUSBAR_HEIGHT 15
44 // ----------------------------------------------------------------------------
45 // creation/destruction
46 // ----------------------------------------------------------------------------
47
48 void wxFrame::Init()
49 {
50 m_frameMenuBar = NULL;
51
52 #if wxUSE_TOOLBAR
53 m_frameToolBar = NULL ;
54 #endif
55 m_frameStatusBar = NULL;
56 m_winLastFocused = NULL ;
57
58 m_iconized = FALSE;
59
60 #if wxUSE_TOOLTIPS
61 m_hwndToolTip = 0;
62 #endif
63 }
64
65 wxPoint wxFrame::GetClientAreaOrigin() const
66 {
67 // on mac we are at position -1,-1 with the control
68 wxPoint pt(0, 0);
69
70 #if wxUSE_TOOLBAR
71 if ( GetToolBar() )
72 {
73 int w, h;
74 GetToolBar()->GetSize(& w, & h);
75
76 if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL )
77 {
78 pt.x += w - 1;
79 }
80 else
81 {
82 pt.y += h - 1 ;
83 }
84 }
85 #endif // wxUSE_TOOLBAR
86
87 return pt;
88 }
89
90 bool wxFrame::Create(wxWindow *parent,
91 wxWindowID id,
92 const wxString& title,
93 const wxPoint& pos,
94 const wxSize& size,
95 long style,
96 const wxString& name)
97 {
98 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
99
100 if ( !wxTopLevelWindow::Create(parent, id, title, pos, size, style, name) )
101 return FALSE;
102
103 MacCreateRealWindow( title, pos , size , MacRemoveBordersFromStyle(style) , name ) ;
104
105 m_macWindowBackgroundTheme = kThemeBrushDocumentWindowBackground ;
106 SetThemeWindowBackground( (WindowRef) m_macWindow , m_macWindowBackgroundTheme , false ) ;
107
108 wxModelessWindows.Append(this);
109
110 return TRUE;
111 }
112
113 wxFrame::~wxFrame()
114 {
115 m_isBeingDeleted = TRUE;
116 DeleteAllBars();
117 }
118
119
120 bool wxFrame::Enable(bool enable)
121 {
122 if ( !wxWindow::Enable(enable) )
123 return FALSE;
124
125 if ( m_frameMenuBar && m_frameMenuBar == wxMenuBar::MacGetInstalledMenuBar() )
126 {
127 int iMaxMenu = m_frameMenuBar->GetMenuCount();
128 for ( int i = 0 ; i < iMaxMenu ; ++ i )
129 {
130 m_frameMenuBar->EnableTop( i , enable ) ;
131 }
132 }
133
134 return TRUE;
135 }
136
137 wxStatusBar *wxFrame::OnCreateStatusBar(int number, long style, wxWindowID id,
138 const wxString& name)
139 {
140 wxStatusBar *statusBar = NULL;
141
142 statusBar = new wxStatusBar(this, id,
143 style, name);
144 statusBar->SetSize( 100 , 15 ) ;
145 statusBar->SetFieldsCount(number);
146 return statusBar;
147 }
148
149 void wxFrame::PositionStatusBar()
150 {
151 if (m_frameStatusBar )
152 {
153 int w, h;
154 GetClientSize(&w, &h);
155 int sw, sh;
156 m_frameStatusBar->GetSize(&sw, &sh);
157
158 // Since we wish the status bar to be directly under the client area,
159 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
160 m_frameStatusBar->SetSize(0, h, w, sh);
161 }
162 }
163
164 // Responds to colour changes, and passes event on to children.
165 void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
166 {
167 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
168 Refresh();
169
170 if ( m_frameStatusBar )
171 {
172 wxSysColourChangedEvent event2;
173 event2.SetEventObject( m_frameStatusBar );
174 m_frameStatusBar->ProcessEvent(event2);
175 }
176
177 // Propagate the event to the non-top-level children
178 wxWindow::OnSysColourChanged(event);
179 }
180
181
182 // Default activation behaviour - set the focus for the first child
183 // subwindow found.
184 void wxFrame::OnActivate(wxActivateEvent& event)
185 {
186 if ( !event.GetActive() )
187 {
188 // remember the last focused child if it is our child
189 m_winLastFocused = FindFocus();
190
191 // so we NULL it out if it's a child from some other frame
192 wxWindow *win = m_winLastFocused;
193 while ( win )
194 {
195 if ( win->IsTopLevel() )
196 {
197 if ( win != this )
198 {
199 m_winLastFocused = NULL;
200 }
201
202 break;
203 }
204
205 win = win->GetParent();
206 }
207
208 event.Skip();
209 }
210 else
211 {
212 // restore focus to the child which was last focused
213 wxWindow *parent = m_winLastFocused ? m_winLastFocused->GetParent()
214 : NULL;
215 if ( !parent )
216 {
217 parent = this;
218 }
219
220 wxSetFocusToChild(parent, &m_winLastFocused);
221
222 if ( m_frameMenuBar != NULL )
223 {
224 m_frameMenuBar->MacInstallMenuBar() ;
225 }
226 else if (wxTheApp->GetTopWindow() && wxTheApp->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame)))
227 {
228 // Trying toplevel frame menbar
229 if( ((wxFrame*)wxTheApp->GetTopWindow())->GetMenuBar() )
230 ((wxFrame*)wxTheApp->GetTopWindow())->GetMenuBar()->MacInstallMenuBar();
231 }
232 }
233 }
234
235 void wxFrame::DetachMenuBar()
236 {
237 if ( m_frameMenuBar )
238 {
239 m_frameMenuBar->UnsetInvokingWindow();
240 }
241
242 wxFrameBase::DetachMenuBar();
243 }
244
245 void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
246 {
247 wxFrameBase::AttachMenuBar(menuBar);
248
249 if (m_frameMenuBar)
250 {
251 m_frameMenuBar->SetInvokingWindow( this );
252 }
253 }
254
255 void wxFrame::DoGetClientSize(int *x, int *y) const
256 {
257 wxWindow::DoGetClientSize( x , y ) ;
258
259 #if wxUSE_STATUSBAR
260 if ( GetStatusBar() && y )
261 {
262 int statusX, statusY;
263 GetStatusBar()->GetClientSize(&statusX, &statusY);
264 *y -= statusY;
265 }
266 #endif // wxUSE_STATUSBAR
267
268 wxPoint pt(GetClientAreaOrigin());
269 if ( y )
270 *y -= pt.y;
271 if ( x )
272 *x -= pt.x;
273 }
274
275 void wxFrame::DoSetClientSize(int clientwidth, int clientheight)
276 {
277 int currentclientwidth , currentclientheight ;
278 int currentwidth , currentheight ;
279
280 GetClientSize( &currentclientwidth , &currentclientheight ) ;
281 GetSize( &currentwidth , &currentheight ) ;
282
283 // find the current client size
284
285 // Find the difference between the entire window (title bar and all)
286 // and the client area; add this to the new client size to move the
287 // window
288
289 DoSetSize( -1 , -1 , currentwidth + clientwidth - currentclientwidth ,
290 currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ;
291 }
292
293
294 #if wxUSE_TOOLBAR
295 wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
296 {
297 if ( wxFrameBase::CreateToolBar(style, id, name) )
298 {
299 PositionToolBar();
300 }
301
302 return m_frameToolBar;
303 }
304
305 void wxFrame::PositionToolBar()
306 {
307 int cw, ch;
308
309 cw = m_width ;
310 ch = m_height ;
311
312 if ( GetStatusBar() )
313 {
314 int statusX, statusY;
315 GetStatusBar()->GetClientSize(&statusX, &statusY);
316 ch -= statusY;
317 }
318
319 if (GetToolBar())
320 {
321 int tw, th;
322 GetToolBar()->GetSize(& tw, & th);
323
324 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
325 {
326 // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS
327 // means, pretend we don't have toolbar/status bar, so we
328 // have the original client size.
329 GetToolBar()->SetSize(-1, -1, tw, ch + 2 , wxSIZE_NO_ADJUSTMENTS | wxSIZE_ALLOW_MINUS_ONE );
330 }
331 else
332 {
333 // Use the 'real' position
334 GetToolBar()->SetSize(-1, -1, cw + 2, th, wxSIZE_NO_ADJUSTMENTS | wxSIZE_ALLOW_MINUS_ONE );
335 }
336 }
337 }
338 #endif