0023670: Support for multiple 3D views: edited commands: vinit; added commands: vclos...
[occt.git] / src / Cocoa / Cocoa_Window.mm
CommitLineData
4fe56619 1// Created on: 2012-11-12
2// Created by: Kirill GAVRILOV
3// Copyright (c) 2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
20#import <Cocoa/Cocoa.h>
21
22#include <Cocoa_Window.hxx>
23
24#include <Cocoa_LocalPool.hxx>
25
26#include <Image_AlienPixMap.hxx>
27#include <Aspect_Convert.hxx>
4fe56619 28#include <Aspect_WindowDefinitionError.hxx>
29
30IMPLEMENT_STANDARD_HANDLE (Cocoa_Window, Aspect_Window)
31IMPLEMENT_STANDARD_RTTIEXT(Cocoa_Window, Aspect_Window)
32
4fe56619 33static Standard_Integer getScreenBottom()
34{
35 Cocoa_LocalPool aLocalPool;
36 NSArray* aScreens = [NSScreen screens];
37 if (aScreens == NULL || [aScreens count] == 0)
38 {
39 return 0;
40 }
41
42 NSScreen* aScreen = (NSScreen* )[aScreens objectAtIndex: 0];
43 NSDictionary* aDict = [aScreen deviceDescription];
44 NSNumber* aNumber = [aDict objectForKey: @"NSScreenNumber"];
45 if (aNumber == NULL
46 || [aNumber isKindOfClass: [NSNumber class]] == NO)
47 {
48 return 0;
49 }
50
51 CGDirectDisplayID aDispId = [aNumber unsignedIntValue];
52 CGRect aRect = CGDisplayBounds(aDispId);
53 return Standard_Integer(aRect.origin.y + aRect.size.height);
54}
55
56// =======================================================================
57// function : Cocoa_Window
58// purpose :
59// =======================================================================
60Cocoa_Window::Cocoa_Window (const Standard_CString theTitle,
61 const Standard_Integer thePxLeft,
62 const Standard_Integer thePxTop,
63 const Standard_Integer thePxWidth,
64 const Standard_Integer thePxHeight)
dc3fe572 65: Aspect_Window (),
4fe56619 66 myHWindow (NULL),
67 myHView (NULL),
68 myXLeft (thePxLeft),
69 myYTop (thePxTop),
70 myXRight (thePxLeft + thePxWidth),
71 myYBottom (thePxTop + thePxHeight)
72{
73 if (thePxWidth <= 0 || thePxHeight <= 0)
74 {
75 Aspect_WindowDefinitionError::Raise ("Coordinate(s) out of range");
76 }
77 else if (NSApp == NULL)
78 {
79 Aspect_WindowDefinitionError::Raise ("Cocoa application should be instantiated before window");
80 return;
81 }
82
83 // convert top-bottom coordinates to bottom-top (Cocoa)
84 myYTop = getScreenBottom() - myYBottom;
85 myYBottom = myYTop + thePxHeight;
86
87 Cocoa_LocalPool aLocalPool;
88 NSUInteger aWinStyle = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask;
89 NSRect aRectNs = NSMakeRect (float(myXLeft), float(myYTop), float(thePxWidth), float(thePxHeight));
90 myHWindow = [[NSWindow alloc] initWithContentRect: aRectNs
91 styleMask: aWinStyle
92 backing: NSBackingStoreBuffered
93 defer: NO];
94 if (myHWindow == NULL)
95 {
96 Aspect_WindowDefinitionError::Raise ("Unable to create window");
97 }
98 myHView = [[myHWindow contentView] retain];
99
100 NSString* aTitleNs = [[NSString alloc] initWithUTF8String: theTitle];
101 [myHWindow setTitle: aTitleNs];
102 [aTitleNs release];
103
104 // do not destroy NSWindow on close - we didn't handle it!
105 [myHWindow setReleasedWhenClosed: NO];
106}
107
108// =======================================================================
109// function : Cocoa_Window
110// purpose :
111// =======================================================================
112Cocoa_Window::Cocoa_Window (NSView* theViewNS)
dc3fe572 113: Aspect_Window (),
4fe56619 114 myHWindow (NULL),
115 myHView ([theViewNS retain]),
116 myXLeft (0),
117 myYTop (0),
118 myXRight (512),
119 myYBottom (512)
120{
121 DoResize();
122}
123
124// =======================================================================
125// function : Destroy
126// purpose :
127// =======================================================================
128void Cocoa_Window::Destroy()
129{
130 Cocoa_LocalPool aLocalPool;
131 if (myHWindow != NULL)
132 {
133 //[myHWindow close];
134 [myHWindow release];
135 myHWindow = NULL;
136 }
137 if (myHView != NULL)
138 {
139 [myHView release];
140 myHView = NULL;
141 }
142}
143
144// =======================================================================
145// function : HView
146// purpose :
147// =======================================================================
148NSView* Cocoa_Window::HView() const
149{
150 return myHView;
151}
152
153// =======================================================================
154// function : SetHView
155// purpose :
156// =======================================================================
157void Cocoa_Window::SetHView (NSView* theView)
158{
159 if (myHWindow != NULL)
160 {
161 [myHWindow setContentView: theView];
162 }
163 if (myHView != NULL)
164 {
165 [myHView release];
166 myHView = NULL;
167 }
168 myHView = [theView retain];
169}
170
4fe56619 171// =======================================================================
172// function : IsMapped
173// purpose :
174// =======================================================================
175Standard_Boolean Cocoa_Window::IsMapped() const
176{
177 if (IsVirtual())
178 {
179 return Standard_True;
180 }
181
182 return (myHView != NULL) && [[myHView window] isVisible];
183}
184
185// =======================================================================
186// function : Map
187// purpose :
188// =======================================================================
189void Cocoa_Window::Map() const
190{
191 if (IsVirtual())
192 {
193 return;
194 }
195
196 if (myHView != NULL)
197 {
198 [[myHView window] orderFront: NULL];
199 }
200}
201
202// =======================================================================
203// function : Unmap
204// purpose :
205// =======================================================================
206void Cocoa_Window::Unmap() const
207{
208 if (myHView != NULL)
209 {
210 [[myHView window] orderOut: NULL];
211 }
212}
213
214// =======================================================================
215// function : DoResize
216// purpose :
217// =======================================================================
218Aspect_TypeOfResize Cocoa_Window::DoResize() const
219{
220 if (myHView == NULL)
221 {
222 return Aspect_TOR_UNKNOWN;
223 }
224
225 NSRect aBounds = [myHView bounds];
226 Standard_Integer aMask = 0;
227 Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
228
229 if (Abs ((Standard_Integer )aBounds.origin.x - myXLeft ) > 2) aMask |= 1;
230 if (Abs ((Standard_Integer )(aBounds.origin.x + aBounds.size.width) - myXRight ) > 2) aMask |= 2;
231 if (Abs ((Standard_Integer )aBounds.origin.y - myYTop ) > 2) aMask |= 4;
232 if (Abs ((Standard_Integer )(aBounds.origin.y + aBounds.size.height) - myYBottom) > 2) aMask |= 8;
233 switch (aMask)
234 {
235 case 0: aMode = Aspect_TOR_NO_BORDER; break;
236 case 1: aMode = Aspect_TOR_LEFT_BORDER; break;
237 case 2: aMode = Aspect_TOR_RIGHT_BORDER; break;
238 case 4: aMode = Aspect_TOR_TOP_BORDER; break;
239 case 5: aMode = Aspect_TOR_LEFT_AND_TOP_BORDER; break;
240 case 6: aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER; break;
241 case 8: aMode = Aspect_TOR_BOTTOM_BORDER; break;
242 case 9: aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER; break;
243 case 10: aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; break;
244 default: break;
245 }
246
247 *((Standard_Integer* )&myXLeft ) = (Standard_Integer )aBounds.origin.x;
248 *((Standard_Integer* )&myXRight ) = (Standard_Integer )(aBounds.origin.x + aBounds.size.width);
249 *((Standard_Integer* )&myYTop ) = (Standard_Integer )aBounds.origin.y;
250 *((Standard_Integer* )&myYBottom ) = (Standard_Integer )(aBounds.origin.y + aBounds.size.height);
251 return aMode;
252}
253
254// =======================================================================
255// function : DoMapping
256// purpose :
257// =======================================================================
258Standard_Boolean Cocoa_Window::DoMapping() const
259{
260 return Standard_True;
261}
262
4fe56619 263// =======================================================================
264// function : Ratio
265// purpose :
266// =======================================================================
267Quantity_Ratio Cocoa_Window::Ratio() const
268{
269 if (myHView == NULL)
270 {
271 return 1.0;
272 }
273
274 NSRect aBounds = [myHView bounds];
275 return Quantity_Ratio (aBounds.size.width / aBounds.size.height);
276}
277
4fe56619 278// =======================================================================
279// function : Position
280// purpose :
281// =======================================================================
282void Cocoa_Window::Position (Standard_Integer& X1, Standard_Integer& Y1,
283 Standard_Integer& X2, Standard_Integer& Y2) const
284{
18d715bd 285 NSWindow* aWindow = [myHView window];
286 NSRect aWindowRect = [aWindow frame];
287 X1 = (Standard_Integer) aWindowRect.origin.x;
288 Y1 = getScreenBottom() - (Standard_Integer) aWindowRect.origin.y - (Standard_Integer) aWindowRect.size.height;
289 X2 = X1 + (Standard_Integer) aWindowRect.size.width;
290 Y2 = Y1 + (Standard_Integer) aWindowRect.size.height;
4fe56619 291}
292
4fe56619 293// =======================================================================
294// function : Size
295// purpose :
296// =======================================================================
297void Cocoa_Window::Size (Standard_Integer& theWidth,
298 Standard_Integer& theHeight) const
299{
300 if (myHView == NULL)
301 {
302 return;
303 }
304
305 NSRect aBounds = [myHView bounds];
306 theWidth = (Standard_Integer )aBounds.size.width;
307 theHeight = (Standard_Integer )aBounds.size.height;
308}