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