1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/nonownedwnd.mm
3 // Purpose: non owned window for cocoa
4 // Author: DavidStefan Csomor
7 // RCS-ID: $Id: nonownedwnd.mm 48805 2007-09-19 14:52:25Z SC $
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
14 #include "wx/nonownedwnd.h"
18 #include "wx/osx/private.h"
20 NSRect wxToNSRect( NSView* parent, const wxRect& r )
22 NSRect frame = parent ? [parent bounds] : [[NSScreen mainScreen] frame];
25 if ( parent == NULL || ![ parent isFlipped ] )
26 y = frame.size.height - ( r.y + r.height );
27 return NSMakeRect(x, y, r.width , r.height);
30 wxRect wxFromNSRect( NSView* parent, const NSRect& rect )
32 NSRect frame = parent ? [parent bounds] : [[NSScreen mainScreen] frame];
33 int y = rect.origin.y;
34 int x = rect.origin.x;
35 if ( parent == NULL || ![ parent isFlipped ] )
36 y = frame.size.height - (rect.origin.y + rect.size.height);
37 return wxRect( x, y, rect.size.width, rect.size.height );
40 NSPoint wxToNSPoint( NSView* parent, const wxPoint& p )
42 NSRect frame = parent ? [parent bounds] : [[NSScreen mainScreen] frame];
45 if ( parent == NULL || ![ parent isFlipped ] )
46 y = frame.size.height - ( p.y );
47 return NSMakePoint(x, y);
50 wxPoint wxFromNSPoint( NSView* parent, const NSPoint& p )
52 NSRect frame = parent ? [parent bounds] : [[NSScreen mainScreen] frame];
55 if ( parent == NULL || ![ parent isFlipped ] )
56 y = frame.size.height - ( p.y );
57 return wxPoint( x, y);
61 // wx native implementation classes
64 @interface wxNSWindow : NSWindow
67 wxNonOwnedWindowCocoaImpl* impl;
70 - (void)setImplementation: (wxNonOwnedWindowCocoaImpl *) theImplementation;
71 - (wxNonOwnedWindowCocoaImpl*) implementation;
75 @implementation wxNSWindow
77 - (void)setImplementation: (wxNonOwnedWindowCocoaImpl *) theImplementation
79 impl = theImplementation;
82 - (wxNonOwnedWindowCocoaImpl*) implementation
90 @interface wxNSPanel : NSPanel
93 wxNonOwnedWindowCocoaImpl* impl;
96 - (void)setImplementation: (wxNonOwnedWindowCocoaImpl *) theImplementation;
97 - (wxNonOwnedWindowCocoaImpl*) implementation;
101 @implementation wxNSPanel
103 - (void)setImplementation: (wxNonOwnedWindowCocoaImpl *) theImplementation
105 impl = theImplementation;
108 - (wxNonOwnedWindowCocoaImpl*) implementation
120 @interface wxNonOwnedWindowController : NSObject
124 - (void)windowDidResize:(NSNotification *)notification;
125 - (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize;
126 - (void)windowDidResignMain:(NSNotification *)notification;
127 - (void)windowDidBecomeMain:(NSNotification *)notification;
128 - (void)windowDidMove:(NSNotification *)notification;
129 - (BOOL)windowShouldClose:(id)window;
133 @implementation wxNonOwnedWindowController
141 - (BOOL)windowShouldClose:(id)nwindow
143 wxNSWindow* window = (wxNSWindow*) nwindow;
144 wxNonOwnedWindowCocoaImpl* windowimpl = [window implementation];
147 wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
154 - (NSSize)windowWillResize:(NSWindow *)win
155 toSize:(NSSize)proposedFrameSize
157 NSRect frame = [win frame];
158 wxRect wxframe = wxFromNSRect( NULL, frame );
159 wxframe.SetWidth( proposedFrameSize.width );
160 wxframe.SetHeight( proposedFrameSize.height );
161 wxNSWindow* window = (wxNSWindow*) win;
162 wxNonOwnedWindowCocoaImpl* windowimpl = [window implementation];
165 wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
168 wxpeer->HandleResizing( 0, &wxframe );
169 NSSize newSize = NSMakeSize(wxframe.GetWidth(), wxframe.GetHeight());
174 return proposedFrameSize;
177 - (void)windowDidResize:(NSNotification *)notification
179 wxNSWindow* window = (wxNSWindow*) [notification object];
180 wxNonOwnedWindowCocoaImpl* windowimpl = [window implementation];
183 wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
185 wxpeer->HandleResized(0);
189 - (void)windowDidMove:(NSNotification *)notification
191 wxNSWindow* window = (wxNSWindow*) [notification object];
192 wxNonOwnedWindowCocoaImpl* windowimpl = [window implementation];
195 wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
197 wxpeer->HandleMoved(0);
201 - (void)windowDidBecomeMain:(NSNotification *)notification
203 wxNSWindow* window = (wxNSWindow*) [notification object];
204 wxNonOwnedWindowCocoaImpl* windowimpl = [window implementation];
207 wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
209 wxpeer->HandleActivated(0, true);
213 - (void)windowDidResignMain:(NSNotification *)notification
215 wxNSWindow* window = (wxNSWindow*) [notification object];
216 wxNonOwnedWindowCocoaImpl* windowimpl = [window implementation];
219 wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
221 wxpeer->HandleActivated(0, false);
227 IMPLEMENT_DYNAMIC_CLASS( wxNonOwnedWindowCocoaImpl , wxNonOwnedWindowImpl )
229 wxNonOwnedWindowCocoaImpl::wxNonOwnedWindowCocoaImpl( wxNonOwnedWindow* nonownedwnd) :
230 wxNonOwnedWindowImpl(nonownedwnd)
233 m_macFullScreenData = NULL;
236 wxNonOwnedWindowCocoaImpl::wxNonOwnedWindowCocoaImpl()
239 m_macFullScreenData = NULL;
242 wxNonOwnedWindowCocoaImpl::~wxNonOwnedWindowCocoaImpl()
244 [m_macWindow setImplementation:nil];
245 [m_macWindow setDelegate:nil];
246 [m_macWindow release];
249 void wxNonOwnedWindowCocoaImpl::Destroy()
251 wxPendingDelete.Append( new wxDeferredObjectDeleter( this ) );
254 void wxNonOwnedWindowCocoaImpl::Create( wxWindow* parent, const wxPoint& pos, const wxSize& size,
255 long style, long extraStyle, const wxString& name )
257 static wxNonOwnedWindowController* controller = NULL;
260 controller =[[wxNonOwnedWindowController alloc] init];
263 int windowstyle = NSBorderlessWindowMask;
265 if ( style & wxFRAME_TOOL_WINDOW )
266 m_macWindow = [wxNSPanel alloc];
268 m_macWindow = [wxNSWindow alloc];
270 CGWindowLevel level = kCGNormalWindowLevel;
272 if ( style & wxFRAME_TOOL_WINDOW )
274 windowstyle |= NSTitledWindowMask | NSUtilityWindowMask;
276 else if ( ( style & wxPOPUP_WINDOW ) )
278 level = kCGPopUpMenuWindowLevel;
280 if ( ( style & wxBORDER_NONE ) )
282 wclass = kHelpWindowClass ; // has no border
283 attr |= kWindowNoShadowAttribute;
287 wclass = kPlainWindowClass ; // has a single line border, it will have to do for now
291 else if ( ( style & wxCAPTION ) )
293 windowstyle |= NSTitledWindowMask ;
295 else if ( ( style & wxFRAME_DRAWER ) )
298 wclass = kDrawerWindowClass;
303 // set these even if we have no title, otherwise the controls won't be visible
304 if ( ( style & wxMINIMIZE_BOX ) || ( style & wxMAXIMIZE_BOX ) ||
305 ( style & wxCLOSE_BOX ) || ( style & wxSYSTEM_MENU ) )
307 windowstyle |= NSTitledWindowMask ;
310 else if ( ( style & wxNO_BORDER ) )
312 wclass = kSimpleWindowClass ;
316 wclass = kPlainWindowClass ;
321 if ( windowstyle & NSTitledWindowMask )
323 if ( ( style & wxMINIMIZE_BOX ) )
324 windowstyle |= NSMiniaturizableWindowMask ;
326 if ( ( style & wxMAXIMIZE_BOX ) )
327 windowstyle |= NSResizableWindowMask ; // TODO showing ZOOM ?
329 if ( ( style & wxRESIZE_BORDER ) )
330 windowstyle |= NSResizableWindowMask ;
332 if ( ( style & wxCLOSE_BOX) )
333 windowstyle |= NSClosableWindowMask ;
335 if ( extraStyle & wxFRAME_EX_METAL)
336 windowstyle |= NSTexturedBackgroundWindowMask;
338 if ( ( style & wxFRAME_FLOAT_ON_PARENT ) || ( style & wxFRAME_TOOL_WINDOW ) )
339 level = kCGFloatingWindowLevel;
341 if ( ( style & wxSTAY_ON_TOP ) )
342 level = kCGUtilityWindowLevel;
344 NSRect r = wxToNSRect( NULL, wxRect( pos, size) );
346 [m_macWindow setImplementation:this];
348 [m_macWindow initWithContentRect:r
349 styleMask:windowstyle
350 backing:NSBackingStoreBuffered
354 [m_macWindow setLevel:level];
356 [m_macWindow setDelegate:controller];
358 // [m_macWindow makeKeyAndOrderFront:nil];
362 WXWindow wxNonOwnedWindowCocoaImpl::GetWXWindow() const
367 void wxNonOwnedWindowCocoaImpl::Raise()
369 [m_macWindow orderWindow:NSWindowAbove relativeTo:0];
372 void wxNonOwnedWindowCocoaImpl::Lower()
374 [m_macWindow orderWindow:NSWindowBelow relativeTo:0];
377 bool wxNonOwnedWindowCocoaImpl::Show(bool show)
381 [m_macWindow orderFront:nil];
382 [[m_macWindow contentView] setNeedsDisplay:YES];
385 [m_macWindow orderOut:nil];
389 bool wxNonOwnedWindowCocoaImpl::ShowWithEffect(bool show, wxShowEffect effect, unsigned timeout)
394 void wxNonOwnedWindowCocoaImpl::Update()
396 [m_macWindow displayIfNeeded];
399 bool wxNonOwnedWindowCocoaImpl::SetTransparent(wxByte alpha)
401 [m_macWindow setAlphaValue:(CGFloat) alpha/255.0];
405 bool wxNonOwnedWindowCocoaImpl::SetBackgroundColour(const wxColour& col )
410 void wxNonOwnedWindowCocoaImpl::SetExtraStyle( long exStyle )
414 bool metal = exStyle & wxFRAME_EX_METAL ;
415 int windowStyle = [ m_macWindow styleMask];
416 if ( metal && !(windowStyle & NSTexturedBackgroundWindowMask) )
418 wxFAIL_MSG( _T("Metal Style cannot be changed after creation") );
420 else if ( !metal && (windowStyle & NSTexturedBackgroundWindowMask ) )
422 wxFAIL_MSG( _T("Metal Style cannot be changed after creation") );
427 bool wxNonOwnedWindowCocoaImpl::SetBackgroundStyle(wxBackgroundStyle style)
432 bool wxNonOwnedWindowCocoaImpl::CanSetTransparent()
437 void wxNonOwnedWindowCocoaImpl::MoveWindow(int x, int y, int width, int height)
439 NSRect r = wxToNSRect( NULL, wxRect(x,y,width, height) );
440 // do not trigger refreshes upon invisible and possible partly created objects
441 [m_macWindow setFrame:r display:GetWXPeer()->IsShownOnScreen()];
444 void wxNonOwnedWindowCocoaImpl::GetPosition( int &x, int &y ) const
446 wxRect r = wxFromNSRect( NULL, [m_macWindow frame] );
451 void wxNonOwnedWindowCocoaImpl::GetSize( int &width, int &height ) const
453 NSRect rect = [m_macWindow frame];
454 width = rect.size.width;
455 height = rect.size.height;
458 void wxNonOwnedWindowCocoaImpl::GetContentArea( int& left, int &right, int &width, int &height ) const
460 NSRect outer = NSMakeRect(100,100,100,100);
461 NSRect content = [NSWindow contentRectForFrameRect:outer styleMask:[m_macWindow styleMask] ];
462 NSRect rect = [[m_macWindow contentView] frame];
463 width = rect.size.width;
464 height = rect.size.height;
467 bool wxNonOwnedWindowCocoaImpl::SetShape(const wxRegion& region)
472 void wxNonOwnedWindowCocoaImpl::SetTitle( const wxString& title, wxFontEncoding encoding )
474 [m_macWindow setTitle:wxCFStringRef( title , encoding ).AsNSString()];
477 bool wxNonOwnedWindowCocoaImpl::IsMaximized() const
479 return [m_macWindow isZoomed];
482 bool wxNonOwnedWindowCocoaImpl::IsIconized() const
484 return [m_macWindow isMiniaturized];
487 void wxNonOwnedWindowCocoaImpl::Iconize( bool iconize )
490 [m_macWindow miniaturize:nil];
492 [m_macWindow deminiaturize:nil];
495 void wxNonOwnedWindowCocoaImpl::Maximize(bool maximize)
497 [m_macWindow zoom:nil];
501 // http://cocoadevcentral.com/articles/000028.php
506 NSRect m_formerFrame;
509 bool wxNonOwnedWindowCocoaImpl::IsFullScreen() const
511 return m_macFullScreenData != NULL ;
514 bool wxNonOwnedWindowCocoaImpl::ShowFullScreen(bool show, long style)
518 FullScreenData *data = (FullScreenData *)m_macFullScreenData ;
520 data = new FullScreenData();
522 m_macFullScreenData = data ;
523 data->m_formerLevel = [m_macWindow level];
524 data->m_formerFrame = [m_macWindow frame];
525 CGDisplayCapture( kCGDirectMainDisplay );
526 [m_macWindow setLevel:CGShieldingWindowLevel()];
527 [m_macWindow setFrame:[[NSScreen mainScreen] frame] display:YES];
529 else if ( m_macFullScreenData != NULL )
531 FullScreenData *data = (FullScreenData *) m_macFullScreenData ;
532 CGDisplayRelease( kCGDirectMainDisplay );
533 [m_macWindow setLevel:data->m_formerLevel];
534 [m_macWindow setFrame:data->m_formerFrame display:YES];
536 m_macFullScreenData = NULL ;
542 void wxNonOwnedWindowCocoaImpl::RequestUserAttention(int WXUNUSED(flags))
546 void wxNonOwnedWindowCocoaImpl::ScreenToWindow( int *x, int *y )
548 wxPoint p((x ? *x : 0), (y ? *y : 0) );
549 NSPoint nspt = wxToNSPoint( NULL, p );
550 nspt = [m_macWindow convertScreenToBase:nspt];
551 nspt = [[m_macWindow contentView] convertPoint:nspt fromView:nil];
552 p = wxFromNSPoint([m_macWindow contentView], nspt);
559 void wxNonOwnedWindowCocoaImpl::WindowToScreen( int *x, int *y )
561 wxPoint p((x ? *x : 0), (y ? *y : 0) );
562 NSPoint nspt = wxToNSPoint( [m_macWindow contentView], p );
563 nspt = [[m_macWindow contentView] convertPoint:nspt toView:nil];
564 nspt = [m_macWindow convertBaseToScreen:nspt];
565 p = wxFromNSPoint( NULL, nspt);
572 wxNonOwnedWindowImpl* wxNonOwnedWindowImpl::CreateNonOwnedWindow( wxNonOwnedWindow* wxpeer, wxWindow* parent, const wxPoint& pos, const wxSize& size,
573 long style, long extraStyle, const wxString& name )
575 wxNonOwnedWindowImpl* now = new wxNonOwnedWindowCocoaImpl( wxpeer );
576 now->Create( parent, pos, size, style , extraStyle, name );