1 // Created on: 2014-11-12
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 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
8 // under the terms of the GNU Lesser General Public 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 <Cocoa/Cocoa.h>
18 #include <Cocoa_Window.hxx>
20 #include <Cocoa_LocalPool.hxx>
22 #include <Image_AlienPixMap.hxx>
23 #include <Aspect_Convert.hxx>
24 #include <Aspect_WindowDefinitionError.hxx>
26 IMPLEMENT_STANDARD_HANDLE (Cocoa_Window, Aspect_Window)
27 IMPLEMENT_STANDARD_RTTIEXT(Cocoa_Window, Aspect_Window)
29 static Standard_Integer getScreenBottom()
31 Cocoa_LocalPool aLocalPool;
32 NSArray* aScreens = [NSScreen screens];
33 if (aScreens == NULL || [aScreens count] == 0)
38 NSScreen* aScreen = (NSScreen* )[aScreens objectAtIndex: 0];
39 NSDictionary* aDict = [aScreen deviceDescription];
40 NSNumber* aNumber = [aDict objectForKey: @"NSScreenNumber"];
42 || [aNumber isKindOfClass: [NSNumber class]] == NO)
47 CGDirectDisplayID aDispId = [aNumber unsignedIntValue];
48 CGRect aRect = CGDisplayBounds(aDispId);
49 return Standard_Integer(aRect.origin.y + aRect.size.height);
52 // =======================================================================
53 // function : Cocoa_Window
55 // =======================================================================
56 Cocoa_Window::Cocoa_Window (const Standard_CString theTitle,
57 const Standard_Integer thePxLeft,
58 const Standard_Integer thePxTop,
59 const Standard_Integer thePxWidth,
60 const Standard_Integer thePxHeight)
66 myXRight (thePxLeft + thePxWidth),
67 myYBottom (thePxTop + thePxHeight)
69 if (thePxWidth <= 0 || thePxHeight <= 0)
71 Aspect_WindowDefinitionError::Raise ("Coordinate(s) out of range");
73 else if (NSApp == NULL)
75 Aspect_WindowDefinitionError::Raise ("Cocoa application should be instantiated before window");
79 // convert top-bottom coordinates to bottom-top (Cocoa)
80 myYTop = getScreenBottom() - myYBottom;
81 myYBottom = myYTop + thePxHeight;
83 Cocoa_LocalPool aLocalPool;
84 NSUInteger aWinStyle = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask;
85 NSRect aRectNs = NSMakeRect (float(myXLeft), float(myYTop), float(thePxWidth), float(thePxHeight));
86 myHWindow = [[NSWindow alloc] initWithContentRect: aRectNs
88 backing: NSBackingStoreBuffered
90 if (myHWindow == NULL)
92 Aspect_WindowDefinitionError::Raise ("Unable to create window");
94 myHView = [[myHWindow contentView] retain];
96 NSString* aTitleNs = [[NSString alloc] initWithUTF8String: theTitle];
97 [myHWindow setTitle: aTitleNs];
100 // do not destroy NSWindow on close - we didn't handle it!
101 [myHWindow setReleasedWhenClosed: NO];
104 // =======================================================================
105 // function : Cocoa_Window
107 // =======================================================================
108 Cocoa_Window::Cocoa_Window (NSView* theViewNS)
111 myHView ([theViewNS retain]),
120 // =======================================================================
121 // function : Destroy
123 // =======================================================================
124 void Cocoa_Window::Destroy()
126 Cocoa_LocalPool aLocalPool;
127 if (myHWindow != NULL)
140 // =======================================================================
143 // =======================================================================
144 NSView* Cocoa_Window::HView() const
149 // =======================================================================
150 // function : SetHView
152 // =======================================================================
153 void Cocoa_Window::SetHView (NSView* theView)
155 if (myHWindow != NULL)
157 [myHWindow setContentView: theView];
164 myHView = [theView retain];
167 // =======================================================================
168 // function : IsMapped
170 // =======================================================================
171 Standard_Boolean Cocoa_Window::IsMapped() const
175 return Standard_True;
178 return (myHView != NULL) && [[myHView window] isVisible];
181 // =======================================================================
184 // =======================================================================
185 void Cocoa_Window::Map() const
194 [[myHView window] orderFront: NULL];
198 // =======================================================================
201 // =======================================================================
202 void Cocoa_Window::Unmap() const
206 [[myHView window] orderOut: NULL];
210 // =======================================================================
211 // function : DoResize
213 // =======================================================================
214 Aspect_TypeOfResize Cocoa_Window::DoResize() const
218 return Aspect_TOR_UNKNOWN;
221 NSRect aBounds = [myHView bounds];
222 Standard_Integer aMask = 0;
223 Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
225 if (Abs ((Standard_Integer )aBounds.origin.x - myXLeft ) > 2) aMask |= 1;
226 if (Abs ((Standard_Integer )(aBounds.origin.x + aBounds.size.width) - myXRight ) > 2) aMask |= 2;
227 if (Abs ((Standard_Integer )aBounds.origin.y - myYTop ) > 2) aMask |= 4;
228 if (Abs ((Standard_Integer )(aBounds.origin.y + aBounds.size.height) - myYBottom) > 2) aMask |= 8;
231 case 0: aMode = Aspect_TOR_NO_BORDER; break;
232 case 1: aMode = Aspect_TOR_LEFT_BORDER; break;
233 case 2: aMode = Aspect_TOR_RIGHT_BORDER; break;
234 case 4: aMode = Aspect_TOR_TOP_BORDER; break;
235 case 5: aMode = Aspect_TOR_LEFT_AND_TOP_BORDER; break;
236 case 6: aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER; break;
237 case 8: aMode = Aspect_TOR_BOTTOM_BORDER; break;
238 case 9: aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER; break;
239 case 10: aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; break;
243 *((Standard_Integer* )&myXLeft ) = (Standard_Integer )aBounds.origin.x;
244 *((Standard_Integer* )&myXRight ) = (Standard_Integer )(aBounds.origin.x + aBounds.size.width);
245 *((Standard_Integer* )&myYTop ) = (Standard_Integer )aBounds.origin.y;
246 *((Standard_Integer* )&myYBottom ) = (Standard_Integer )(aBounds.origin.y + aBounds.size.height);
250 // =======================================================================
251 // function : DoMapping
253 // =======================================================================
254 Standard_Boolean Cocoa_Window::DoMapping() const
256 return Standard_True;
259 // =======================================================================
262 // =======================================================================
263 Quantity_Ratio Cocoa_Window::Ratio() const
270 NSRect aBounds = [myHView bounds];
271 return Quantity_Ratio (aBounds.size.width / aBounds.size.height);
274 // =======================================================================
275 // function : Position
277 // =======================================================================
278 void Cocoa_Window::Position (Standard_Integer& X1, Standard_Integer& Y1,
279 Standard_Integer& X2, Standard_Integer& Y2) const
281 NSWindow* aWindow = [myHView window];
282 NSRect aWindowRect = [aWindow frame];
283 X1 = (Standard_Integer) aWindowRect.origin.x;
284 Y1 = getScreenBottom() - (Standard_Integer) aWindowRect.origin.y - (Standard_Integer) aWindowRect.size.height;
285 X2 = X1 + (Standard_Integer) aWindowRect.size.width;
286 Y2 = Y1 + (Standard_Integer) aWindowRect.size.height;
289 // =======================================================================
292 // =======================================================================
293 void Cocoa_Window::Size (Standard_Integer& theWidth,
294 Standard_Integer& theHeight) const
301 NSRect aBounds = [myHView bounds];
302 theWidth = (Standard_Integer )aBounds.size.width;
303 theHeight = (Standard_Integer )aBounds.size.height;