]> git.saurik.com Git - wxWidgets.git/blob - src/cocoa/toplevel.mm
reSWIGed
[wxWidgets.git] / src / cocoa / toplevel.mm
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: cocoa/toplevel.mm
3 // Purpose: implements wxTopLevelWindow for Cocoa
4 // Author: David Elliott
5 // Modified by:
6 // Created: 2002/11/27
7 // RCS-ID: $Id$
8 // Copyright: (c) 2002 David Elliott
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22 #ifndef WX_PRECOMP
23 #include "wx/window.h"
24 #include "wx/toplevel.h"
25 #include "wx/menuitem.h"
26 #include "wx/frame.h"
27 #include "wx/log.h"
28 #include "wx/app.h"
29 #endif //WX_PRECOMP
30
31 #include "wx/cocoa/autorelease.h"
32 #include "wx/cocoa/string.h"
33
34 #import <AppKit/NSView.h>
35 #import <AppKit/NSWindow.h>
36 #import <AppKit/NSPanel.h>
37 // ----------------------------------------------------------------------------
38 // globals
39 // ----------------------------------------------------------------------------
40
41 // list of all frames and modeless dialogs
42 wxWindowList wxModelessWindows;
43
44 // ============================================================================
45 // wxTopLevelWindowCocoa implementation
46 // ============================================================================
47
48 wxTopLevelWindowCocoa *wxTopLevelWindowCocoa::sm_cocoaDeactivateWindow = NULL;
49
50 // ----------------------------------------------------------------------------
51 // wxTopLevelWindowCocoa creation
52 // ----------------------------------------------------------------------------
53 BEGIN_EVENT_TABLE(wxTopLevelWindowCocoa,wxTopLevelWindowBase)
54 EVT_CLOSE(wxTopLevelWindowCocoa::OnCloseWindow)
55 END_EVENT_TABLE()
56
57 void wxTopLevelWindowCocoa::Init()
58 {
59 m_iconized =
60 m_maximizeOnShow =
61 m_closed = false;
62 }
63
64 unsigned int wxTopLevelWindowCocoa::NSWindowStyleForWxStyle(long style)
65 {
66 unsigned int styleMask = 0;
67 if(style & wxCAPTION)
68 styleMask |= NSTitledWindowMask;
69 if(style & wxMINIMIZE_BOX)
70 styleMask |= NSMiniaturizableWindowMask;
71 #if 0
72 if(style & wxMAXIMIZE_BOX)
73 styleMask |= NSWindowMask;
74 #endif
75 if(style & wxCLOSE_BOX)
76 styleMask |= NSClosableWindowMask;
77 if(style & wxRESIZE_BORDER)
78 styleMask |= NSResizableWindowMask;
79 if(style & wxSIMPLE_BORDER)
80 styleMask |= NSBorderlessWindowMask;
81 return styleMask;
82 }
83
84 bool wxTopLevelWindowCocoa::Create(wxWindow *parent,
85 wxWindowID winid,
86 const wxString& title,
87 const wxPoint& pos,
88 const wxSize& size,
89 long style,
90 const wxString& name)
91 {
92 wxAutoNSAutoreleasePool pool;
93 wxTopLevelWindows.Append(this);
94
95 if(!CreateBase(parent,winid,pos,size,style,wxDefaultValidator,name))
96 return FALSE;
97
98 if ( parent )
99 parent->AddChild(this);
100
101 unsigned int cocoaStyle = NSWindowStyleForWxStyle(style);
102 if(style & wxFRAME_TOOL_WINDOW)
103 cocoaStyle |= NSUtilityWindowMask;
104
105 wxPoint realpos = pos;
106 wxSize realsize = size;
107 // FIXME: this is lame
108 if(realpos.x==-1)
109 realpos.x=100;
110 if(realpos.y==-1)
111 realpos.y=100;
112 if(realsize.x==-1)
113 realsize.x=200;
114 if(realsize.y==-1)
115 realsize.y=200;
116 // NOTE: y-origin needs to be flipped.
117 NSRect cocoaRect = [NSWindow contentRectForFrameRect:NSMakeRect(realpos.x,realpos.y,realsize.x,realsize.y) styleMask:cocoaStyle];
118
119 m_cocoaNSWindow = NULL;
120 m_cocoaNSView = NULL;
121 if(style & wxFRAME_TOOL_WINDOW)
122 SetNSWindow([[NSPanel alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]);
123 else
124 SetNSWindow([[NSWindow alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]);
125 // NOTE: SetNSWindow has retained the Cocoa object for this object.
126 // Because we do not release on close, the following release matches the
127 // above alloc and thus the retain count will be 1.
128 [m_cocoaNSWindow release];
129
130 if(style & wxFRAME_NO_TASKBAR)
131 [m_cocoaNSWindow setExcludedFromWindowsMenu: YES];
132 if(style & wxSTAY_ON_TOP)
133 [m_cocoaNSWindow setLevel:NSFloatingWindowLevel];
134 [m_cocoaNSWindow setTitle:wxNSStringWithWxString(title)];
135 return TRUE;
136 }
137
138 wxTopLevelWindowCocoa::~wxTopLevelWindowCocoa()
139 {
140 wxASSERT(sm_cocoaDeactivateWindow!=this);
141 wxAutoNSAutoreleasePool pool;
142 DestroyChildren();
143 SetNSWindow(NULL);
144 }
145
146 bool wxTopLevelWindowCocoa::Destroy()
147 {
148 if(sm_cocoaDeactivateWindow==this)
149 {
150 sm_cocoaDeactivateWindow = NULL;
151 wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey();
152 }
153 return wxTopLevelWindowBase::Destroy();
154 }
155
156 // ----------------------------------------------------------------------------
157 // wxTopLevelWindowCocoa Cocoa Specifics
158 // ----------------------------------------------------------------------------
159
160 wxMenuBar* wxTopLevelWindowCocoa::GetAppMenuBar(wxCocoaNSWindow *win)
161 {
162 wxTopLevelWindowCocoa *parent = wxDynamicCast(GetParent(),wxTopLevelWindow);
163 if(parent)
164 return parent->GetAppMenuBar(win);
165 return NULL;
166 }
167
168 void wxTopLevelWindowCocoa::SetNSWindow(WX_NSWindow cocoaNSWindow)
169 {
170 bool need_debug = cocoaNSWindow || m_cocoaNSWindow;
171 if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [m_cocoaNSWindow=%p retainCount]=%d",this,m_cocoaNSWindow,[m_cocoaNSWindow retainCount]);
172 DisassociateNSWindow(m_cocoaNSWindow);
173 [cocoaNSWindow retain];
174 [m_cocoaNSWindow release];
175 m_cocoaNSWindow = cocoaNSWindow;
176 if(m_cocoaNSWindow)
177 SetNSView([m_cocoaNSWindow contentView]);
178 else
179 SetNSView(NULL);
180 AssociateNSWindow(m_cocoaNSWindow);
181 if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [cocoaNSWindow=%p retainCount]=%d",this,cocoaNSWindow,[cocoaNSWindow retainCount]);
182 }
183
184 void wxTopLevelWindowCocoa::CocoaReplaceView(WX_NSView oldView, WX_NSView newView)
185 {
186 if([m_cocoaNSWindow contentView] == (id)oldView)
187 [m_cocoaNSWindow setContentView:newView];
188 }
189
190 /*static*/ void wxTopLevelWindowCocoa::DeactivatePendingWindow()
191 {
192 if(sm_cocoaDeactivateWindow)
193 sm_cocoaDeactivateWindow->wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey();
194 sm_cocoaDeactivateWindow = NULL;
195 }
196
197 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeKey(void)
198 {
199 DeactivatePendingWindow();
200 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeKey",this);
201 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, GetId());
202 event.SetEventObject(this);
203 GetEventHandler()->ProcessEvent(event);
204 }
205
206 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey(void)
207 {
208 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignKey",this);
209 wxActivateEvent event(wxEVT_ACTIVATE, FALSE, GetId());
210 event.SetEventObject(this);
211 GetEventHandler()->ProcessEvent(event);
212 }
213
214 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeMain(void)
215 {
216 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeMain",this);
217 }
218
219 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignMain(void)
220 {
221 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignMain",this);
222 }
223
224 void wxTopLevelWindowCocoa::CocoaDelegate_windowWillClose(void)
225 {
226 m_closed = true;
227 Destroy();
228 /* Be SURE that idle events get ran. If the window was not active when
229 it was closed, then there will be no more events to trigger this and
230 therefore it must be done here */
231 wxTheApp->CocoaInstallRequestedIdleHandler();
232 }
233
234 bool wxTopLevelWindowCocoa::CocoaDelegate_windowShouldClose()
235 {
236 return wxWindowBase::Close(false);
237 }
238
239 // ----------------------------------------------------------------------------
240 // wxTopLevelWindowCocoa maximize/minimize
241 // ----------------------------------------------------------------------------
242
243 void wxTopLevelWindowCocoa::Maximize(bool maximize)
244 {
245 }
246
247 bool wxTopLevelWindowCocoa::IsMaximized() const
248 {
249 return false ;
250 }
251
252 void wxTopLevelWindowCocoa::Iconize(bool iconize)
253 {
254 }
255
256 bool wxTopLevelWindowCocoa::IsIconized() const
257 {
258 return FALSE;
259 }
260
261 void wxTopLevelWindowCocoa::Restore()
262 {
263 }
264
265 bool wxTopLevelWindowCocoa::Show(bool show)
266 {
267 if(m_isShown == show)
268 return false;
269 wxAutoNSAutoreleasePool pool;
270 if(show)
271 {
272 // Send the window a size event because wxWindows apps expect it
273 // NOTE: This should really only be done the first time a window
274 // is shown. I doubt this will cause any problems though.
275 wxSizeEvent event(GetSize(), GetId());
276 event.SetEventObject(this);
277 GetEventHandler()->ProcessEvent(event);
278
279 [m_cocoaNSWindow makeKeyAndOrderFront:m_cocoaNSWindow];
280 }
281 else
282 [m_cocoaNSWindow orderOut:m_cocoaNSWindow];
283 m_isShown = show;
284 return true;
285 }
286
287 bool wxTopLevelWindowCocoa::Close(bool force)
288 {
289 if(force)
290 return wxWindowBase::Close(force);
291 // performClose will fake the user clicking the close button which
292 // will invoke windowShouldClose which will call the base class version
293 // of Close() which will NOT Destroy() the window (see below) but
294 // if closing is not stopped, then performClose will go ahead and
295 // close the window which will send the close notifications setting
296 // m_closed to true and Destroy()ing the window.
297 [m_cocoaNSWindow performClose:m_cocoaNSWindow];
298 return m_closed;
299 }
300
301 void wxTopLevelWindowCocoa::OnCloseWindow(wxCloseEvent& event)
302 {
303 // If the event was forced, close the window which will Destroy() it
304 if(!event.CanVeto())
305 [m_cocoaNSWindow close];
306 // if the event was not forced, it's probably because the user clicked
307 // the close button, or Close(false) was called which (see above) is
308 // redirected to performClose and thus Cocoa itself will close the window
309 }
310
311 // ----------------------------------------------------------------------------
312 // wxTopLevelWindowCocoa misc
313 // ----------------------------------------------------------------------------
314
315 bool wxTopLevelWindowCocoa::ShowFullScreen(bool show, long style)
316 {
317 return FALSE;
318 }
319
320 bool wxTopLevelWindowCocoa::IsFullScreen() const
321 {
322 return FALSE;
323 }
324
325 void wxTopLevelWindowCocoa::CocoaSetWxWindowSize(int width, int height)
326 {
327 // Set the NSView size by setting the frame size to enclose it
328 unsigned int styleMask = [m_cocoaNSWindow styleMask];
329 NSRect frameRect = [m_cocoaNSWindow frame];
330 NSRect contentRect = [NSWindow
331 contentRectForFrameRect: frameRect
332 styleMask: styleMask];
333 contentRect.size.width = width;
334 contentRect.size.height = height;
335 frameRect = [NSWindow
336 frameRectForContentRect: contentRect
337 styleMask: styleMask];
338 [m_cocoaNSWindow setFrame: frameRect display: NO];
339 }
340
341 void wxTopLevelWindowCocoa::DoMoveWindow(int x, int y, int width, int height)
342 {
343 // wxLogDebug("wxTopLevelWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height);
344
345 NSRect cocoaRect = NSMakeRect(x,y,width,height);
346 [m_cocoaNSWindow setFrame: cocoaRect display:NO];
347 }
348
349 void wxTopLevelWindowCocoa::DoGetSize(int *w, int *h) const
350 {
351 NSRect cocoaRect = [m_cocoaNSWindow frame];
352 if(w)
353 *w=(int)cocoaRect.size.width;
354 if(h)
355 *h=(int)cocoaRect.size.height;
356 // wxLogDebug("wxTopLevelWindow=%p::DoGetSize = (%d,%d)",this,(int)cocoaRect.size.width,(int)cocoaRect.size.height);
357 }
358
359 void wxTopLevelWindowCocoa::DoGetPosition(int *x, int *y) const
360 {
361 NSRect cocoaRect = [m_cocoaNSWindow frame];
362 if(x)
363 *x=(int)cocoaRect.origin.x;
364 if(y)
365 *y=(int)cocoaRect.origin.y;
366 // wxLogDebug("wxTopLevelWindow=%p::DoGetPosition = (%d,%d)",this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y);
367 }
368