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 | |
30 | IMPLEMENT_STANDARD_HANDLE (Cocoa_Window, Aspect_Window) |
31 | IMPLEMENT_STANDARD_RTTIEXT(Cocoa_Window, Aspect_Window) |
32 | |
4fe56619 |
33 | static 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 | // ======================================================================= |
60 | Cocoa_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 | // ======================================================================= |
112 | Cocoa_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 | // ======================================================================= |
128 | void 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 | // ======================================================================= |
148 | NSView* Cocoa_Window::HView() const |
149 | { |
150 | return myHView; |
151 | } |
152 | |
153 | // ======================================================================= |
154 | // function : SetHView |
155 | // purpose : |
156 | // ======================================================================= |
157 | void 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 | // ======================================================================= |
175 | Standard_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 | // ======================================================================= |
189 | void 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 | // ======================================================================= |
206 | void 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 | // ======================================================================= |
218 | Aspect_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 | // ======================================================================= |
258 | Standard_Boolean Cocoa_Window::DoMapping() const |
259 | { |
260 | return Standard_True; |
261 | } |
262 | |
4fe56619 |
263 | // ======================================================================= |
264 | // function : Ratio |
265 | // purpose : |
266 | // ======================================================================= |
267 | Quantity_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 | // ======================================================================= |
282 | void 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 | // ======================================================================= |
297 | void 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 | } |