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