]> git.saurik.com Git - wxWidgets.git/blob - src/osx/cocoa/nonownedwnd.mm
using systemui for full screen to allow modal dialogs
[wxWidgets.git] / src / osx / cocoa / nonownedwnd.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/nonownedwnd.mm
3 // Purpose: non owned window for cocoa
4 // Author: DavidStefan Csomor
5 // Modified by:
6 // Created: 2008-06-20
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13 #ifndef WX_PRECOMP
14 #include "wx/nonownedwnd.h"
15 #include "wx/frame.h"
16 #include "wx/app.h"
17 #include "wx/dialog.h"
18 #include "wx/menuitem.h"
19 #include "wx/menu.h"
20 #endif
21
22 #include "wx/osx/private.h"
23
24 NSScreen* wxOSXGetMenuScreen()
25 {
26 if ( [NSScreen screens] == nil )
27 return [NSScreen mainScreen];
28 else
29 {
30 return [[NSScreen screens] objectAtIndex:0];
31 }
32 }
33
34 NSRect wxToNSRect( NSView* parent, const wxRect& r )
35 {
36 NSRect frame = parent ? [parent bounds] : [wxOSXGetMenuScreen() frame];
37 int y = r.y;
38 int x = r.x ;
39 if ( parent == NULL || ![ parent isFlipped ] )
40 y = (int)(frame.size.height - ( r.y + r.height ));
41 return NSMakeRect(x, y, r.width , r.height);
42 }
43
44 wxRect wxFromNSRect( NSView* parent, const NSRect& rect )
45 {
46 NSRect frame = parent ? [parent bounds] : [wxOSXGetMenuScreen() frame];
47 int y = (int)rect.origin.y;
48 int x = (int)rect.origin.x;
49 if ( parent == NULL || ![ parent isFlipped ] )
50 y = (int)(frame.size.height - (rect.origin.y + rect.size.height));
51 return wxRect( x, y, (int)rect.size.width, (int)rect.size.height );
52 }
53
54 NSPoint wxToNSPoint( NSView* parent, const wxPoint& p )
55 {
56 NSRect frame = parent ? [parent bounds] : [wxOSXGetMenuScreen() frame];
57 int x = p.x ;
58 int y = p.y;
59 if ( parent == NULL || ![ parent isFlipped ] )
60 y = (int)(frame.size.height - ( p.y ));
61 return NSMakePoint(x, y);
62 }
63
64 wxPoint wxFromNSPoint( NSView* parent, const NSPoint& p )
65 {
66 NSRect frame = parent ? [parent bounds] : [wxOSXGetMenuScreen() frame];
67 int x = (int)p.x;
68 int y = (int)p.y;
69 if ( parent == NULL || ![ parent isFlipped ] )
70 y = (int)(frame.size.height - ( p.y ));
71 return wxPoint( x, y);
72 }
73
74 bool shouldHandleSelector(SEL selector)
75 {
76 if (selector == @selector(noop:)
77 || selector == @selector(complete:)
78 || selector == @selector(deleteBackward:)
79 || selector == @selector(deleteForward:)
80 || selector == @selector(insertNewline:)
81 || selector == @selector(insertTab:)
82 || selector == @selector(insertBacktab:)
83 || selector == @selector(keyDown:)
84 || selector == @selector(keyUp:)
85 || selector == @selector(scrollPageUp:)
86 || selector == @selector(scrollPageDown:)
87 || selector == @selector(scrollToBeginningOfDocument:)
88 || selector == @selector(scrollToEndOfDocument:))
89 return false;
90
91 return true;
92
93 }
94
95 //
96 // wx category for NSWindow (our own and wrapped instances)
97 //
98
99 @interface NSWindow (wxNSWindowSupport)
100
101 - (wxNonOwnedWindowCocoaImpl*) WX_implementation;
102
103 - (bool) WX_filterSendEvent:(NSEvent *) event;
104
105 @end
106
107 @implementation NSWindow (wxNSWindowSupport)
108
109 - (wxNonOwnedWindowCocoaImpl*) WX_implementation
110 {
111 return (wxNonOwnedWindowCocoaImpl*) wxNonOwnedWindowImpl::FindFromWXWindow( self );
112 }
113
114 // TODO in cocoa everything during a drag is sent to the NSWindow the mouse down occured,
115 // this does not conform to the wx behaviour if the window is not captured, so try to resend
116 // or capture all wx mouse event handling at the tlw as we did for carbon
117
118 - (bool) WX_filterSendEvent:(NSEvent *) event
119 {
120 bool handled = false;
121 if ( ([event type] >= NSLeftMouseDown) && ([event type] <= NSMouseExited) )
122 {
123 wxWindow* cw = wxWindow::GetCapture();
124 if ( cw != NULL )
125 {
126 ((wxWidgetCocoaImpl*)cw->GetPeer())->DoHandleMouseEvent( event);
127 handled = true;
128 }
129 }
130 return handled;
131 }
132 @end
133
134 //
135 // wx native implementation
136 //
137
138 @interface wxNSWindow : NSWindow
139 {
140 }
141
142 - (void) sendEvent:(NSEvent *)event;
143 - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen;
144 - (void)noResponderFor: (SEL) selector;
145 @end
146
147 @implementation wxNSWindow
148
149 - (void)sendEvent:(NSEvent *) event
150 {
151 if ( ![self WX_filterSendEvent: event] )
152 {
153 WXEVENTREF formerEvent = wxTheApp == NULL ? NULL : wxTheApp->MacGetCurrentEvent();
154 WXEVENTHANDLERCALLREF formerHandler = wxTheApp == NULL ? NULL : wxTheApp->MacGetCurrentEventHandlerCallRef();
155
156 if (wxTheApp)
157 wxTheApp->MacSetCurrentEvent(event, NULL);
158
159 [super sendEvent: event];
160
161 if (wxTheApp)
162 wxTheApp->MacSetCurrentEvent(formerEvent , formerHandler);
163 }
164 }
165
166 // The default implementation always moves the window back onto the screen,
167 // even when the programmer explicitly wants to hide it.
168 - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
169 {
170 wxUnusedVar(screen);
171 return frameRect;
172 }
173
174 - (void)doCommandBySelector:(SEL)selector
175 {
176 if (shouldHandleSelector(selector) &&
177 !(selector == @selector(cancel:) || selector == @selector(cancelOperation:)) )
178 [super doCommandBySelector:selector];
179 }
180
181
182 // NB: if we don't do this, all key downs that get handled lead to a NSBeep
183 - (void)noResponderFor: (SEL) selector
184 {
185 if (selector != @selector(keyDown:) && selector != @selector(keyUp:))
186 {
187 [super noResponderFor:selector];
188 }
189 }
190
191 // We need this for borderless windows, i.e. shaped windows or windows without
192 // a title bar. For more info, see:
193 // http://lists.apple.com/archives/cocoa-dev/2008/May/msg02091.html
194 - (BOOL)canBecomeKeyWindow
195 {
196 return YES;
197 }
198
199 @end
200
201 @interface wxNSPanel : NSPanel
202 {
203 }
204
205 - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen;
206 - (void)noResponderFor: (SEL) selector;
207 - (void)sendEvent:(NSEvent *)event;
208 @end
209
210 @implementation wxNSPanel
211
212 - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
213 {
214 wxNonOwnedWindowCocoaImpl* impl = (wxNonOwnedWindowCocoaImpl*) wxNonOwnedWindowImpl::FindFromWXWindow( self );
215 if (impl && impl->IsFullScreen())
216 return frameRect;
217 else
218 return [super constrainFrameRect:frameRect toScreen:screen];
219 }
220
221 - (BOOL)canBecomeKeyWindow
222 {
223 return YES;
224 }
225
226 - (void)doCommandBySelector:(SEL)selector
227 {
228 if (shouldHandleSelector(selector))
229 [super doCommandBySelector:selector];
230 }
231
232 // NB: if we don't do this, it seems that all events that end here lead to a NSBeep
233 - (void)noResponderFor: (SEL) selector
234 {
235 if (selector != @selector(keyDown:) && selector != @selector(keyUp:))
236 {
237 [super noResponderFor:selector];
238 }
239 }
240
241 - (void)sendEvent:(NSEvent *) event
242 {
243 if ( ![self WX_filterSendEvent: event] )
244 [super sendEvent: event];
245 }
246
247 @end
248
249
250 //
251 // controller
252 //
253
254 @interface wxNonOwnedWindowController : NSObject wxOSX_10_6_AND_LATER(<NSWindowDelegate>)
255 {
256 }
257
258 - (void)windowDidResize:(NSNotification *)notification;
259 - (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize;
260 - (void)windowDidResignKey:(NSNotification *)notification;
261 - (void)windowDidBecomeKey:(NSNotification *)notification;
262 - (void)windowDidMove:(NSNotification *)notification;
263 - (BOOL)windowShouldClose:(id)window;
264 - (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame;
265
266 @end
267
268 extern int wxOSXGetIdFromSelector(SEL action );
269
270 @implementation wxNonOwnedWindowController
271
272 - (id) init
273 {
274 [super init];
275 return self;
276 }
277
278 - (BOOL) triggerMenu:(SEL) action
279 {
280 wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar();
281 if ( mbar )
282 {
283 wxMenu* menu = NULL;
284 wxMenuItem* menuitem = mbar->FindItem(wxOSXGetIdFromSelector(action), &menu);
285 if ( menu != NULL && menuitem != NULL)
286 return menu->HandleCommandProcess(menuitem);
287 }
288 return NO;
289 }
290
291 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
292 {
293 SEL action = [menuItem action];
294
295 wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar();
296 if ( mbar )
297 {
298 wxMenu* menu = NULL;
299 wxMenuItem* menuitem = mbar->FindItem(wxOSXGetIdFromSelector(action), &menu);
300 if ( menu != NULL && menuitem != NULL)
301 {
302 if ( menu->HandleCommandUpdateStatus(menuitem) )
303 return menuitem->IsEnabled();
304 }
305 }
306 return YES;
307 }
308
309 - (void)undo:(id)sender
310 {
311 wxUnusedVar(sender);
312 [self triggerMenu:_cmd];
313 }
314
315 - (void)redo:(id)sender
316 {
317 wxUnusedVar(sender);
318 [self triggerMenu:_cmd];
319 }
320
321 - (void)cut:(id)sender
322 {
323 wxUnusedVar(sender);
324 [self triggerMenu:_cmd];
325 }
326
327 - (void)copy:(id)sender
328 {
329 wxUnusedVar(sender);
330 [self triggerMenu:_cmd];
331 }
332
333 - (void)paste:(id)sender
334 {
335 wxUnusedVar(sender);
336 [self triggerMenu:_cmd];
337 }
338
339 - (void)delete:(id)sender
340 {
341 wxUnusedVar(sender);
342 [self triggerMenu:_cmd];
343 }
344
345 - (void)selectAll:(id)sender
346 {
347 wxUnusedVar(sender);
348 [self triggerMenu:_cmd];
349 }
350
351 - (BOOL)windowShouldClose:(id)nwindow
352 {
353 wxNonOwnedWindowCocoaImpl* windowimpl = [(NSWindow*) nwindow WX_implementation];
354 if ( windowimpl )
355 {
356 wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
357 if ( wxpeer )
358 wxpeer->Close();
359 }
360 return NO;
361 }
362
363 - (NSSize)windowWillResize:(NSWindow *)window
364 toSize:(NSSize)proposedFrameSize
365 {
366 NSRect frame = [window frame];
367 wxRect wxframe = wxFromNSRect( NULL, frame );
368 wxframe.SetWidth( (int)proposedFrameSize.width );
369 wxframe.SetHeight( (int)proposedFrameSize.height );
370
371 wxNonOwnedWindowCocoaImpl* windowimpl = [window WX_implementation];
372 if ( windowimpl )
373 {
374 wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
375 if ( wxpeer )
376 {
377 wxpeer->HandleResizing( 0, &wxframe );
378 NSSize newSize = NSMakeSize(wxframe.GetWidth(), wxframe.GetHeight());
379 return newSize;
380 }
381 }
382
383 return proposedFrameSize;
384 }
385
386 - (void)windowDidResize:(NSNotification *)notification
387 {
388 NSWindow* window = (NSWindow*) [notification object];
389 wxNonOwnedWindowCocoaImpl* windowimpl = [window WX_implementation];
390 if ( windowimpl )
391 {
392 wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
393 if ( wxpeer )
394 wxpeer->HandleResized(0);
395 }
396 }
397
398 - (void)windowDidMove:(NSNotification *)notification
399 {
400 wxNSWindow* window = (wxNSWindow*) [notification object];
401 wxNonOwnedWindowCocoaImpl* windowimpl = [window WX_implementation];
402 if ( windowimpl )
403 {
404 wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
405 if ( wxpeer )
406 wxpeer->HandleMoved(0);
407 }
408 }
409
410 - (void)windowDidBecomeKey:(NSNotification *)notification
411 {
412 NSWindow* window = (NSWindow*) [notification object];
413 wxNonOwnedWindowCocoaImpl* windowimpl = [window WX_implementation];
414 if ( windowimpl )
415 {
416 wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
417 if ( wxpeer )
418 wxpeer->HandleActivated(0, true);
419 }
420 }
421
422 - (void)windowDidResignKey:(NSNotification *)notification
423 {
424 NSWindow* window = (NSWindow*) [notification object];
425 wxNonOwnedWindowCocoaImpl* windowimpl = [window WX_implementation];
426 if ( windowimpl )
427 {
428 wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
429 if ( wxpeer )
430 {
431 wxpeer->HandleActivated(0, false);
432 // Needed for popup window since the firstResponder
433 // (focus in wx) doesn't change when this
434 // TLW becomes inactive.
435 wxFocusEvent event( wxEVT_KILL_FOCUS, wxpeer->GetId());
436 event.SetEventObject(wxpeer);
437 wxpeer->HandleWindowEvent(event);
438 }
439 }
440 }
441
442 - (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)anObject
443 {
444 wxUnusedVar(sender);
445
446 if ([anObject isKindOfClass:[wxNSTextField class]])
447 {
448 wxNSTextField* tf = (wxNSTextField*) anObject;
449 wxNSTextFieldEditor* editor = [tf fieldEditor];
450 if ( editor == nil )
451 {
452 editor = [[wxNSTextFieldEditor alloc] init];
453 [editor setFieldEditor:YES];
454 [tf setFieldEditor:editor];
455 }
456 return editor;
457 }
458
459 return nil;
460 }
461
462 - (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame
463 {
464 wxUnusedVar(newFrame);
465 wxNonOwnedWindowCocoaImpl* windowimpl = [window WX_implementation];
466 if ( windowimpl )
467 {
468 wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer();
469 wxMaximizeEvent event(wxpeer->GetId());
470 event.SetEventObject(wxpeer);
471 return !wxpeer->HandleWindowEvent(event);
472 }
473 return true;
474 }
475
476 @end
477
478 IMPLEMENT_DYNAMIC_CLASS( wxNonOwnedWindowCocoaImpl , wxNonOwnedWindowImpl )
479
480 wxNonOwnedWindowCocoaImpl::wxNonOwnedWindowCocoaImpl( wxNonOwnedWindow* nonownedwnd) :
481 wxNonOwnedWindowImpl(nonownedwnd)
482 {
483 m_macWindow = NULL;
484 m_macFullScreenData = NULL;
485 }
486
487 wxNonOwnedWindowCocoaImpl::wxNonOwnedWindowCocoaImpl()
488 {
489 m_macWindow = NULL;
490 m_macFullScreenData = NULL;
491 }
492
493 wxNonOwnedWindowCocoaImpl::~wxNonOwnedWindowCocoaImpl()
494 {
495 if ( !m_wxPeer->IsNativeWindowWrapper() )
496 {
497 [m_macWindow setDelegate:nil];
498 [m_macWindow release];
499 }
500 }
501
502 void wxNonOwnedWindowCocoaImpl::WillBeDestroyed()
503 {
504 if ( !m_wxPeer->IsNativeWindowWrapper() )
505 {
506 [m_macWindow setDelegate:nil];
507 }
508 }
509
510 void wxNonOwnedWindowCocoaImpl::Create( wxWindow* parent, const wxPoint& pos, const wxSize& size,
511 long style, long extraStyle, const wxString& WXUNUSED(name) )
512 {
513 static wxNonOwnedWindowController* controller = NULL;
514
515 if ( !controller )
516 controller =[[wxNonOwnedWindowController alloc] init];
517
518
519 int windowstyle = NSBorderlessWindowMask;
520
521 if ( style & wxFRAME_TOOL_WINDOW || ( style & wxPOPUP_WINDOW ) ||
522 GetWXPeer()->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG )
523 {
524 m_macWindow = [wxNSPanel alloc];
525 }
526 else
527 m_macWindow = [wxNSWindow alloc];
528
529 CGWindowLevel level = kCGNormalWindowLevel;
530
531 if ( style & wxFRAME_TOOL_WINDOW )
532 {
533 windowstyle |= NSUtilityWindowMask;
534 if ( ( style & wxMINIMIZE_BOX ) || ( style & wxMAXIMIZE_BOX ) ||
535 ( style & wxCLOSE_BOX ) || ( style & wxSYSTEM_MENU ) )
536 {
537 windowstyle |= NSTitledWindowMask ;
538 }
539 }
540 else if ( ( style & wxPOPUP_WINDOW ) )
541 {
542 level = kCGPopUpMenuWindowLevel;
543 /*
544 if ( ( style & wxBORDER_NONE ) )
545 {
546 wclass = kHelpWindowClass ; // has no border
547 attr |= kWindowNoShadowAttribute;
548 }
549 else
550 {
551 wclass = kPlainWindowClass ; // has a single line border, it will have to do for now
552 }
553 */
554 }
555 else if ( ( style & wxCAPTION ) )
556 {
557 windowstyle |= NSTitledWindowMask ;
558 }
559 else if ( ( style & wxFRAME_DRAWER ) )
560 {
561 /*
562 wclass = kDrawerWindowClass;
563 */
564 }
565 else
566 {
567 // set these even if we have no title, otherwise the controls won't be visible
568 if ( ( style & wxMINIMIZE_BOX ) || ( style & wxMAXIMIZE_BOX ) ||
569 ( style & wxCLOSE_BOX ) || ( style & wxSYSTEM_MENU ) )
570 {
571 windowstyle |= NSTitledWindowMask ;
572 }
573 /*
574 else if ( ( style & wxNO_BORDER ) )
575 {
576 wclass = kSimpleWindowClass ;
577 }
578 else
579 {
580 wclass = kPlainWindowClass ;
581 }
582 */
583 }
584
585 if ( windowstyle & NSTitledWindowMask )
586 {
587 if ( ( style & wxMINIMIZE_BOX ) )
588 windowstyle |= NSMiniaturizableWindowMask ;
589
590 if ( ( style & wxMAXIMIZE_BOX ) )
591 windowstyle |= NSResizableWindowMask ; // TODO showing ZOOM ?
592
593 if ( ( style & wxRESIZE_BORDER ) )
594 windowstyle |= NSResizableWindowMask ;
595
596 if ( ( style & wxCLOSE_BOX) )
597 windowstyle |= NSClosableWindowMask ;
598 }
599 if ( extraStyle & wxFRAME_EX_METAL)
600 windowstyle |= NSTexturedBackgroundWindowMask;
601
602 if ( ( style & wxFRAME_FLOAT_ON_PARENT ) || ( style & wxFRAME_TOOL_WINDOW ) )
603 level = kCGFloatingWindowLevel;
604
605 if ( ( style & wxSTAY_ON_TOP ) )
606 level = kCGUtilityWindowLevel;
607
608 NSRect r = wxToNSRect( NULL, wxRect( pos, size) );
609
610 r = [NSWindow contentRectForFrameRect:r styleMask:windowstyle];
611
612 [m_macWindow initWithContentRect:r
613 styleMask:windowstyle
614 backing:NSBackingStoreBuffered
615 defer:NO
616 ];
617
618 // If the parent is modal, windows with wxFRAME_FLOAT_ON_PARENT style need
619 // to be in kCGUtilityWindowLevel and not kCGFloatingWindowLevel to stay
620 // above the parent.
621 wxDialog * const parentDialog = wxDynamicCast(parent, wxDialog);
622 if (parentDialog && parentDialog->IsModal())
623 {
624 if (level == kCGFloatingWindowLevel)
625 {
626 level = kCGUtilityWindowLevel;
627 }
628
629 // Cocoa's modal loop does not process other windows by default, but
630 // don't call this on normal window levels so nested modal dialogs will
631 // still behave modally.
632 if (level != kCGNormalWindowLevel)
633 {
634 if ([m_macWindow isKindOfClass:[NSPanel class]])
635 {
636 [(NSPanel*)m_macWindow setWorksWhenModal:YES];
637 }
638 }
639 }
640
641 [m_macWindow setLevel:level];
642 m_macWindowLevel = level;
643
644 [m_macWindow setDelegate:controller];
645
646 [m_macWindow setAcceptsMouseMovedEvents: YES];
647
648 if ( ( style & wxFRAME_SHAPED) )
649 {
650 [m_macWindow setOpaque:NO];
651 [m_macWindow setAlphaValue:1.0];
652 }
653
654 if ( !(style & wxFRAME_TOOL_WINDOW) )
655 [m_macWindow setHidesOnDeactivate:NO];
656 }
657
658 void wxNonOwnedWindowCocoaImpl::Create( wxWindow* WXUNUSED(parent), WXWindow nativeWindow )
659 {
660 m_macWindow = nativeWindow;
661 }
662
663 WXWindow wxNonOwnedWindowCocoaImpl::GetWXWindow() const
664 {
665 return m_macWindow;
666 }
667
668 void wxNonOwnedWindowCocoaImpl::Raise()
669 {
670 [m_macWindow makeKeyAndOrderFront:nil];
671 }
672
673 void wxNonOwnedWindowCocoaImpl::Lower()
674 {
675 [m_macWindow orderWindow:NSWindowBelow relativeTo:0];
676 }
677
678 void wxNonOwnedWindowCocoaImpl::ShowWithoutActivating()
679 {
680 [m_macWindow orderFront:nil];
681 [[m_macWindow contentView] setNeedsDisplay: YES];
682 }
683
684 bool wxNonOwnedWindowCocoaImpl::Show(bool show)
685 {
686 if ( show )
687 {
688 wxNonOwnedWindow* wxpeer = GetWXPeer();
689 if (wxpeer && !(wxpeer->GetWindowStyle() & wxFRAME_TOOL_WINDOW))
690 [m_macWindow makeKeyAndOrderFront:nil];
691 else
692 [m_macWindow orderFront:nil];
693 [[m_macWindow contentView] setNeedsDisplay: YES];
694 }
695 else
696 [m_macWindow orderOut:nil];
697 return true;
698 }
699
700 bool wxNonOwnedWindowCocoaImpl::ShowWithEffect(bool show,
701 wxShowEffect effect,
702 unsigned timeout)
703 {
704 return wxWidgetCocoaImpl::
705 ShowViewOrWindowWithEffect(m_wxPeer, show, effect, timeout);
706 }
707
708 void wxNonOwnedWindowCocoaImpl::Update()
709 {
710 [m_macWindow displayIfNeeded];
711 }
712
713 bool wxNonOwnedWindowCocoaImpl::SetTransparent(wxByte alpha)
714 {
715 [m_macWindow setAlphaValue:(CGFloat) alpha/255.0];
716 return true;
717 }
718
719 bool wxNonOwnedWindowCocoaImpl::SetBackgroundColour(const wxColour& WXUNUSED(col) )
720 {
721 return true;
722 }
723
724 void wxNonOwnedWindowCocoaImpl::SetExtraStyle( long exStyle )
725 {
726 if ( m_macWindow )
727 {
728 bool metal = exStyle & wxFRAME_EX_METAL ;
729 int windowStyle = [ m_macWindow styleMask];
730 if ( metal && !(windowStyle & NSTexturedBackgroundWindowMask) )
731 {
732 wxFAIL_MSG( wxT("Metal Style cannot be changed after creation") );
733 }
734 else if ( !metal && (windowStyle & NSTexturedBackgroundWindowMask ) )
735 {
736 wxFAIL_MSG( wxT("Metal Style cannot be changed after creation") );
737 }
738 }
739 }
740
741 void wxNonOwnedWindowCocoaImpl::SetWindowStyleFlag( long style )
742 {
743 if (m_macWindow)
744 {
745 CGWindowLevel level = kCGNormalWindowLevel;
746
747 if (style & wxSTAY_ON_TOP)
748 level = kCGUtilityWindowLevel;
749 else if (( style & wxFRAME_FLOAT_ON_PARENT ) || ( style & wxFRAME_TOOL_WINDOW ))
750 level = kCGFloatingWindowLevel;
751
752 [m_macWindow setLevel: level];
753 m_macWindowLevel = level;
754 }
755 }
756
757 bool wxNonOwnedWindowCocoaImpl::SetBackgroundStyle(wxBackgroundStyle style)
758 {
759 if ( style == wxBG_STYLE_TRANSPARENT )
760 {
761 [m_macWindow setOpaque:NO];
762 [m_macWindow setBackgroundColor:[NSColor clearColor]];
763 }
764
765 return true;
766 }
767
768 bool wxNonOwnedWindowCocoaImpl::CanSetTransparent()
769 {
770 return true;
771 }
772
773 void wxNonOwnedWindowCocoaImpl::MoveWindow(int x, int y, int width, int height)
774 {
775 NSRect r = wxToNSRect( NULL, wxRect(x,y,width, height) );
776 // do not trigger refreshes upon invisible and possible partly created objects
777 [m_macWindow setFrame:r display:GetWXPeer()->IsShownOnScreen()];
778 }
779
780 void wxNonOwnedWindowCocoaImpl::GetPosition( int &x, int &y ) const
781 {
782 wxRect r = wxFromNSRect( NULL, [m_macWindow frame] );
783 x = r.GetLeft();
784 y = r.GetTop();
785 }
786
787 void wxNonOwnedWindowCocoaImpl::GetSize( int &width, int &height ) const
788 {
789 NSRect rect = [m_macWindow frame];
790 width = (int)rect.size.width;
791 height = (int)rect.size.height;
792 }
793
794 void wxNonOwnedWindowCocoaImpl::GetContentArea( int& left, int &top, int &width, int &height ) const
795 {
796 NSRect rect = [[m_macWindow contentView] frame];
797 left = (int)rect.origin.x;
798 top = (int)rect.origin.y;
799 width = (int)rect.size.width;
800 height = (int)rect.size.height;
801 }
802
803 bool wxNonOwnedWindowCocoaImpl::SetShape(const wxRegion& WXUNUSED(region))
804 {
805 [m_macWindow setOpaque:NO];
806 [m_macWindow setBackgroundColor:[NSColor clearColor]];
807
808 return true;
809 }
810
811 void wxNonOwnedWindowCocoaImpl::SetTitle( const wxString& title, wxFontEncoding encoding )
812 {
813 [m_macWindow setTitle:wxCFStringRef( title , encoding ).AsNSString()];
814 }
815
816 bool wxNonOwnedWindowCocoaImpl::IsMaximized() const
817 {
818 if (([m_macWindow styleMask] & NSResizableWindowMask) != 0)
819 {
820 return [m_macWindow isZoomed];
821 }
822 else
823 {
824 NSRect rectScreen = [[NSScreen mainScreen] visibleFrame];
825 NSRect rectWindow = [m_macWindow frame];
826 return (rectScreen.origin.x == rectWindow.origin.x &&
827 rectScreen.origin.y == rectWindow.origin.y &&
828 rectScreen.size.width == rectWindow.size.width &&
829 rectScreen.size.height == rectWindow.size.height);
830 }
831 }
832
833 bool wxNonOwnedWindowCocoaImpl::IsIconized() const
834 {
835 return [m_macWindow isMiniaturized];
836 }
837
838 void wxNonOwnedWindowCocoaImpl::Iconize( bool iconize )
839 {
840 if ( iconize )
841 [m_macWindow miniaturize:nil];
842 else
843 [m_macWindow deminiaturize:nil];
844 }
845
846 void wxNonOwnedWindowCocoaImpl::Maximize(bool WXUNUSED(maximize))
847 {
848 [m_macWindow zoom:nil];
849 }
850
851
852 // http://cocoadevcentral.com/articles/000028.php
853
854 typedef struct
855 {
856 int m_formerLevel;
857 NSRect m_formerFrame;
858 } FullScreenData ;
859
860 bool wxNonOwnedWindowCocoaImpl::IsFullScreen() const
861 {
862 return m_macFullScreenData != NULL ;
863 }
864
865 bool wxNonOwnedWindowCocoaImpl::ShowFullScreen(bool show, long WXUNUSED(style))
866 {
867 if ( show )
868 {
869 FullScreenData *data = (FullScreenData *)m_macFullScreenData ;
870 delete data ;
871 data = new FullScreenData();
872
873 m_macFullScreenData = data ;
874 data->m_formerLevel = [m_macWindow level];
875 data->m_formerFrame = [m_macWindow frame];
876 #if 0
877 // CGDisplayCapture( kCGDirectMainDisplay );
878 //[m_macWindow setLevel:NSMainMenuWindowLevel+1/*CGShieldingWindowLevel()*/];
879 #endif
880 NSRect screenframe = [[NSScreen mainScreen] frame];
881 NSRect frame = NSMakeRect (0, 0, 100, 100);
882 NSRect contentRect;
883 contentRect = [NSWindow contentRectForFrameRect: frame
884 styleMask: NSTitledWindowMask];
885 screenframe.origin.y += (frame.origin.y - contentRect.origin.y);
886 screenframe.size.height += (frame.size.height - contentRect.size.height);
887 [m_macWindow setFrame:screenframe display:YES];
888
889 OSStatus error = SetSystemUIMode(kUIModeAllHidden,
890 kUIOptionDisableAppleMenu
891 | kUIOptionDisableProcessSwitch
892 | kUIOptionDisableForceQuit);
893 }
894 else if ( m_macFullScreenData != NULL )
895 {
896 FullScreenData *data = (FullScreenData *) m_macFullScreenData ;
897 #if 0
898 // CGDisplayRelease( kCGDirectMainDisplay );
899 // [m_macWindow setLevel:data->m_formerLevel];
900 #endif
901
902 [m_macWindow setFrame:data->m_formerFrame display:YES];
903 delete data ;
904 m_macFullScreenData = NULL ;
905
906 OSStatus error = SetSystemUIMode(kUIModeNormal, 0);
907 }
908
909 return true;
910 }
911
912 void wxNonOwnedWindowCocoaImpl::RequestUserAttention(int flagsWX)
913 {
914 NSRequestUserAttentionType flagsOSX;
915 switch ( flagsWX )
916 {
917 case wxUSER_ATTENTION_INFO:
918 flagsOSX = NSInformationalRequest;
919 break;
920
921 case wxUSER_ATTENTION_ERROR:
922 flagsOSX = NSCriticalRequest;
923 break;
924
925 default:
926 wxFAIL_MSG( "invalid RequestUserAttention() flags" );
927 return;
928 }
929
930 [NSApp requestUserAttention:flagsOSX];
931 }
932
933 void wxNonOwnedWindowCocoaImpl::ScreenToWindow( int *x, int *y )
934 {
935 wxPoint p((x ? *x : 0), (y ? *y : 0) );
936 NSPoint nspt = wxToNSPoint( NULL, p );
937 nspt = [m_macWindow convertScreenToBase:nspt];
938 nspt = [[m_macWindow contentView] convertPoint:nspt fromView:nil];
939 p = wxFromNSPoint([m_macWindow contentView], nspt);
940 if ( x )
941 *x = p.x;
942 if ( y )
943 *y = p.y;
944 }
945
946 void wxNonOwnedWindowCocoaImpl::WindowToScreen( int *x, int *y )
947 {
948 wxPoint p((x ? *x : 0), (y ? *y : 0) );
949 NSPoint nspt = wxToNSPoint( [m_macWindow contentView], p );
950 nspt = [[m_macWindow contentView] convertPoint:nspt toView:nil];
951 nspt = [m_macWindow convertBaseToScreen:nspt];
952 p = wxFromNSPoint( NULL, nspt);
953 if ( x )
954 *x = p.x;
955 if ( y )
956 *y = p.y;
957 }
958
959 bool wxNonOwnedWindowCocoaImpl::IsActive()
960 {
961 return [m_macWindow isKeyWindow];
962 }
963
964 void wxNonOwnedWindowCocoaImpl::SetModified(bool modified)
965 {
966 [m_macWindow setDocumentEdited:modified];
967 }
968
969 bool wxNonOwnedWindowCocoaImpl::IsModified() const
970 {
971 return [m_macWindow isDocumentEdited];
972 }
973
974 void wxNonOwnedWindowCocoaImpl::RestoreWindowLevel()
975 {
976 if ( [m_macWindow level] != m_macWindowLevel )
977 [m_macWindow setLevel:m_macWindowLevel];
978 }
979
980 //
981 //
982 //
983
984 wxNonOwnedWindowImpl* wxNonOwnedWindowImpl::CreateNonOwnedWindow( wxNonOwnedWindow* wxpeer, wxWindow* parent, WXWindow nativeWindow)
985 {
986 wxNonOwnedWindowCocoaImpl* now = new wxNonOwnedWindowCocoaImpl( wxpeer );
987 now->Create( parent, nativeWindow );
988 return now;
989 }
990
991 wxNonOwnedWindowImpl* wxNonOwnedWindowImpl::CreateNonOwnedWindow( wxNonOwnedWindow* wxpeer, wxWindow* parent, const wxPoint& pos, const wxSize& size,
992 long style, long extraStyle, const wxString& name )
993 {
994 wxNonOwnedWindowImpl* now = new wxNonOwnedWindowCocoaImpl( wxpeer );
995 now->Create( parent, pos, size, style , extraStyle, name );
996 return now;
997 }
998