]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/cocoa/toplevel.mm
Added debug unicode config
[wxWidgets.git] / src / cocoa / toplevel.mm
... / ...
CommitLineData
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// Licence: wxWindows licence
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
34#import <AppKit/NSView.h>
35#import <AppKit/NSWindow.h>
36#import <AppKit/NSPanel.h>
37// ----------------------------------------------------------------------------
38// globals
39// ----------------------------------------------------------------------------
40
41// list of all frames and modeless dialogs
42wxWindowList wxModelessWindows;
43
44// ============================================================================
45// wxTopLevelWindowCocoa implementation
46// ============================================================================
47
48wxTopLevelWindowCocoa *wxTopLevelWindowCocoa::sm_cocoaDeactivateWindow = NULL;
49
50// ----------------------------------------------------------------------------
51// wxTopLevelWindowCocoa creation
52// ----------------------------------------------------------------------------
53BEGIN_EVENT_TABLE(wxTopLevelWindowCocoa,wxTopLevelWindowBase)
54 EVT_CLOSE(wxTopLevelWindowCocoa::OnCloseWindow)
55END_EVENT_TABLE()
56
57void wxTopLevelWindowCocoa::Init()
58{
59 m_iconized =
60 m_maximizeOnShow =
61 m_closed = false;
62}
63
64unsigned int wxTopLevelWindowCocoa::NSWindowStyleForWxStyle(long style)
65{
66 unsigned int styleMask = 0;
67 if(style & wxCAPTION)
68 styleMask |= NSTitledWindowMask;
69 if(style & wxMINIMIZE_BOX)
70 styleMask |= NSMiniaturizableWindowMask;
71 #if 0
72 if(style & wxMAXIMIZE_BOX)
73 styleMask |= NSWindowMask;
74 #endif
75 if(style & wxCLOSE_BOX)
76 styleMask |= NSClosableWindowMask;
77 if(style & wxRESIZE_BORDER)
78 styleMask |= NSResizableWindowMask;
79 if(style & wxSIMPLE_BORDER)
80 styleMask |= NSBorderlessWindowMask;
81 return styleMask;
82}
83
84bool wxTopLevelWindowCocoa::Create(wxWindow *parent,
85 wxWindowID winid,
86 const wxString& title,
87 const wxPoint& pos,
88 const wxSize& size,
89 long style,
90 const wxString& name)
91{
92 wxAutoNSAutoreleasePool pool;
93 wxTopLevelWindows.Append(this);
94
95 if(!CreateBase(parent,winid,pos,size,style,wxDefaultValidator,name))
96 return FALSE;
97
98 if ( parent )
99 parent->AddChild(this);
100
101 unsigned int cocoaStyle = NSWindowStyleForWxStyle(style);
102 if(style & wxFRAME_TOOL_WINDOW)
103 cocoaStyle |= NSUtilityWindowMask;
104
105 wxPoint realpos = pos;
106 wxSize realsize = size;
107 // FIXME: this is lame
108 if(realpos.x==-1)
109 realpos.x=100;
110 if(realpos.y==-1)
111 realpos.y=100;
112 if(realsize.x==-1)
113 realsize.x=200;
114 if(realsize.y==-1)
115 realsize.y=200;
116 // NOTE: y-origin needs to be flipped.
117 NSRect cocoaRect = [NSWindow contentRectForFrameRect:NSMakeRect(realpos.x,realpos.y,realsize.x,realsize.y) styleMask:cocoaStyle];
118
119 m_cocoaNSWindow = NULL;
120 m_cocoaNSView = NULL;
121 if(style & wxFRAME_TOOL_WINDOW)
122 SetNSWindow([[NSPanel alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]);
123 else
124 SetNSWindow([[NSWindow alloc] initWithContentRect:cocoaRect styleMask:cocoaStyle backing:NSBackingStoreBuffered defer:NO]);
125 // NOTE: SetNSWindow has retained the Cocoa object for this object.
126 // Because we do not release on close, the following release matches the
127 // above alloc and thus the retain count will be 1.
128 [m_cocoaNSWindow release];
129
130 if(style & wxFRAME_NO_TASKBAR)
131 [m_cocoaNSWindow setExcludedFromWindowsMenu: YES];
132 if(style & wxSTAY_ON_TOP)
133 [m_cocoaNSWindow setLevel:NSFloatingWindowLevel];
134 [m_cocoaNSWindow setTitle:wxNSStringWithWxString(title)];
135 return TRUE;
136}
137
138wxTopLevelWindowCocoa::~wxTopLevelWindowCocoa()
139{
140 wxASSERT(sm_cocoaDeactivateWindow!=this);
141 wxAutoNSAutoreleasePool pool;
142 DestroyChildren();
143 SetNSWindow(NULL);
144}
145
146bool wxTopLevelWindowCocoa::Destroy()
147{
148 if(sm_cocoaDeactivateWindow==this)
149 {
150 sm_cocoaDeactivateWindow = NULL;
151 wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey();
152 }
153 return wxTopLevelWindowBase::Destroy();
154}
155
156// ----------------------------------------------------------------------------
157// wxTopLevelWindowCocoa Cocoa Specifics
158// ----------------------------------------------------------------------------
159
160wxMenuBar* wxTopLevelWindowCocoa::GetAppMenuBar(wxCocoaNSWindow *win)
161{
162 wxTopLevelWindowCocoa *parent = wxDynamicCast(GetParent(),wxTopLevelWindow);
163 if(parent)
164 return parent->GetAppMenuBar(win);
165 return NULL;
166}
167
168void wxTopLevelWindowCocoa::SetNSWindow(WX_NSWindow cocoaNSWindow)
169{
170 bool need_debug = cocoaNSWindow || m_cocoaNSWindow;
171 if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [m_cocoaNSWindow=%p retainCount]=%d",this,m_cocoaNSWindow,[m_cocoaNSWindow retainCount]);
172 DisassociateNSWindow(m_cocoaNSWindow);
173 [cocoaNSWindow retain];
174 [m_cocoaNSWindow release];
175 m_cocoaNSWindow = cocoaNSWindow;
176 if(m_cocoaNSWindow)
177 SetNSView([m_cocoaNSWindow contentView]);
178 else
179 SetNSView(NULL);
180 AssociateNSWindow(m_cocoaNSWindow);
181 if(need_debug) wxLogDebug("wxTopLevelWindowCocoa=%p::SetNSWindow [cocoaNSWindow=%p retainCount]=%d",this,cocoaNSWindow,[cocoaNSWindow retainCount]);
182}
183
184void wxTopLevelWindowCocoa::CocoaReplaceView(WX_NSView oldView, WX_NSView newView)
185{
186 if([m_cocoaNSWindow contentView] == (id)oldView)
187 [m_cocoaNSWindow setContentView:newView];
188}
189
190/*static*/ void wxTopLevelWindowCocoa::DeactivatePendingWindow()
191{
192 if(sm_cocoaDeactivateWindow)
193 sm_cocoaDeactivateWindow->wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey();
194 sm_cocoaDeactivateWindow = NULL;
195}
196
197void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeKey(void)
198{
199 DeactivatePendingWindow();
200 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeKey",this);
201 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, GetId());
202 event.SetEventObject(this);
203 GetEventHandler()->ProcessEvent(event);
204}
205
206void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignKey(void)
207{
208 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignKey",this);
209 wxActivateEvent event(wxEVT_ACTIVATE, FALSE, GetId());
210 event.SetEventObject(this);
211 GetEventHandler()->ProcessEvent(event);
212}
213
214void wxTopLevelWindowCocoa::CocoaDelegate_windowDidBecomeMain(void)
215{
216 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidBecomeMain",this);
217}
218
219void wxTopLevelWindowCocoa::CocoaDelegate_windowDidResignMain(void)
220{
221 wxLogDebug("wxTopLevelWindowCocoa=%p::CocoaDelegate_windowDidResignMain",this);
222}
223
224void wxTopLevelWindowCocoa::CocoaDelegate_windowWillClose(void)
225{
226 m_closed = true;
227 Destroy();
228 /* Be SURE that idle events get ran. If the window was not active when
229 it was closed, then there will be no more events to trigger this and
230 therefore it must be done here */
231 wxTheApp->CocoaInstallRequestedIdleHandler();
232}
233
234bool wxTopLevelWindowCocoa::CocoaDelegate_windowShouldClose()
235{
236 return wxWindowBase::Close(false);
237}
238
239// ----------------------------------------------------------------------------
240// wxTopLevelWindowCocoa maximize/minimize
241// ----------------------------------------------------------------------------
242
243void wxTopLevelWindowCocoa::Maximize(bool maximize)
244{
245}
246
247bool wxTopLevelWindowCocoa::IsMaximized() const
248{
249 return false ;
250}
251
252void wxTopLevelWindowCocoa::Iconize(bool iconize)
253{
254}
255
256bool wxTopLevelWindowCocoa::IsIconized() const
257{
258 return FALSE;
259}
260
261void wxTopLevelWindowCocoa::Restore()
262{
263}
264
265bool wxTopLevelWindowCocoa::Show(bool show)
266{
267 if(m_isShown == show)
268 return false;
269 wxAutoNSAutoreleasePool pool;
270 if(show)
271 {
272 // Send the window a size event because wxWindows apps expect it
273 // NOTE: This should really only be done the first time a window
274 // is shown. I doubt this will cause any problems though.
275 wxSizeEvent event(GetSize(), GetId());
276 event.SetEventObject(this);
277 GetEventHandler()->ProcessEvent(event);
278
279 [m_cocoaNSWindow makeKeyAndOrderFront:m_cocoaNSWindow];
280 }
281 else
282 [m_cocoaNSWindow orderOut:m_cocoaNSWindow];
283 m_isShown = show;
284 return true;
285}
286
287bool wxTopLevelWindowCocoa::Close(bool force)
288{
289 if(force)
290 return wxWindowBase::Close(force);
291 // performClose will fake the user clicking the close button which
292 // will invoke windowShouldClose which will call the base class version
293 // of Close() which will NOT Destroy() the window (see below) but
294 // if closing is not stopped, then performClose will go ahead and
295 // close the window which will send the close notifications setting
296 // m_closed to true and Destroy()ing the window.
297 [m_cocoaNSWindow performClose:m_cocoaNSWindow];
298 return m_closed;
299}
300
301void wxTopLevelWindowCocoa::OnCloseWindow(wxCloseEvent& event)
302{
303 // If the event was forced, close the window which will Destroy() it
304 if(!event.CanVeto())
305 [m_cocoaNSWindow close];
306 // if the event was not forced, it's probably because the user clicked
307 // the close button, or Close(false) was called which (see above) is
308 // redirected to performClose and thus Cocoa itself will close the window
309}
310
311// ----------------------------------------------------------------------------
312// wxTopLevelWindowCocoa misc
313// ----------------------------------------------------------------------------
314
315bool wxTopLevelWindowCocoa::ShowFullScreen(bool show, long style)
316{
317 return FALSE;
318}
319
320bool wxTopLevelWindowCocoa::IsFullScreen() const
321{
322 return FALSE;
323}
324
325void wxTopLevelWindowCocoa::CocoaSetWxWindowSize(int width, int height)
326{
327 // Set the NSView size by setting the frame size to enclose it
328 unsigned int styleMask = [m_cocoaNSWindow styleMask];
329 NSRect frameRect = [m_cocoaNSWindow frame];
330 NSRect contentRect = [NSWindow
331 contentRectForFrameRect: frameRect
332 styleMask: styleMask];
333 contentRect.size.width = width;
334 contentRect.size.height = height;
335 frameRect = [NSWindow
336 frameRectForContentRect: contentRect
337 styleMask: styleMask];
338 [m_cocoaNSWindow setFrame: frameRect display: NO];
339}
340
341void wxTopLevelWindowCocoa::DoMoveWindow(int x, int y, int width, int height)
342{
343// wxLogDebug("wxTopLevelWindow=%p::DoMoveWindow(%d,%d,%d,%d)",this,x,y,width,height);
344
345 NSRect cocoaRect = NSMakeRect(x,y,width,height);
346 [m_cocoaNSWindow setFrame: cocoaRect display:NO];
347}
348
349void wxTopLevelWindowCocoa::DoGetSize(int *w, int *h) const
350{
351 NSRect cocoaRect = [m_cocoaNSWindow frame];
352 if(w)
353 *w=(int)cocoaRect.size.width;
354 if(h)
355 *h=(int)cocoaRect.size.height;
356// wxLogDebug("wxTopLevelWindow=%p::DoGetSize = (%d,%d)",this,(int)cocoaRect.size.width,(int)cocoaRect.size.height);
357}
358
359void wxTopLevelWindowCocoa::DoGetPosition(int *x, int *y) const
360{
361 NSRect cocoaRect = [m_cocoaNSWindow frame];
362 if(x)
363 *x=(int)cocoaRect.origin.x;
364 if(y)
365 *y=(int)cocoaRect.origin.y;
366// wxLogDebug("wxTopLevelWindow=%p::DoGetPosition = (%d,%d)",this,(int)cocoaRect.origin.x,(int)cocoaRect.origin.y);
367}
368