Put wxAutoNSAutoreleasePool in methods that may be used outside the run loop.
[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     // Hand ownership of the content view to wxWindow so it can destroy
102     // itself properly.
103     NSView *view = [m_cocoaNSView retain];
104     SetNSWindow(NULL);
105     SetNSView(view);
106     [view release];
107 }
108
109 // ----------------------------------------------------------------------------
110 // wxTopLevelWindowCocoa Cocoa Specifics
111 // ----------------------------------------------------------------------------
112
113 void wxTopLevelWindowCocoa::SetNSWindow(WX_NSWindow cocoaNSWindow)
114 {
115     bool need_debug = cocoaNSWindow || m_cocoaNSWindow;
116     if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [m_cocoaNSWindow=%p retainCount]=%d",this,m_cocoaNSWindow,[m_cocoaNSWindow retainCount]);
117     DisassociateNSWindow(m_cocoaNSWindow);
118     [cocoaNSWindow retain];
119     [m_cocoaNSWindow release];
120     m_cocoaNSWindow = cocoaNSWindow;
121     if(m_cocoaNSWindow)
122         SetNSView([m_cocoaNSWindow contentView]);
123     else
124         SetNSView(NULL);
125     AssociateNSWindow(m_cocoaNSWindow);
126     if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [cocoaNSWindow=%p retainCount]=%d",this,cocoaNSWindow,[cocoaNSWindow retainCount]);
127 }
128
129 void wxTopLevelWindowCocoa::Cocoa_wxMenuItemAction(wxMenuItem& item)
130 {
131 }
132
133 void wxTopLevelWindowCocoa::Cocoa_close(void)
134 {
135     m_closed = true;
136     Destroy();
137     /* Be SURE that idle events get ran.  If the window was not active when
138     it was closed, then there will be no more events to trigger this and
139     therefore it must be done here */
140     wxTheApp->CocoaInstallRequestedIdleHandler();
141 }
142
143 bool wxTopLevelWindowCocoa::Cocoa_windowShouldClose()
144 {
145     return wxWindowBase::Close(false);
146 }
147
148 // ----------------------------------------------------------------------------
149 // wxTopLevelWindowCocoa maximize/minimize
150 // ----------------------------------------------------------------------------
151
152 void wxTopLevelWindowCocoa::Maximize(bool maximize)
153 {
154 }
155
156 bool wxTopLevelWindowCocoa::IsMaximized() const
157 {
158     return false ; 
159 }
160
161 void wxTopLevelWindowCocoa::Iconize(bool iconize)
162 {
163 }
164
165 bool wxTopLevelWindowCocoa::IsIconized() const
166 {
167     return FALSE;
168 }
169
170 void wxTopLevelWindowCocoa::Restore()
171 {
172 }
173
174 bool wxTopLevelWindowCocoa::Show(bool show)
175 {
176     wxAutoNSAutoreleasePool pool;
177     if(show)
178         [m_cocoaNSWindow makeKeyAndOrderFront:m_cocoaNSWindow];
179     else
180         [m_cocoaNSWindow orderOut:m_cocoaNSWindow];
181     return true;
182 }
183
184 bool wxTopLevelWindowCocoa::Close(bool force)
185 {
186     if(force)
187         return wxWindowBase::Close(force);
188     // performClose  will fake the user clicking the close button which
189     // will invoke windowShouldClose which will call the base class version
190     // of Close() which will NOT Destroy() the window (see below) but
191     // if closing is not stopped, then performClose will go ahead and
192     // close the window which will invoke Cocoa_close() setting m_closed
193     // to true and Destroy()ing the window.
194     [m_cocoaNSWindow performClose:m_cocoaNSWindow];
195     return m_closed;
196 }
197
198 void wxTopLevelWindowCocoa::OnCloseWindow(wxCloseEvent& event)
199 {
200     // If the event was forced, close the window which will Destroy() it
201     if(!event.CanVeto())
202         [m_cocoaNSWindow close];
203     // if the event was not forced, it's probably because the user clicked
204     // the close button, or Close(false) was called which (see above) is
205     // redirected to performClose and thus Cocoa itself will close the window
206 }
207
208 // ----------------------------------------------------------------------------
209 // wxTopLevelWindowCocoa misc
210 // ----------------------------------------------------------------------------
211
212 bool wxTopLevelWindowCocoa::ShowFullScreen(bool show, long style)
213 {
214     return FALSE;
215 }
216
217 bool wxTopLevelWindowCocoa::IsFullScreen() const
218 {
219     return FALSE;
220 }
221
222 void wxTopLevelWindowCocoa::DoMoveWindow(int x, int y, int width, int height)
223 {
224     wxLogDebug("wxTopLevelWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height);
225
226     NSRect cocoaRect = NSMakeRect(x,y,width,height);
227     [m_cocoaNSWindow setFrame: cocoaRect display:NO];
228 }
229
230 void wxTopLevelWindowCocoa::DoGetSize(int *w, int *h) const
231 {
232     NSRect cocoaRect = [m_cocoaNSWindow frame];
233     if(w)
234         *w=(int)cocoaRect.size.width;
235     if(h)
236         *h=(int)cocoaRect.size.height;
237     wxLogDebug("wxTopLevelWindow=%p::DoGetSize = (%d,%d)",this,(int)cocoaRect.size.width,(int)cocoaRect.size.height);
238 }
239
240 void wxTopLevelWindowCocoa::DoGetPosition(int *x, int *y) const
241 {
242     NSRect cocoaRect = [m_cocoaNSWindow frame];
243     if(x)
244         *x=(int)cocoaRect.origin.x;
245     if(y)
246         *y=(int)cocoaRect.origin.y;
247     wxLogDebug("wxTopLevelWindow=%p::DoGetPosition = (%d,%d)",this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y);
248 }
249