0026859: Export of GDT from XCAF to STEP
[occt.git] / src / Cocoa / Cocoa_Window.mm
1 // Created on: 2012-11-12
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2012-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #import <TargetConditionals.h>
17
18 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
19   #import <UIKit/UIKit.h>
20 #else
21   #import <Cocoa/Cocoa.h>
22 #endif
23
24 #include <Cocoa_Window.hxx>
25
26 #include <Cocoa_LocalPool.hxx>
27
28 #include <Image_AlienPixMap.hxx>
29 #include <Aspect_Convert.hxx>
30 #include <Aspect_WindowDefinitionError.hxx>
31
32 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
33   //
34 #else
35 static Standard_Integer getScreenBottom()
36 {
37   Cocoa_LocalPool aLocalPool;
38   NSArray* aScreens = [NSScreen screens];
39   if (aScreens == NULL || [aScreens count] == 0)
40   {
41     return 0;
42   }
43
44   NSScreen* aScreen = (NSScreen* )[aScreens objectAtIndex: 0];
45   NSDictionary* aDict = [aScreen deviceDescription];
46   NSNumber* aNumber = [aDict objectForKey: @"NSScreenNumber"];
47   if (aNumber == NULL
48   || [aNumber isKindOfClass: [NSNumber class]] == NO)
49   {
50     return 0;
51   }
52
53   CGDirectDisplayID aDispId = [aNumber unsignedIntValue];
54   CGRect aRect = CGDisplayBounds(aDispId);
55   return Standard_Integer(aRect.origin.y + aRect.size.height);
56 }
57 #endif
58
59 // =======================================================================
60 // function : Cocoa_Window
61 // purpose  :
62 // =======================================================================
63 Cocoa_Window::Cocoa_Window (const Standard_CString theTitle,
64                             const Standard_Integer thePxLeft,
65                             const Standard_Integer thePxTop,
66                             const Standard_Integer thePxWidth,
67                             const Standard_Integer thePxHeight)
68 : Aspect_Window (),
69 #if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
70   myHWindow (NULL),
71 #endif
72   myHView   (NULL),
73   myXLeft   (thePxLeft),
74   myYTop    (thePxTop),
75   myXRight  (thePxLeft + thePxWidth),
76   myYBottom (thePxTop + thePxHeight)
77 {
78 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
79   //
80 #else
81   if (thePxWidth <= 0 || thePxHeight <= 0)
82   {
83     Aspect_WindowDefinitionError::Raise ("Coordinate(s) out of range");
84   }
85   else if (NSApp == NULL)
86   {
87     Aspect_WindowDefinitionError::Raise ("Cocoa application should be instantiated before window");
88     return;
89   }
90
91   // convert top-bottom coordinates to bottom-top (Cocoa)
92   myYTop    = getScreenBottom() - myYBottom;
93   myYBottom = myYTop + thePxHeight;
94
95   Cocoa_LocalPool aLocalPool;
96   NSUInteger aWinStyle = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask;
97   NSRect aRectNs = NSMakeRect (float(myXLeft), float(myYTop), float(thePxWidth), float(thePxHeight));
98   myHWindow = [[NSWindow alloc] initWithContentRect: aRectNs
99                                           styleMask: aWinStyle
100                                             backing: NSBackingStoreBuffered
101                                               defer: NO];
102   if (myHWindow == NULL)
103   {
104     Aspect_WindowDefinitionError::Raise ("Unable to create window");
105   }
106   myHView = [[myHWindow contentView] retain];
107
108   NSString* aTitleNs = [[NSString alloc] initWithUTF8String: theTitle];
109   [myHWindow setTitle: aTitleNs];
110   [aTitleNs release];
111
112   // do not destroy NSWindow on close - we didn't handle it!
113   [myHWindow setReleasedWhenClosed: NO];
114 #endif
115 }
116
117 // =======================================================================
118 // function : Cocoa_Window
119 // purpose  :
120 // =======================================================================
121 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
122 Cocoa_Window::Cocoa_Window (UIView* theViewNS)
123 : Aspect_Window(),
124 #else
125 Cocoa_Window::Cocoa_Window (NSView* theViewNS)
126 : Aspect_Window(),
127   myHWindow (NULL),
128 #endif
129   myHView   (NULL),
130   myXLeft   (0),
131   myYTop    (0),
132   myXRight  (512),
133   myYBottom (512)
134 {
135 #if defined(HAVE_OBJC_ARC)
136   myHView = theViewNS;
137 #else
138   myHView = [theViewNS retain];
139 #endif
140   DoResize();
141 }
142
143 // =======================================================================
144 // function : Destroy
145 // purpose  :
146 // =======================================================================
147 void Cocoa_Window::Destroy()
148 {
149 #if !defined(HAVE_OBJC_ARC)
150   Cocoa_LocalPool aLocalPool;
151 #endif
152 #if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
153   if (myHWindow != NULL)
154   {
155   #if !defined(HAVE_OBJC_ARC)
156     //[myHWindow close];
157     [myHWindow release];
158   #endif
159     myHWindow = NULL;
160   }
161 #endif
162   if (myHView != NULL)
163   {
164   #if !defined(HAVE_OBJC_ARC)
165     [myHView release];
166   #endif
167     myHView = NULL;
168   }
169 }
170
171 // =======================================================================
172 // function : SetHView
173 // purpose  :
174 // =======================================================================
175 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
176 void Cocoa_Window::SetHView (UIView* theView)
177 {
178 #else
179 void Cocoa_Window::SetHView (NSView* theView)
180 {
181   if (myHWindow != NULL)
182   {
183     [myHWindow setContentView: theView];
184   }
185 #endif
186
187 #if defined(HAVE_OBJC_ARC)
188   myHView = theView;
189 #else
190   if (myHView != NULL)
191   {
192     [myHView release];
193     myHView = NULL;
194   }
195   myHView = [theView retain];
196 #endif
197 }
198
199 // =======================================================================
200 // function : IsMapped
201 // purpose  :
202 // =======================================================================
203 Standard_Boolean Cocoa_Window::IsMapped() const
204 {
205   if (IsVirtual())
206   {
207     return Standard_True;
208   }
209
210 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
211   return myHView != NULL;
212 #else
213   return myHView != NULL
214    &&  [[myHView window] isVisible];
215 #endif
216 }
217
218 // =======================================================================
219 // function : Map
220 // purpose  :
221 // =======================================================================
222 void Cocoa_Window::Map() const
223 {
224   if (IsVirtual())
225   {
226     return;
227   }
228
229   if (myHView != NULL)
230   {
231   #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
232     //
233   #else
234     [[myHView window] orderFront: NULL];
235   #endif
236   }
237 }
238
239 // =======================================================================
240 // function : Unmap
241 // purpose  :
242 // =======================================================================
243 void Cocoa_Window::Unmap() const
244 {
245   if (myHView != NULL)
246   {
247   #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
248     //
249   #else
250     [[myHView window] orderOut: NULL];
251   #endif
252   }
253 }
254
255 // =======================================================================
256 // function : DoResize
257 // purpose  :
258 // =======================================================================
259 Aspect_TypeOfResize Cocoa_Window::DoResize() const
260 {
261   if (myHView == NULL)
262   {
263     return Aspect_TOR_UNKNOWN;
264   }
265
266 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
267   CGRect aBounds = [myHView bounds];
268 #else
269   NSRect aBounds = [myHView bounds];
270 #endif
271   Standard_Integer aMask = 0;
272   Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
273
274   if (Abs ((Standard_Integer )aBounds.origin.x                         - myXLeft  ) > 2) aMask |= 1;
275   if (Abs ((Standard_Integer )(aBounds.origin.x + aBounds.size.width)  - myXRight ) > 2) aMask |= 2;
276   if (Abs ((Standard_Integer )aBounds.origin.y                         - myYTop   ) > 2) aMask |= 4;
277   if (Abs ((Standard_Integer )(aBounds.origin.y + aBounds.size.height) - myYBottom) > 2) aMask |= 8;
278   switch (aMask)
279   {
280     case 0:  aMode = Aspect_TOR_NO_BORDER;               break;
281     case 1:  aMode = Aspect_TOR_LEFT_BORDER;             break;
282     case 2:  aMode = Aspect_TOR_RIGHT_BORDER;            break;
283     case 4:  aMode = Aspect_TOR_TOP_BORDER;              break;
284     case 5:  aMode = Aspect_TOR_LEFT_AND_TOP_BORDER;     break;
285     case 6:  aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER;    break;
286     case 8:  aMode = Aspect_TOR_BOTTOM_BORDER;           break;
287     case 9:  aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER;  break;
288     case 10: aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; break;
289     default: break;
290   }
291
292   *((Standard_Integer* )&myXLeft   ) = (Standard_Integer )aBounds.origin.x;
293   *((Standard_Integer* )&myXRight  ) = (Standard_Integer )(aBounds.origin.x + aBounds.size.width);
294   *((Standard_Integer* )&myYTop    ) = (Standard_Integer )aBounds.origin.y;
295   *((Standard_Integer* )&myYBottom ) = (Standard_Integer )(aBounds.origin.y + aBounds.size.height);
296   return aMode;
297 }
298
299 // =======================================================================
300 // function : DoMapping
301 // purpose  :
302 // =======================================================================
303 Standard_Boolean Cocoa_Window::DoMapping() const
304 {
305   return Standard_True;
306 }
307
308 // =======================================================================
309 // function : Ratio
310 // purpose  :
311 // =======================================================================
312 Quantity_Ratio Cocoa_Window::Ratio() const
313 {
314   if (myHView == NULL)
315   {
316     return 1.0;
317   }
318
319 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
320   CGRect aBounds = [myHView bounds];
321 #else
322   NSRect aBounds = [myHView bounds];
323 #endif
324   return Quantity_Ratio (aBounds.size.width / aBounds.size.height);
325 }
326
327 // =======================================================================
328 // function : Position
329 // purpose  :
330 // =======================================================================
331 void Cocoa_Window::Position (Standard_Integer& X1, Standard_Integer& Y1,
332                              Standard_Integer& X2, Standard_Integer& Y2) const
333 {
334 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
335   CGRect aBounds = [myHView bounds];
336   X1 = 0;
337   Y1 = 0;
338   X2 = (Standard_Integer )aBounds.size.width;
339   Y2 = (Standard_Integer )aBounds.size.height;
340 #else
341   NSWindow* aWindow = [myHView window];
342   NSRect aWindowRect = [aWindow frame];
343   X1 = (Standard_Integer) aWindowRect.origin.x;
344   Y1 = getScreenBottom() - (Standard_Integer) aWindowRect.origin.y - (Standard_Integer) aWindowRect.size.height;
345   X2 = X1 + (Standard_Integer) aWindowRect.size.width;
346   Y2 = Y1 + (Standard_Integer) aWindowRect.size.height;
347 #endif
348 }
349
350 // =======================================================================
351 // function : Size
352 // purpose  :
353 // =======================================================================
354 void Cocoa_Window::Size (Standard_Integer& theWidth,
355                          Standard_Integer& theHeight) const
356 {
357   if (myHView == NULL)
358   {
359     return;
360   }
361
362 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
363   CGRect aBounds = [myHView bounds];
364 #else
365   NSRect aBounds = [myHView bounds];
366 #endif
367   theWidth  = (Standard_Integer )aBounds.size.width;
368   theHeight = (Standard_Integer )aBounds.size.height;
369 }