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