Set the window's title
[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 #include "wx/cocoa/string.h"
33 #include "wx/cocoa/mbarman.h"
34
35 #import <AppKit/NSView.h>
36 #import <AppKit/NSWindow.h>
37 // ----------------------------------------------------------------------------
38 // globals
39 // ----------------------------------------------------------------------------
40
41 // list of all frames and modeless dialogs
42 wxWindowList       wxModelessWindows;
43
44 // ============================================================================
45 // wxTopLevelWindowCocoa implementation
46 // ============================================================================
47
48 // ----------------------------------------------------------------------------
49 // wxTopLevelWindowCocoa creation
50 // ----------------------------------------------------------------------------
51 BEGIN_EVENT_TABLE(wxTopLevelWindowCocoa,wxTopLevelWindowBase)
52     EVT_CLOSE(wxTopLevelWindowCocoa::OnCloseWindow)
53 END_EVENT_TABLE()
54
55 void wxTopLevelWindowCocoa::Init()
56 {
57     m_iconized =
58     m_maximizeOnShow =
59     m_closed = false;
60 }
61
62 bool wxTopLevelWindowCocoa::Create(wxWindow *parent,
63                                  wxWindowID winid,
64                                  const wxString& title,
65                                  const wxPoint& pos,
66                                  const wxSize& size,
67                                  long style,
68                                  const wxString& name)
69 {
70     wxAutoNSAutoreleasePool pool;
71     wxTopLevelWindows.Append(this);
72
73     if(!CreateBase(parent,winid,pos,size,style,wxDefaultValidator,name))
74         return FALSE;
75
76     if ( parent )
77         parent->AddChild(this);
78
79     // TODO: get rect from given position/size
80     NSRect cocoaRect =  NSMakeRect(100,100,200,200);
81
82     // TODO: Set flags given wxWindows style
83     unsigned int cocoaStyle = 0;
84     cocoaStyle |= NSTitledWindowMask;
85     cocoaStyle |= NSClosableWindowMask;
86     cocoaStyle |= NSMiniaturizableWindowMask;
87     cocoaStyle |= NSResizableWindowMask;
88
89     m_cocoaNSWindow = NULL;
90     m_cocoaNSView = 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];
96
97     [m_cocoaNSWindow setTitle:wxNSStringWithWxString(title)];
98     return TRUE;
99 }
100
101 wxTopLevelWindowCocoa::~wxTopLevelWindowCocoa()
102 {
103     wxAutoNSAutoreleasePool pool;
104     DestroyChildren();
105     SetNSWindow(NULL);
106 }
107
108 // ----------------------------------------------------------------------------
109 // wxTopLevelWindowCocoa Cocoa Specifics
110 // ----------------------------------------------------------------------------
111
112 void wxTopLevelWindowCocoa::SetNSWindow(WX_NSWindow cocoaNSWindow)
113 {
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;
120     if(m_cocoaNSWindow)
121         SetNSView([m_cocoaNSWindow contentView]);
122     else
123         SetNSView(NULL);
124     AssociateNSWindow(m_cocoaNSWindow);
125     if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [cocoaNSWindow=%p retainCount]=%d",this,cocoaNSWindow,[cocoaNSWindow retainCount]);
126 }
127
128 void wxTopLevelWindowCocoa::CocoaReplaceView(WX_NSView oldView, WX_NSView newView)
129 {
130     if([m_cocoaNSWindow contentView] == (id)oldView)
131         [m_cocoaNSWindow setContentView:newView];
132 }
133
134 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeKey(void)
135 {
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);
141 }
142
143 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey(void)
144 {
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);
150 }
151
152 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeMain(void)
153 {
154     wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeMain",this);
155     wxMenuBarManager::GetInstance()->WindowDidBecomeMain(this);
156 }
157
158 void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignMain(void)
159 {
160     wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignMain",this);
161     wxMenuBarManager::GetInstance()->WindowDidResignMain(this);
162 }
163
164 void wxTopLevelWindowCocoa::Cocoa_close(void)
165 {
166     m_closed = true;
167     Destroy();
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();
172 }
173
174 bool wxTopLevelWindowCocoa::CocoaDelegate_windowShouldClose()
175 {
176     return wxWindowBase::Close(false);
177 }
178
179 // ----------------------------------------------------------------------------
180 // wxTopLevelWindowCocoa maximize/minimize
181 // ----------------------------------------------------------------------------
182
183 void wxTopLevelWindowCocoa::Maximize(bool maximize)
184 {
185 }
186
187 bool wxTopLevelWindowCocoa::IsMaximized() const
188 {
189     return false ; 
190 }
191
192 void wxTopLevelWindowCocoa::Iconize(bool iconize)
193 {
194 }
195
196 bool wxTopLevelWindowCocoa::IsIconized() const
197 {
198     return FALSE;
199 }
200
201 void wxTopLevelWindowCocoa::Restore()
202 {
203 }
204
205 bool wxTopLevelWindowCocoa::Show(bool show)
206 {
207     if(m_isShown == show)
208         return false;
209     wxAutoNSAutoreleasePool pool;
210     if(show)
211     {
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);
218
219         [m_cocoaNSWindow makeKeyAndOrderFront:m_cocoaNSWindow];
220     }
221     else
222         [m_cocoaNSWindow orderOut:m_cocoaNSWindow];
223     m_isShown = show;
224     return true;
225 }
226
227 bool wxTopLevelWindowCocoa::Close(bool force)
228 {
229     if(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];
238     return m_closed;
239 }
240
241 void wxTopLevelWindowCocoa::OnCloseWindow(wxCloseEvent& event)
242 {
243     // If the event was forced, close the window which will Destroy() it
244     if(!event.CanVeto())
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
249 }
250
251 // ----------------------------------------------------------------------------
252 // wxTopLevelWindowCocoa misc
253 // ----------------------------------------------------------------------------
254
255 bool wxTopLevelWindowCocoa::ShowFullScreen(bool show, long style)
256 {
257     return FALSE;
258 }
259
260 bool wxTopLevelWindowCocoa::IsFullScreen() const
261 {
262     return FALSE;
263 }
264
265 void wxTopLevelWindowCocoa::CocoaSetWxWindowSize(int width, int height)
266 {
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];
279 }
280
281 void wxTopLevelWindowCocoa::DoMoveWindow(int x, int y, int width, int height)
282 {
283 //    wxLogDebug("wxTopLevelWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height);
284
285     NSRect cocoaRect = NSMakeRect(x,y,width,height);
286     [m_cocoaNSWindow setFrame: cocoaRect display:NO];
287 }
288
289 void wxTopLevelWindowCocoa::DoGetSize(int *w, int *h) const
290 {
291     NSRect cocoaRect = [m_cocoaNSWindow frame];
292     if(w)
293         *w=(int)cocoaRect.size.width;
294     if(h)
295         *h=(int)cocoaRect.size.height;
296 //    wxLogDebug("wxTopLevelWindow=%p::DoGetSize = (%d,%d)",this,(int)cocoaRect.size.width,(int)cocoaRect.size.height);
297 }
298
299 void wxTopLevelWindowCocoa::DoGetPosition(int *x, int *y) const
300 {
301     NSRect cocoaRect = [m_cocoaNSWindow frame];
302     if(x)
303         *x=(int)cocoaRect.origin.x;
304     if(y)
305         *y=(int)cocoaRect.origin.y;
306 //    wxLogDebug("wxTopLevelWindow=%p::DoGetPosition = (%d,%d)",this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y);
307 }
308