0025809: Visualization, TKOpenGl - fix texture mapping in capping
[occt.git] / src / Cocoa / Cocoa_Window.mm
... / ...
CommitLineData
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 <Cocoa/Cocoa.h>
17
18#include <Cocoa_Window.hxx>
19
20#include <Cocoa_LocalPool.hxx>
21
22#include <Image_AlienPixMap.hxx>
23#include <Aspect_Convert.hxx>
24#include <Aspect_WindowDefinitionError.hxx>
25
26IMPLEMENT_STANDARD_HANDLE (Cocoa_Window, Aspect_Window)
27IMPLEMENT_STANDARD_RTTIEXT(Cocoa_Window, Aspect_Window)
28
29static Standard_Integer getScreenBottom()
30{
31 Cocoa_LocalPool aLocalPool;
32 NSArray* aScreens = [NSScreen screens];
33 if (aScreens == NULL || [aScreens count] == 0)
34 {
35 return 0;
36 }
37
38 NSScreen* aScreen = (NSScreen* )[aScreens objectAtIndex: 0];
39 NSDictionary* aDict = [aScreen deviceDescription];
40 NSNumber* aNumber = [aDict objectForKey: @"NSScreenNumber"];
41 if (aNumber == NULL
42 || [aNumber isKindOfClass: [NSNumber class]] == NO)
43 {
44 return 0;
45 }
46
47 CGDirectDisplayID aDispId = [aNumber unsignedIntValue];
48 CGRect aRect = CGDisplayBounds(aDispId);
49 return Standard_Integer(aRect.origin.y + aRect.size.height);
50}
51
52// =======================================================================
53// function : Cocoa_Window
54// purpose :
55// =======================================================================
56Cocoa_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)
61: Aspect_Window (),
62 myHWindow (NULL),
63 myHView (NULL),
64 myXLeft (thePxLeft),
65 myYTop (thePxTop),
66 myXRight (thePxLeft + thePxWidth),
67 myYBottom (thePxTop + thePxHeight)
68{
69 if (thePxWidth <= 0 || thePxHeight <= 0)
70 {
71 Aspect_WindowDefinitionError::Raise ("Coordinate(s) out of range");
72 }
73 else if (NSApp == NULL)
74 {
75 Aspect_WindowDefinitionError::Raise ("Cocoa application should be instantiated before window");
76 return;
77 }
78
79 // convert top-bottom coordinates to bottom-top (Cocoa)
80 myYTop = getScreenBottom() - myYBottom;
81 myYBottom = myYTop + thePxHeight;
82
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
87 styleMask: aWinStyle
88 backing: NSBackingStoreBuffered
89 defer: NO];
90 if (myHWindow == NULL)
91 {
92 Aspect_WindowDefinitionError::Raise ("Unable to create window");
93 }
94 myHView = [[myHWindow contentView] retain];
95
96 NSString* aTitleNs = [[NSString alloc] initWithUTF8String: theTitle];
97 [myHWindow setTitle: aTitleNs];
98 [aTitleNs release];
99
100 // do not destroy NSWindow on close - we didn't handle it!
101 [myHWindow setReleasedWhenClosed: NO];
102}
103
104// =======================================================================
105// function : Cocoa_Window
106// purpose :
107// =======================================================================
108Cocoa_Window::Cocoa_Window (NSView* theViewNS)
109: Aspect_Window (),
110 myHWindow (NULL),
111 myHView ([theViewNS retain]),
112 myXLeft (0),
113 myYTop (0),
114 myXRight (512),
115 myYBottom (512)
116{
117 DoResize();
118}
119
120// =======================================================================
121// function : Destroy
122// purpose :
123// =======================================================================
124void Cocoa_Window::Destroy()
125{
126 Cocoa_LocalPool aLocalPool;
127 if (myHWindow != NULL)
128 {
129 //[myHWindow close];
130 [myHWindow release];
131 myHWindow = NULL;
132 }
133 if (myHView != NULL)
134 {
135 [myHView release];
136 myHView = NULL;
137 }
138}
139
140// =======================================================================
141// function : HView
142// purpose :
143// =======================================================================
144NSView* Cocoa_Window::HView() const
145{
146 return myHView;
147}
148
149// =======================================================================
150// function : SetHView
151// purpose :
152// =======================================================================
153void Cocoa_Window::SetHView (NSView* theView)
154{
155 if (myHWindow != NULL)
156 {
157 [myHWindow setContentView: theView];
158 }
159 if (myHView != NULL)
160 {
161 [myHView release];
162 myHView = NULL;
163 }
164 myHView = [theView retain];
165}
166
167// =======================================================================
168// function : IsMapped
169// purpose :
170// =======================================================================
171Standard_Boolean Cocoa_Window::IsMapped() const
172{
173 if (IsVirtual())
174 {
175 return Standard_True;
176 }
177
178 return (myHView != NULL) && [[myHView window] isVisible];
179}
180
181// =======================================================================
182// function : Map
183// purpose :
184// =======================================================================
185void Cocoa_Window::Map() const
186{
187 if (IsVirtual())
188 {
189 return;
190 }
191
192 if (myHView != NULL)
193 {
194 [[myHView window] orderFront: NULL];
195 }
196}
197
198// =======================================================================
199// function : Unmap
200// purpose :
201// =======================================================================
202void Cocoa_Window::Unmap() const
203{
204 if (myHView != NULL)
205 {
206 [[myHView window] orderOut: NULL];
207 }
208}
209
210// =======================================================================
211// function : DoResize
212// purpose :
213// =======================================================================
214Aspect_TypeOfResize Cocoa_Window::DoResize() const
215{
216 if (myHView == NULL)
217 {
218 return Aspect_TOR_UNKNOWN;
219 }
220
221 NSRect aBounds = [myHView bounds];
222 Standard_Integer aMask = 0;
223 Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
224
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;
229 switch (aMask)
230 {
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;
240 default: break;
241 }
242
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);
247 return aMode;
248}
249
250// =======================================================================
251// function : DoMapping
252// purpose :
253// =======================================================================
254Standard_Boolean Cocoa_Window::DoMapping() const
255{
256 return Standard_True;
257}
258
259// =======================================================================
260// function : Ratio
261// purpose :
262// =======================================================================
263Quantity_Ratio Cocoa_Window::Ratio() const
264{
265 if (myHView == NULL)
266 {
267 return 1.0;
268 }
269
270 NSRect aBounds = [myHView bounds];
271 return Quantity_Ratio (aBounds.size.width / aBounds.size.height);
272}
273
274// =======================================================================
275// function : Position
276// purpose :
277// =======================================================================
278void Cocoa_Window::Position (Standard_Integer& X1, Standard_Integer& Y1,
279 Standard_Integer& X2, Standard_Integer& Y2) const
280{
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;
287}
288
289// =======================================================================
290// function : Size
291// purpose :
292// =======================================================================
293void Cocoa_Window::Size (Standard_Integer& theWidth,
294 Standard_Integer& theHeight) const
295{
296 if (myHView == NULL)
297 {
298 return;
299 }
300
301 NSRect aBounds = [myHView bounds];
302 theWidth = (Standard_Integer )aBounds.size.width;
303 theHeight = (Standard_Integer )aBounds.size.height;
304}