]> git.saurik.com Git - wxWidgets.git/blob - src/cocoa/toplevel.mm
39fa6a5b2555dd16f47c4a5b83481ec2948757e5
[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 // License: wxWindows license
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/mbarman.h"
33
34 #import <AppKit/NSView.h>
35 #import <AppKit/NSWindow.h>
36 // ----------------------------------------------------------------------------
37 // globals
38 // ----------------------------------------------------------------------------
39
40 // list of all frames and modeless dialogs
41 wxWindowList wxModelessWindows;
42
43 // ============================================================================
44 // wxTopLevelWindowCocoa implementation
45 // ============================================================================
46
47 // ----------------------------------------------------------------------------
48 // wxTopLevelWindowCocoa creation
49 // ----------------------------------------------------------------------------
50 BEGIN_EVENT_TABLE(wxTopLevelWindowCocoa,wxTopLevelWindowBase)
51 EVT_CLOSE(wxTopLevelWindowCocoa::OnCloseWindow)
52 END_EVENT_TABLE()
53
54 void wxTopLevelWindowCocoa::Init()
55 {
56 m_iconized =
57 m_maximizeOnShow =
58 m_closed = false;
59 }
60
61 bool wxTopLevelWindowCocoa::Create(wxWindow *parent,
62 wxWindowID winid,
63 const wxString& title,
64 const wxPoint& pos,
65 const wxSize& size,
66 long style,
67 const wxString& name)
68 {
69 wxAutoNSAutoreleasePool pool;
70 wxTopLevelWindows.Append(this);
71
72 if(!CreateBase(parent,winid,pos,size,style,wxDefaultValidator,name))
73 return FALSE;
74
75 if ( parent )
76 parent->AddChild(this);
77
78 // TODO: get rect from given position/size
79 NSRect cocoaRect = NSMakeRect(100,100,200,200);
80
81 // TODO: Set flags given wxWindows style
82 unsigned int cocoaStyle = 0;
83 cocoaStyle |= NSTitledWindowMask;
84 cocoaStyle |= NSClosableWindowMask;
85 cocoaStyle |= NSMiniaturizableWindowMask;
86 cocoaStyle |= NSResizableWindowMask;
87
88 m_cocoaNSWindow = NULL;
89 m_cocoaNSView = NULL;
90 SetNSWindow([[NSWindow alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]);
91 // NOTE: SetNSWindow has retained the Cocoa object for this object.
92 // Because we do not release on close, the following release matches the
93 // above alloc and thus the retain count will be 1.
94 [m_cocoaNSWindow release];
95
96 return TRUE;
97 }
98
99 wxTopLevelWindowCocoa::~wxTopLevelWindowCocoa()
100 {
101 wxAutoNSAutoreleasePool pool;
102 DestroyChildren();
103 SetNSWindow(NULL);
104 }
105
106 // ----------------------------------------------------------------------------
107 // wxTopLevelWindowCocoa Cocoa Specifics
108 // ----------------------------------------------------------------------------
109
110 void wxTopLevelWindowCocoa::SetNSWindow(WX_NSWindow cocoaNSWindow)
111 {
112 bool need_debug = cocoaNSWindow || m_cocoaNSWindow;
113 if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [m_cocoaNSWindow=%p retainCount]=%d",this,m_cocoaNSWindow,[m_cocoaNSWindow retainCount]);
114 DisassociateNSWindow(m_cocoaNSWindow);
115 [cocoaNSWindow retain];
116 [m_cocoaNSWindow release];
117 m_cocoaNSWindow = cocoaNSWindow;
118 if(m_cocoaNSWindow)
119 SetNSView([m_cocoaNSWindow contentView]);
120 else
121 SetNSView(NULL);
122 AssociateNSWindow(m_cocoaNSWindow);
123 if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [cocoaNSWindow=%p retainCount]=%d",this,cocoaNSWindow,[cocoaNSWindow retainCount]);
124 }
125
126 void wxTopLevelWindowCocoa::CocoaReplaceView(WX_NSView oldView, WX_NSView newView)
127 {
128 if([m_cocoaNSWindow contentView] == (id)oldView)
129 [m_cocoaNSWindow setContentView:newView];
130 }
131
132 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeKey(void)
133 {
134 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeKey",this);
135 wxMenuBarManager::GetInstance()->WindowDidBecomeKey(this);
136 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, GetId());
137 event.SetEventObject(this);
138 GetEventHandler()->ProcessEvent(event);
139 }
140
141 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey(void)
142 {
143 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignKey",this);
144 wxActivateEvent event(wxEVT_ACTIVATE, FALSE, GetId());
145 event.SetEventObject(this);
146 GetEventHandler()->ProcessEvent(event);
147 wxMenuBarManager::GetInstance()->WindowDidResignKey(this);
148 }
149
150 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeMain(void)
151 {
152 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeMain",this);
153 wxMenuBarManager::GetInstance()->WindowDidBecomeMain(this);
154 }
155
156 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignMain(void)
157 {
158 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignMain",this);
159 wxMenuBarManager::GetInstance()->WindowDidResignMain(this);
160 }
161
162 void wxTopLevelWindowCocoa::Cocoa_close(void)
163 {
164 m_closed = true;
165 Destroy();
166 /* Be SURE that idle events get ran. If the window was not active when
167 it was closed, then there will be no more events to trigger this and
168 therefore it must be done here */
169 wxTheApp->CocoaInstallRequestedIdleHandler();
170 }
171
172 bool wxTopLevelWindowCocoa::CocoaDelegate_windowShouldClose()
173 {
174 return wxWindowBase::Close(false);
175 }
176
177 // ----------------------------------------------------------------------------
178 // wxTopLevelWindowCocoa maximize/minimize
179 // ----------------------------------------------------------------------------
180
181 void wxTopLevelWindowCocoa::Maximize(bool maximize)
182 {
183 }
184
185 bool wxTopLevelWindowCocoa::IsMaximized() const
186 {
187 return false ;
188 }
189
190 void wxTopLevelWindowCocoa::Iconize(bool iconize)
191 {
192 }
193
194 bool wxTopLevelWindowCocoa::IsIconized() const
195 {
196 return FALSE;
197 }
198
199 void wxTopLevelWindowCocoa::Restore()
200 {
201 }
202
203 bool wxTopLevelWindowCocoa::Show(bool show)
204 {
205 if(m_isShown == show)
206 return false;
207 wxAutoNSAutoreleasePool pool;
208 if(show)
209 {
210 // Send the window a size event because wxWindows apps expect it
211 // NOTE: This should really only be done the first time a window
212 // is shown. I doubt this will cause any problems though.
213 wxSizeEvent event(GetSize(), GetId());
214 event.SetEventObject(this);
215 GetEventHandler()->ProcessEvent(event);
216
217 [m_cocoaNSWindow makeKeyAndOrderFront:m_cocoaNSWindow];
218 }
219 else
220 [m_cocoaNSWindow orderOut:m_cocoaNSWindow];
221 m_isShown = show;
222 return true;
223 }
224
225 bool wxTopLevelWindowCocoa::Close(bool force)
226 {
227 if(force)
228 return wxWindowBase::Close(force);
229 // performClose will fake the user clicking the close button which
230 // will invoke windowShouldClose which will call the base class version
231 // of Close() which will NOT Destroy() the window (see below) but
232 // if closing is not stopped, then performClose will go ahead and
233 // close the window which will invoke Cocoa_close() setting m_closed
234 // to true and Destroy()ing the window.
235 [m_cocoaNSWindow performClose:m_cocoaNSWindow];
236 return m_closed;
237 }
238
239 void wxTopLevelWindowCocoa::OnCloseWindow(wxCloseEvent& event)
240 {
241 // If the event was forced, close the window which will Destroy() it
242 if(!event.CanVeto())
243 [m_cocoaNSWindow close];
244 // if the event was not forced, it's probably because the user clicked
245 // the close button, or Close(false) was called which (see above) is
246 // redirected to performClose and thus Cocoa itself will close the window
247 }
248
249 // ----------------------------------------------------------------------------
250 // wxTopLevelWindowCocoa misc
251 // ----------------------------------------------------------------------------
252
253 bool wxTopLevelWindowCocoa::ShowFullScreen(bool show, long style)
254 {
255 return FALSE;
256 }
257
258 bool wxTopLevelWindowCocoa::IsFullScreen() const
259 {
260 return FALSE;
261 }
262
263 void wxTopLevelWindowCocoa::CocoaSetWxWindowSize(int width, int height)
264 {
265 // Set the NSView size by setting the frame size to enclose it
266 unsigned int styleMask = [m_cocoaNSWindow styleMask];
267 NSRect frameRect = [m_cocoaNSWindow frame];
268 NSRect contentRect = [NSWindow
269 contentRectForFrameRect: frameRect
270 styleMask: styleMask];
271 contentRect.size.width = width;
272 contentRect.size.height = height;
273 frameRect = [NSWindow
274 frameRectForContentRect: contentRect
275 styleMask: styleMask];
276 [m_cocoaNSWindow setFrame: frameRect display: NO];
277 }
278
279 void wxTopLevelWindowCocoa::DoMoveWindow(int x, int y, int width, int height)
280 {
281 // wxLogDebug("wxTopLevelWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height);
282
283 NSRect cocoaRect = NSMakeRect(x,y,width,height);
284 [m_cocoaNSWindow setFrame: cocoaRect display:NO];
285 }
286
287 void wxTopLevelWindowCocoa::DoGetSize(int *w, int *h) const
288 {
289 NSRect cocoaRect = [m_cocoaNSWindow frame];
290 if(w)
291 *w=(int)cocoaRect.size.width;
292 if(h)
293 *h=(int)cocoaRect.size.height;
294 // wxLogDebug("wxTopLevelWindow=%p::DoGetSize = (%d,%d)",this,(int)cocoaRect.size.width,(int)cocoaRect.size.height);
295 }
296
297 void wxTopLevelWindowCocoa::DoGetPosition(int *x, int *y) const
298 {
299 NSRect cocoaRect = [m_cocoaNSWindow frame];
300 if(x)
301 *x=(int)cocoaRect.origin.x;
302 if(y)
303 *y=(int)cocoaRect.origin.y;
304 // wxLogDebug("wxTopLevelWindow=%p::DoGetPosition = (%d,%d)",this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y);
305 }
306