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"
32 #include "wx/cocoa/string.h"
33 #include "wx/cocoa/mbarman.h"
35 #import <AppKit/NSView.h>
36 #import <AppKit/NSWindow.h>
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
41 // list of all frames and modeless dialogs
42 wxWindowList wxModelessWindows;
44 // ============================================================================
45 // wxTopLevelWindowCocoa implementation
46 // ============================================================================
48 // ----------------------------------------------------------------------------
49 // wxTopLevelWindowCocoa creation
50 // ----------------------------------------------------------------------------
51 BEGIN_EVENT_TABLE(wxTopLevelWindowCocoa,wxTopLevelWindowBase)
52 EVT_CLOSE(wxTopLevelWindowCocoa::OnCloseWindow)
55 void wxTopLevelWindowCocoa::Init()
62 bool wxTopLevelWindowCocoa::Create(wxWindow *parent,
64 const wxString& title,
70 wxAutoNSAutoreleasePool pool;
71 wxTopLevelWindows.Append(this);
73 if(!CreateBase(parent,winid,pos,size,style,wxDefaultValidator,name))
77 parent->AddChild(this);
79 // TODO: get rect from given position/size
80 NSRect cocoaRect = NSMakeRect(100,100,200,200);
82 // TODO: Set flags given wxWindows style
83 unsigned int cocoaStyle = 0;
84 cocoaStyle |= NSTitledWindowMask;
85 cocoaStyle |= NSClosableWindowMask;
86 cocoaStyle |= NSMiniaturizableWindowMask;
87 cocoaStyle |= NSResizableWindowMask;
89 m_cocoaNSWindow = 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];
97 [m_cocoaNSWindow setTitle:wxNSStringWithWxString(title)];
101 wxTopLevelWindowCocoa::~wxTopLevelWindowCocoa()
103 wxAutoNSAutoreleasePool pool;
108 // ----------------------------------------------------------------------------
109 // wxTopLevelWindowCocoa Cocoa Specifics
110 // ----------------------------------------------------------------------------
112 void wxTopLevelWindowCocoa::SetNSWindow(WX_NSWindow cocoaNSWindow)
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;
121 SetNSView([m_cocoaNSWindow contentView]);
124 AssociateNSWindow(m_cocoaNSWindow);
125 if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [cocoaNSWindow=%p retainCount]=%d",this,cocoaNSWindow,[cocoaNSWindow retainCount]);
128 void wxTopLevelWindowCocoa::CocoaReplaceView(WX_NSView oldView, WX_NSView newView)
130 if([m_cocoaNSWindow contentView] == (id)oldView)
131 [m_cocoaNSWindow setContentView:newView];
134 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeKey(void)
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);
143 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey(void)
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);
152 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeMain(void)
154 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeMain",this);
155 wxMenuBarManager::GetInstance()->WindowDidBecomeMain(this);
158 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignMain(void)
160 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignMain",this);
161 wxMenuBarManager::GetInstance()->WindowDidResignMain(this);
164 void wxTopLevelWindowCocoa::Cocoa_close(void)
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();
174 bool wxTopLevelWindowCocoa::CocoaDelegate_windowShouldClose()
176 return wxWindowBase::Close(false);
179 // ----------------------------------------------------------------------------
180 // wxTopLevelWindowCocoa maximize/minimize
181 // ----------------------------------------------------------------------------
183 void wxTopLevelWindowCocoa::Maximize(bool maximize)
187 bool wxTopLevelWindowCocoa::IsMaximized() const
192 void wxTopLevelWindowCocoa::Iconize(bool iconize)
196 bool wxTopLevelWindowCocoa::IsIconized() const
201 void wxTopLevelWindowCocoa::Restore()
205 bool wxTopLevelWindowCocoa::Show(bool show)
207 if(m_isShown == show)
209 wxAutoNSAutoreleasePool pool;
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);
219 [m_cocoaNSWindow makeKeyAndOrderFront:m_cocoaNSWindow];
222 [m_cocoaNSWindow orderOut:m_cocoaNSWindow];
227 bool wxTopLevelWindowCocoa::Close(bool 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];
241 void wxTopLevelWindowCocoa::OnCloseWindow(wxCloseEvent& event)
243 // If the event was forced, close the window which will Destroy() it
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
251 // ----------------------------------------------------------------------------
252 // wxTopLevelWindowCocoa misc
253 // ----------------------------------------------------------------------------
255 bool wxTopLevelWindowCocoa::ShowFullScreen(bool show, long style)
260 bool wxTopLevelWindowCocoa::IsFullScreen() const
265 void wxTopLevelWindowCocoa::CocoaSetWxWindowSize(int width, int height)
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];
281 void wxTopLevelWindowCocoa::DoMoveWindow(int x, int y, int width, int height)
283 // wxLogDebug("wxTopLevelWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height);
285 NSRect cocoaRect = NSMakeRect(x,y,width,height);
286 [m_cocoaNSWindow setFrame: cocoaRect display:NO];
289 void wxTopLevelWindowCocoa::DoGetSize(int *w, int *h) const
291 NSRect cocoaRect = [m_cocoaNSWindow frame];
293 *w=(int)cocoaRect.size.width;
295 *h=(int)cocoaRect.size.height;
296 // wxLogDebug("wxTopLevelWindow=%p::DoGetSize = (%d,%d)",this,(int)cocoaRect.size.width,(int)cocoaRect.size.height);
299 void wxTopLevelWindowCocoa::DoGetPosition(int *x, int *y) const
301 NSRect cocoaRect = [m_cocoaNSWindow frame];
303 *x=(int)cocoaRect.origin.x;
305 *y=(int)cocoaRect.origin.y;
306 // wxLogDebug("wxTopLevelWindow=%p::DoGetPosition = (%d,%d)",this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y);