1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: cocoa/toplevel.mm
3 // Purpose: implements wxTopLevelWindow for Cocoa
4 // Author: David Elliott
8 // Copyright: (c) 2002 David Elliott
9 // License: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
23 #include "wx/window.h"
24 #include "wx/toplevel.h"
25 #include "wx/menuitem.h"
31 #include "wx/cocoa/autorelease.h"
33 #import <AppKit/NSView.h>
34 #import <AppKit/NSWindow.h>
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 // list of all frames and modeless dialogs
40 wxWindowList wxModelessWindows;
42 // ============================================================================
43 // wxTopLevelWindowCocoa implementation
44 // ============================================================================
46 // ----------------------------------------------------------------------------
47 // wxTopLevelWindowCocoa creation
48 // ----------------------------------------------------------------------------
49 BEGIN_EVENT_TABLE(wxTopLevelWindowCocoa,wxTopLevelWindowBase)
50 EVT_CLOSE(wxTopLevelWindowCocoa::OnCloseWindow)
53 void wxTopLevelWindowCocoa::Init()
60 bool wxTopLevelWindowCocoa::Create(wxWindow *parent,
62 const wxString& title,
68 wxAutoNSAutoreleasePool pool;
69 wxTopLevelWindows.Append(this);
71 if(!CreateBase(parent,winid,pos,size,style,wxDefaultValidator,name))
75 parent->AddChild(this);
77 // TODO: get rect from given position/size
78 NSRect cocoaRect = NSMakeRect(100,100,200,200);
80 // TODO: Set flags given wxWindows style
81 unsigned int cocoaStyle = 0;
82 cocoaStyle |= NSTitledWindowMask;
83 cocoaStyle |= NSClosableWindowMask;
84 cocoaStyle |= NSMiniaturizableWindowMask;
85 cocoaStyle |= NSResizableWindowMask;
87 m_cocoaNSWindow = 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];
98 wxTopLevelWindowCocoa::~wxTopLevelWindowCocoa()
100 wxAutoNSAutoreleasePool pool;
105 // ----------------------------------------------------------------------------
106 // wxTopLevelWindowCocoa Cocoa Specifics
107 // ----------------------------------------------------------------------------
109 void wxTopLevelWindowCocoa::SetNSWindow(WX_NSWindow cocoaNSWindow)
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;
118 SetNSView([m_cocoaNSWindow contentView]);
121 AssociateNSWindow(m_cocoaNSWindow);
122 if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [cocoaNSWindow=%p retainCount]=%d",this,cocoaNSWindow,[cocoaNSWindow retainCount]);
125 void wxTopLevelWindowCocoa::CocoaReplaceView(WX_NSView oldView, WX_NSView newView)
127 if([m_cocoaNSWindow contentView] == oldView)
128 [m_cocoaNSWindow setContentView:newView];
131 void wxTopLevelWindowCocoa::Cocoa_wxMenuItemAction(wxMenuItem& item)
135 void wxTopLevelWindowCocoa::CocoaNotification_DidBecomeKey(void)
137 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaNotification_DidBecomeKey",this);
138 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, GetId());
139 event.SetEventObject(this);
140 GetEventHandler()->ProcessEvent(event);
143 void wxTopLevelWindowCocoa::CocoaNotification_DidResignKey(void)
145 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaNotification_DidResignKey",this);
146 wxActivateEvent event(wxEVT_ACTIVATE, FALSE, GetId());
147 event.SetEventObject(this);
148 GetEventHandler()->ProcessEvent(event);
151 void wxTopLevelWindowCocoa::Cocoa_close(void)
155 /* Be SURE that idle events get ran. If the window was not active when
156 it was closed, then there will be no more events to trigger this and
157 therefore it must be done here */
158 wxTheApp->CocoaInstallRequestedIdleHandler();
161 bool wxTopLevelWindowCocoa::Cocoa_windowShouldClose()
163 return wxWindowBase::Close(false);
166 // ----------------------------------------------------------------------------
167 // wxTopLevelWindowCocoa maximize/minimize
168 // ----------------------------------------------------------------------------
170 void wxTopLevelWindowCocoa::Maximize(bool maximize)
174 bool wxTopLevelWindowCocoa::IsMaximized() const
179 void wxTopLevelWindowCocoa::Iconize(bool iconize)
183 bool wxTopLevelWindowCocoa::IsIconized() const
188 void wxTopLevelWindowCocoa::Restore()
192 bool wxTopLevelWindowCocoa::Show(bool show)
194 wxAutoNSAutoreleasePool pool;
197 // Send the window a size event because wxWindows apps expect it
198 // NOTE: This should really only be done the first time a window
199 // is shown. I doubt this will cause any problems though.
200 wxSizeEvent event(GetSize(), GetId());
201 event.SetEventObject(this);
202 GetEventHandler()->ProcessEvent(event);
204 [m_cocoaNSWindow makeKeyAndOrderFront:m_cocoaNSWindow];
207 [m_cocoaNSWindow orderOut:m_cocoaNSWindow];
211 bool wxTopLevelWindowCocoa::Close(bool force)
214 return wxWindowBase::Close(force);
215 // performClose will fake the user clicking the close button which
216 // will invoke windowShouldClose which will call the base class version
217 // of Close() which will NOT Destroy() the window (see below) but
218 // if closing is not stopped, then performClose will go ahead and
219 // close the window which will invoke Cocoa_close() setting m_closed
220 // to true and Destroy()ing the window.
221 [m_cocoaNSWindow performClose:m_cocoaNSWindow];
225 void wxTopLevelWindowCocoa::OnCloseWindow(wxCloseEvent& event)
227 // If the event was forced, close the window which will Destroy() it
229 [m_cocoaNSWindow close];
230 // if the event was not forced, it's probably because the user clicked
231 // the close button, or Close(false) was called which (see above) is
232 // redirected to performClose and thus Cocoa itself will close the window
235 // ----------------------------------------------------------------------------
236 // wxTopLevelWindowCocoa misc
237 // ----------------------------------------------------------------------------
239 bool wxTopLevelWindowCocoa::ShowFullScreen(bool show, long style)
244 bool wxTopLevelWindowCocoa::IsFullScreen() const
249 void wxTopLevelWindowCocoa::CocoaSetWxWindowSize(int width, int height)
251 // Set the NSView size by setting the frame size to enclose it
252 unsigned int styleMask = [m_cocoaNSWindow styleMask];
253 NSRect frameRect = [m_cocoaNSWindow frame];
254 NSRect contentRect = [NSWindow
255 contentRectForFrameRect: frameRect
256 styleMask: styleMask];
257 contentRect.size.width = width;
258 contentRect.size.height = height;
259 frameRect = [NSWindow
260 frameRectForContentRect: contentRect
261 styleMask: styleMask];
262 [m_cocoaNSWindow setFrame: frameRect display: NO];
265 void wxTopLevelWindowCocoa::DoMoveWindow(int x, int y, int width, int height)
267 // wxLogDebug("wxTopLevelWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height);
269 NSRect cocoaRect = NSMakeRect(x,y,width,height);
270 [m_cocoaNSWindow setFrame: cocoaRect display:NO];
273 void wxTopLevelWindowCocoa::DoGetSize(int *w, int *h) const
275 NSRect cocoaRect = [m_cocoaNSWindow frame];
277 *w=(int)cocoaRect.size.width;
279 *h=(int)cocoaRect.size.height;
280 // wxLogDebug("wxTopLevelWindow=%p::DoGetSize = (%d,%d)",this,(int)cocoaRect.size.width,(int)cocoaRect.size.height);
283 void wxTopLevelWindowCocoa::DoGetPosition(int *x, int *y) const
285 NSRect cocoaRect = [m_cocoaNSWindow frame];
287 *x=(int)cocoaRect.origin.x;
289 *y=(int)cocoaRect.origin.y;
290 // wxLogDebug("wxTopLevelWindow=%p::DoGetPosition = (%d,%d)",this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y);