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/mbarman.h"
34 #import <AppKit/NSView.h>
35 #import <AppKit/NSWindow.h>
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 // list of all frames and modeless dialogs
41 wxWindowList wxModelessWindows;
43 // ============================================================================
44 // wxTopLevelWindowCocoa implementation
45 // ============================================================================
47 // ----------------------------------------------------------------------------
48 // wxTopLevelWindowCocoa creation
49 // ----------------------------------------------------------------------------
50 BEGIN_EVENT_TABLE(wxTopLevelWindowCocoa,wxTopLevelWindowBase)
51 EVT_CLOSE(wxTopLevelWindowCocoa::OnCloseWindow)
54 void wxTopLevelWindowCocoa::Init()
61 bool wxTopLevelWindowCocoa::Create(wxWindow *parent,
63 const wxString& title,
69 wxAutoNSAutoreleasePool pool;
70 wxTopLevelWindows.Append(this);
72 if(!CreateBase(parent,winid,pos,size,style,wxDefaultValidator,name))
76 parent->AddChild(this);
78 // TODO: get rect from given position/size
79 NSRect cocoaRect = NSMakeRect(100,100,200,200);
81 // TODO: Set flags given wxWindows style
82 unsigned int cocoaStyle = 0;
83 cocoaStyle |= NSTitledWindowMask;
84 cocoaStyle |= NSClosableWindowMask;
85 cocoaStyle |= NSMiniaturizableWindowMask;
86 cocoaStyle |= NSResizableWindowMask;
88 m_cocoaNSWindow = NULL;
90 SetNSWindow([[NSWindow alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]);
91 // NOTE: SetNSWindow has retained the Cocoa object for this object.
92 // Because we do not release on close, the following release matches the
93 // above alloc and thus the retain count will be 1.
94 [m_cocoaNSWindow release];
99 wxTopLevelWindowCocoa::~wxTopLevelWindowCocoa()
101 wxAutoNSAutoreleasePool pool;
106 // ----------------------------------------------------------------------------
107 // wxTopLevelWindowCocoa Cocoa Specifics
108 // ----------------------------------------------------------------------------
110 void wxTopLevelWindowCocoa::SetNSWindow(WX_NSWindow cocoaNSWindow)
112 bool need_debug = cocoaNSWindow || m_cocoaNSWindow;
113 if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [m_cocoaNSWindow=%p retainCount]=%d",this,m_cocoaNSWindow,[m_cocoaNSWindow retainCount]);
114 DisassociateNSWindow(m_cocoaNSWindow);
115 [cocoaNSWindow retain];
116 [m_cocoaNSWindow release];
117 m_cocoaNSWindow = cocoaNSWindow;
119 SetNSView([m_cocoaNSWindow contentView]);
122 AssociateNSWindow(m_cocoaNSWindow);
123 if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [cocoaNSWindow=%p retainCount]=%d",this,cocoaNSWindow,[cocoaNSWindow retainCount]);
126 void wxTopLevelWindowCocoa::CocoaReplaceView(WX_NSView oldView, WX_NSView newView)
128 if([m_cocoaNSWindow contentView] == (id)oldView)
129 [m_cocoaNSWindow setContentView:newView];
132 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeKey(void)
134 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeKey",this);
135 wxMenuBarManager::GetInstance()->WindowDidBecomeKey(this);
136 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, GetId());
137 event.SetEventObject(this);
138 GetEventHandler()->ProcessEvent(event);
141 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey(void)
143 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignKey",this);
144 wxActivateEvent event(wxEVT_ACTIVATE, FALSE, GetId());
145 event.SetEventObject(this);
146 GetEventHandler()->ProcessEvent(event);
147 wxMenuBarManager::GetInstance()->WindowDidResignKey(this);
150 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeMain(void)
152 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeMain",this);
153 wxMenuBarManager::GetInstance()->WindowDidBecomeMain(this);
156 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignMain(void)
158 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignMain",this);
159 wxMenuBarManager::GetInstance()->WindowDidResignMain(this);
162 void wxTopLevelWindowCocoa::Cocoa_close(void)
166 /* Be SURE that idle events get ran. If the window was not active when
167 it was closed, then there will be no more events to trigger this and
168 therefore it must be done here */
169 wxTheApp->CocoaInstallRequestedIdleHandler();
172 bool wxTopLevelWindowCocoa::CocoaDelegate_windowShouldClose()
174 return wxWindowBase::Close(false);
177 // ----------------------------------------------------------------------------
178 // wxTopLevelWindowCocoa maximize/minimize
179 // ----------------------------------------------------------------------------
181 void wxTopLevelWindowCocoa::Maximize(bool maximize)
185 bool wxTopLevelWindowCocoa::IsMaximized() const
190 void wxTopLevelWindowCocoa::Iconize(bool iconize)
194 bool wxTopLevelWindowCocoa::IsIconized() const
199 void wxTopLevelWindowCocoa::Restore()
203 bool wxTopLevelWindowCocoa::Show(bool show)
205 if(m_isShown == show)
207 wxAutoNSAutoreleasePool pool;
210 // Send the window a size event because wxWindows apps expect it
211 // NOTE: This should really only be done the first time a window
212 // is shown. I doubt this will cause any problems though.
213 wxSizeEvent event(GetSize(), GetId());
214 event.SetEventObject(this);
215 GetEventHandler()->ProcessEvent(event);
217 [m_cocoaNSWindow makeKeyAndOrderFront:m_cocoaNSWindow];
220 [m_cocoaNSWindow orderOut:m_cocoaNSWindow];
225 bool wxTopLevelWindowCocoa::Close(bool force)
228 return wxWindowBase::Close(force);
229 // performClose will fake the user clicking the close button which
230 // will invoke windowShouldClose which will call the base class version
231 // of Close() which will NOT Destroy() the window (see below) but
232 // if closing is not stopped, then performClose will go ahead and
233 // close the window which will invoke Cocoa_close() setting m_closed
234 // to true and Destroy()ing the window.
235 [m_cocoaNSWindow performClose:m_cocoaNSWindow];
239 void wxTopLevelWindowCocoa::OnCloseWindow(wxCloseEvent& event)
241 // If the event was forced, close the window which will Destroy() it
243 [m_cocoaNSWindow close];
244 // if the event was not forced, it's probably because the user clicked
245 // the close button, or Close(false) was called which (see above) is
246 // redirected to performClose and thus Cocoa itself will close the window
249 // ----------------------------------------------------------------------------
250 // wxTopLevelWindowCocoa misc
251 // ----------------------------------------------------------------------------
253 bool wxTopLevelWindowCocoa::ShowFullScreen(bool show, long style)
258 bool wxTopLevelWindowCocoa::IsFullScreen() const
263 void wxTopLevelWindowCocoa::CocoaSetWxWindowSize(int width, int height)
265 // Set the NSView size by setting the frame size to enclose it
266 unsigned int styleMask = [m_cocoaNSWindow styleMask];
267 NSRect frameRect = [m_cocoaNSWindow frame];
268 NSRect contentRect = [NSWindow
269 contentRectForFrameRect: frameRect
270 styleMask: styleMask];
271 contentRect.size.width = width;
272 contentRect.size.height = height;
273 frameRect = [NSWindow
274 frameRectForContentRect: contentRect
275 styleMask: styleMask];
276 [m_cocoaNSWindow setFrame: frameRect display: NO];
279 void wxTopLevelWindowCocoa::DoMoveWindow(int x, int y, int width, int height)
281 // wxLogDebug("wxTopLevelWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height);
283 NSRect cocoaRect = NSMakeRect(x,y,width,height);
284 [m_cocoaNSWindow setFrame: cocoaRect display:NO];
287 void wxTopLevelWindowCocoa::DoGetSize(int *w, int *h) const
289 NSRect cocoaRect = [m_cocoaNSWindow frame];
291 *w=(int)cocoaRect.size.width;
293 *h=(int)cocoaRect.size.height;
294 // wxLogDebug("wxTopLevelWindow=%p::DoGetSize = (%d,%d)",this,(int)cocoaRect.size.width,(int)cocoaRect.size.height);
297 void wxTopLevelWindowCocoa::DoGetPosition(int *x, int *y) const
299 NSRect cocoaRect = [m_cocoaNSWindow frame];
301 *x=(int)cocoaRect.origin.x;
303 *y=(int)cocoaRect.origin.y;
304 // wxLogDebug("wxTopLevelWindow=%p::DoGetPosition = (%d,%d)",this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y);