1 // Created on: 2012-11-12
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2012-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #import <TargetConditionals.h>
18 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
19 #import <UIKit/UIKit.h>
21 #import <Cocoa/Cocoa.h>
24 #include <Cocoa_Window.hxx>
26 #include <Cocoa_LocalPool.hxx>
28 #include <Image_AlienPixMap.hxx>
29 #include <Aspect_Convert.hxx>
30 #include <Aspect_WindowDefinitionError.hxx>
32 IMPLEMENT_STANDARD_RTTIEXT(Cocoa_Window,Aspect_Window)
34 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
38 #if !defined(MAC_OS_X_VERSION_10_12) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12)
39 // replacements for macOS versions before 10.12
40 #define NSWindowStyleMaskResizable NSResizableWindowMask
41 #define NSWindowStyleMaskClosable NSClosableWindowMask
42 #define NSWindowStyleMaskTitled NSTitledWindowMask
45 static Standard_Integer getScreenBottom()
47 Cocoa_LocalPool aLocalPool;
48 NSArray* aScreens = [NSScreen screens];
49 if (aScreens == NULL || [aScreens count] == 0)
54 NSScreen* aScreen = (NSScreen* )[aScreens objectAtIndex: 0];
55 NSDictionary* aDict = [aScreen deviceDescription];
56 NSNumber* aNumber = [aDict objectForKey: @"NSScreenNumber"];
58 || [aNumber isKindOfClass: [NSNumber class]] == NO)
63 CGDirectDisplayID aDispId = [aNumber unsignedIntValue];
64 CGRect aRect = CGDisplayBounds(aDispId);
65 return Standard_Integer(aRect.origin.y + aRect.size.height);
69 //! Extension for Cocoa_Window::InvalidateContent().
70 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
71 @interface UIView (UIViewOcctAdditions)
72 - (void )invalidateContentOcct: (id )theSender;
74 @implementation UIView (UIViewOcctAdditions)
75 - (void )invalidateContentOcct: (id )theSender
78 [self setNeedsDisplay];
82 @interface NSView (NSViewOcctAdditions)
83 - (void )invalidateContentOcct: (id )theSender;
85 @implementation NSView (NSViewOcctAdditions)
86 - (void )invalidateContentOcct: (id )theSender
89 [self setNeedsDisplay: YES];
94 // =======================================================================
95 // function : Cocoa_Window
97 // =======================================================================
98 Cocoa_Window::Cocoa_Window (const Standard_CString theTitle,
99 const Standard_Integer thePxLeft,
100 const Standard_Integer thePxTop,
101 const Standard_Integer thePxWidth,
102 const Standard_Integer thePxHeight)
104 #if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
110 myXRight (thePxLeft + thePxWidth),
111 myYBottom (thePxTop + thePxHeight)
113 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
116 if (thePxWidth <= 0 || thePxHeight <= 0)
118 throw Aspect_WindowDefinitionError("Coordinate(s) out of range");
120 else if (NSApp == NULL)
122 throw Aspect_WindowDefinitionError("Cocoa application should be instantiated before window");
126 // convert top-bottom coordinates to bottom-top (Cocoa)
127 myYTop = getScreenBottom() - myYBottom;
128 myYBottom = myYTop + thePxHeight;
130 Cocoa_LocalPool aLocalPool;
131 NSUInteger aWinStyle = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable;
132 NSRect aRectNs = NSMakeRect (float(myXLeft), float(myYTop), float(thePxWidth), float(thePxHeight));
133 myHWindow = [[NSWindow alloc] initWithContentRect: aRectNs
135 backing: NSBackingStoreBuffered
137 if (myHWindow == NULL)
139 throw Aspect_WindowDefinitionError("Unable to create window");
141 myHView = [[myHWindow contentView] retain];
143 NSString* aTitleNs = [[NSString alloc] initWithUTF8String: theTitle];
144 [myHWindow setTitle: aTitleNs];
147 // do not destroy NSWindow on close - we didn't handle it!
148 [myHWindow setReleasedWhenClosed: NO];
152 // =======================================================================
153 // function : Cocoa_Window
155 // =======================================================================
156 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
157 Cocoa_Window::Cocoa_Window (UIView* theViewNS)
160 Cocoa_Window::Cocoa_Window (NSView* theViewNS)
170 #if defined(HAVE_OBJC_ARC)
173 myHView = [theViewNS retain];
178 // =======================================================================
179 // function : ~Cocoa_Window
181 // =======================================================================
182 Cocoa_Window::~Cocoa_Window()
184 #if !defined(HAVE_OBJC_ARC)
185 Cocoa_LocalPool aLocalPool;
187 #if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
188 if (myHWindow != NULL)
190 #if !defined(HAVE_OBJC_ARC)
199 #if !defined(HAVE_OBJC_ARC)
206 // =======================================================================
207 // function : SetHView
209 // =======================================================================
210 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
211 void Cocoa_Window::SetHView (UIView* theView)
214 void Cocoa_Window::SetHView (NSView* theView)
216 if (myHWindow != NULL)
218 [myHWindow setContentView: theView];
222 #if defined(HAVE_OBJC_ARC)
230 myHView = [theView retain];
234 // =======================================================================
235 // function : IsMapped
237 // =======================================================================
238 Standard_Boolean Cocoa_Window::IsMapped() const
242 return Standard_True;
245 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
246 return myHView != NULL;
248 return myHView != NULL
249 && [[myHView window] isVisible];
253 // =======================================================================
256 // =======================================================================
257 void Cocoa_Window::Map() const
266 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
269 [[myHView window] orderFront: NULL];
274 // =======================================================================
277 // =======================================================================
278 void Cocoa_Window::Unmap() const
282 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
285 [[myHView window] orderOut: NULL];
290 // =======================================================================
291 // function : DoResize
293 // =======================================================================
294 Aspect_TypeOfResize Cocoa_Window::DoResize() const
298 return Aspect_TOR_UNKNOWN;
301 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
302 CGRect aBounds = [myHView bounds];
304 NSRect aBounds = [myHView bounds];
306 Standard_Integer aMask = 0;
307 Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
309 if (Abs ((Standard_Integer )aBounds.origin.x - myXLeft ) > 2) aMask |= 1;
310 if (Abs ((Standard_Integer )(aBounds.origin.x + aBounds.size.width) - myXRight ) > 2) aMask |= 2;
311 if (Abs ((Standard_Integer )aBounds.origin.y - myYTop ) > 2) aMask |= 4;
312 if (Abs ((Standard_Integer )(aBounds.origin.y + aBounds.size.height) - myYBottom) > 2) aMask |= 8;
315 case 0: aMode = Aspect_TOR_NO_BORDER; break;
316 case 1: aMode = Aspect_TOR_LEFT_BORDER; break;
317 case 2: aMode = Aspect_TOR_RIGHT_BORDER; break;
318 case 4: aMode = Aspect_TOR_TOP_BORDER; break;
319 case 5: aMode = Aspect_TOR_LEFT_AND_TOP_BORDER; break;
320 case 6: aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER; break;
321 case 8: aMode = Aspect_TOR_BOTTOM_BORDER; break;
322 case 9: aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER; break;
323 case 10: aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; break;
327 *((Standard_Integer* )&myXLeft ) = (Standard_Integer )aBounds.origin.x;
328 *((Standard_Integer* )&myXRight ) = (Standard_Integer )(aBounds.origin.x + aBounds.size.width);
329 *((Standard_Integer* )&myYTop ) = (Standard_Integer )aBounds.origin.y;
330 *((Standard_Integer* )&myYBottom ) = (Standard_Integer )(aBounds.origin.y + aBounds.size.height);
334 // =======================================================================
335 // function : DoMapping
337 // =======================================================================
338 Standard_Boolean Cocoa_Window::DoMapping() const
340 return Standard_True;
343 // =======================================================================
346 // =======================================================================
347 Standard_Real Cocoa_Window::Ratio() const
354 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
355 CGRect aBounds = [myHView bounds];
357 NSRect aBounds = [myHView bounds];
359 return Standard_Real (aBounds.size.width / aBounds.size.height);
362 // =======================================================================
363 // function : Position
365 // =======================================================================
366 void Cocoa_Window::Position (Standard_Integer& X1, Standard_Integer& Y1,
367 Standard_Integer& X2, Standard_Integer& Y2) const
369 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
370 CGRect aBounds = [myHView bounds];
373 X2 = (Standard_Integer )aBounds.size.width;
374 Y2 = (Standard_Integer )aBounds.size.height;
376 NSWindow* aWindow = [myHView window];
377 NSRect aWindowRect = [aWindow frame];
378 X1 = (Standard_Integer) aWindowRect.origin.x;
379 Y1 = getScreenBottom() - (Standard_Integer) aWindowRect.origin.y - (Standard_Integer) aWindowRect.size.height;
380 X2 = X1 + (Standard_Integer) aWindowRect.size.width;
381 Y2 = Y1 + (Standard_Integer) aWindowRect.size.height;
385 // =======================================================================
388 // =======================================================================
389 void Cocoa_Window::Size (Standard_Integer& theWidth,
390 Standard_Integer& theHeight) const
397 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
398 CGRect aBounds = [myHView bounds];
400 NSRect aBounds = [myHView bounds];
402 theWidth = (Standard_Integer )aBounds.size.width;
403 theHeight = (Standard_Integer )aBounds.size.height;
406 // =======================================================================
407 // function : InvalidateContent
409 // =======================================================================
410 void Cocoa_Window::InvalidateContent (const Handle(Aspect_DisplayConnection)& )
417 if ([NSThread isMainThread])
419 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
420 [myHView setNeedsDisplay];
422 [myHView setNeedsDisplay: YES];
427 [myHView performSelectorOnMainThread: @selector(invalidateContentOcct:)