4fe56619 |
1 | // Copyright (c) 2012 OPEN CASCADE SAS |
2 | // |
3 | // The content of this file is subject to the Open CASCADE Technology Public |
4 | // License Version 6.5 (the "License"). You may not use the content of this file |
5 | // except in compliance with the License. Please obtain a copy of the License |
6 | // at http://www.opencascade.org and read it completely before using this file. |
7 | // |
8 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
9 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
10 | // |
11 | // The Original Code and all software distributed under the License is |
12 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
13 | // Initial Developer hereby disclaims all such warranties, including without |
14 | // limitation, any warranties of merchantability, fitness for a particular |
15 | // purpose or non-infringement. Please see the License for the specific terms |
16 | // and conditions governing the rights and limitations under the License. |
17 | |
18 | #if defined(__APPLE__) && !defined(MACOSX_USE_GLX) |
19 | |
20 | #import <Cocoa/Cocoa.h> |
21 | |
22 | #include <Cocoa_Window.hxx> |
23 | #include <ViewerTest.hxx> |
24 | #include <V3d_View.hxx> |
25 | #include <V3d_Viewer.hxx> |
26 | #include <AIS_InteractiveContext.hxx> |
27 | #include <NIS_View.hxx> |
18d715bd |
28 | #include <TCollection_AsciiString.hxx> |
29 | #include <NCollection_DoubleMap.hxx> |
4fe56619 |
30 | |
31 | //! Custom Cocoa view to handle events |
32 | @interface ViewerTest_CocoaEventManagerView : NSView |
33 | @end |
34 | |
18d715bd |
35 | //! Custom Cocoa window delegate to handle window events |
36 | @interface Cocoa_WindowController : NSObject <NSWindowDelegate> |
37 | @end |
38 | |
39 | extern void ActivateView (const TCollection_AsciiString& theViewName); |
4fe56619 |
40 | extern void VT_ProcessExpose(); |
41 | extern void VT_ProcessConfigure(); |
42 | extern void VT_ProcessKeyPress (const char* theBuffer); |
43 | extern void VT_ProcessMotion(); |
44 | extern void VT_ProcessButton3Press(); |
45 | extern void VT_ProcessButton3Release(); |
46 | extern void VT_ProcessControlButton2Motion(); |
47 | extern void VT_ProcessControlButton3Motion(); |
48 | extern Standard_Boolean VT_ProcessButton1Press (Standard_Integer theArgsNb, |
49 | const char** theArgsVec, |
50 | Standard_Boolean theToPick, |
51 | Standard_Boolean theIsShift); |
52 | extern void VT_ProcessButton1Release(Standard_Boolean theIsShift); |
53 | |
18d715bd |
54 | extern NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews; |
4fe56619 |
55 | extern int X_Motion; // Current cursor position |
56 | extern int Y_Motion; |
57 | extern int X_ButtonPress; // Last ButtonPress position |
58 | extern int Y_ButtonPress; |
59 | extern Standard_Boolean IsDragged; |
60 | |
18d715bd |
61 | // ======================================================================= |
62 | // function : SetCocoaWindowTitle |
63 | // purpose : |
64 | // ======================================================================= |
65 | void SetCocoaWindowTitle (const Handle(Cocoa_Window)& theWindow, Standard_CString theTitle) |
66 | { |
67 | NSView* aView = theWindow->HView(); |
68 | NSWindow* aWindow = [aView window]; |
69 | |
70 | NSString* aTitleNS = [[NSString alloc] initWithUTF8String: theTitle]; |
71 | [aWindow setTitle: aTitleNS]; |
72 | [aTitleNS release]; |
73 | |
74 | } |
75 | |
76 | // ======================================================================= |
77 | // function : GetCocoaScreenResolution |
78 | // purpose : |
79 | // ======================================================================= |
80 | void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight) |
81 | { |
82 | NSRect aRect = [[NSScreen mainScreen] visibleFrame]; |
83 | theWidth = (Standard_Integer )aRect.size.width; |
84 | theHeight = (Standard_Integer )aRect.size.height; |
85 | } |
86 | |
87 | // ======================================================================= |
88 | // function : FindViewId |
89 | // purpose : |
90 | // ======================================================================= |
91 | TCollection_AsciiString FindViewId (const NSWindow* theWindow) |
92 | { |
93 | TCollection_AsciiString aViewId = ""; |
94 | NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter(ViewerTest_myViews); |
95 | for (;anIter.More();anIter.Next()) |
96 | { |
97 | NSView* aView = Handle(Cocoa_Window)::DownCast |
98 | (anIter.Value()->Window())->HView(); |
99 | NSWindow* aWindow = [aView window]; |
100 | if (aWindow == theWindow) |
101 | { |
102 | aViewId = anIter.Key1(); |
103 | return aViewId; |
104 | } |
105 | } |
106 | return aViewId; |
107 | } |
108 | |
109 | @implementation Cocoa_WindowController |
110 | |
111 | - (void )windowWillClose: (NSNotification* )theNotification |
112 | { |
113 | TCollection_AsciiString aViewId = ""; |
114 | if (ViewerTest_myViews.IsBound2 (ViewerTest::CurrentView())) |
115 | { |
116 | aViewId = ViewerTest_myViews.Find2 (ViewerTest::CurrentView()); |
117 | } |
118 | ViewerTest::RemoveView (aViewId); |
119 | } |
120 | |
121 | - (void )windowDidBecomeKey: (NSNotification* )theNotification |
122 | { |
123 | NSWindow *aWindow = [theNotification object]; |
124 | ActivateView (FindViewId (aWindow)); |
125 | } |
126 | |
127 | @end |
128 | |
4fe56619 |
129 | // ======================================================================= |
130 | // function : ViewerMainLoop |
131 | // purpose : |
132 | // ======================================================================= |
133 | int ViewerMainLoop (Standard_Integer, const char** ) |
134 | { |
135 | // unused |
136 | return 0; |
137 | } |
138 | |
139 | // ======================================================================= |
140 | // function : ViewerTest_SetCocoaEventManagerView |
141 | // purpose : |
142 | // ======================================================================= |
143 | void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow) |
144 | { |
145 | if (theWindow.IsNull()) |
146 | { |
147 | return; |
148 | } |
149 | |
150 | NSWindow* aWin = [theWindow->HView() window]; |
151 | NSRect aBounds = [[aWin contentView] bounds]; |
152 | |
153 | ViewerTest_CocoaEventManagerView* aView = [[ViewerTest_CocoaEventManagerView alloc] initWithFrame: aBounds]; |
154 | |
155 | // replace content view in the window |
156 | theWindow->SetHView (aView); |
157 | |
18d715bd |
158 | // set delegate for window |
159 | Cocoa_WindowController* aWindowController = [[[Cocoa_WindowController alloc] init] autorelease]; |
160 | [aWin setDelegate: aWindowController]; |
161 | |
4fe56619 |
162 | // make view as first responder in winow to capture all useful events |
163 | [aWin makeFirstResponder: aView]; |
164 | [aWin setAcceptsMouseMovedEvents: YES]; |
165 | |
166 | // should be retained by parent NSWindow |
167 | [aView release]; |
168 | } |
169 | |
170 | // ======================================================================= |
171 | // function : getMouseCoords |
172 | // purpose : Retrieve cursor position |
173 | // ======================================================================= |
174 | static void getMouseCoords (NSView* theView, |
175 | NSEvent* theEvent, |
176 | Standard_Integer& theX, |
177 | Standard_Integer& theY) |
178 | { |
179 | NSPoint aMouseLoc = [theView convertPoint: [theEvent locationInWindow] fromView: nil]; |
180 | NSRect aBounds = [theView bounds]; |
181 | |
182 | theX = Standard_Integer(aMouseLoc.x); |
183 | theY = Standard_Integer(aBounds.size.height - aMouseLoc.y); |
184 | } |
185 | |
186 | @implementation ViewerTest_CocoaEventManagerView |
187 | |
188 | // ======================================================================= |
189 | // function : setFrameSize |
190 | // purpose : |
191 | // ======================================================================= |
192 | - (void )setFrameSize: (NSSize )theNewSize |
193 | { |
194 | [super setFrameSize: theNewSize]; |
195 | VT_ProcessConfigure(); |
196 | } |
197 | |
198 | // ======================================================================= |
199 | // function : drawRect |
200 | // purpose : |
201 | // ======================================================================= |
202 | - (void )drawRect: (NSRect )theDirtyRect |
203 | { |
204 | VT_ProcessExpose(); |
205 | } |
206 | |
207 | // ======================================================================= |
208 | // function : mouseMoved |
209 | // purpose : |
210 | // ======================================================================= |
211 | - (void )mouseMoved: (NSEvent* )theEvent |
212 | { |
213 | getMouseCoords (self, theEvent, X_Motion, Y_Motion); |
214 | VT_ProcessMotion(); |
215 | } |
216 | |
217 | // ======================================================================= |
218 | // function : acceptsFirstResponder |
219 | // purpose : |
220 | // ======================================================================= |
221 | - (BOOL )acceptsFirstResponder |
222 | { |
223 | return YES; |
224 | } |
225 | |
226 | // ======================================================================= |
227 | // function : mouseDown |
228 | // purpose : |
229 | // ======================================================================= |
230 | - (void )mouseDown: (NSEvent* )theEvent |
231 | { |
232 | getMouseCoords (self, theEvent, X_ButtonPress, Y_ButtonPress); |
233 | VT_ProcessButton1Press (0, NULL, Standard_False, [theEvent modifierFlags] & NSShiftKeyMask); |
234 | } |
235 | |
236 | // ======================================================================= |
237 | // function : mouseUp |
238 | // purpose : |
239 | // ======================================================================= |
240 | - (void )mouseUp: (NSEvent* )theEvent |
241 | { |
242 | getMouseCoords (self, theEvent, X_Motion, Y_Motion); |
243 | VT_ProcessButton1Release([theEvent modifierFlags] & NSShiftKeyMask); |
244 | } |
245 | |
246 | |
247 | // ======================================================================= |
248 | // function : mouseDragged |
249 | // purpose : |
250 | // ======================================================================= |
251 | - (void )mouseDragged: (NSEvent* )theEvent |
252 | { |
253 | IsDragged = Standard_True; |
254 | if ([theEvent modifierFlags] & NSControlKeyMask) |
255 | { |
256 | getMouseCoords (self, theEvent, X_Motion, Y_Motion); |
257 | VT_ProcessControlButton2Motion(); |
258 | } |
259 | } |
260 | |
261 | // ======================================================================= |
262 | // function : rightMouseDown |
263 | // purpose : |
264 | // ======================================================================= |
265 | - (void )rightMouseDown: (NSEvent* )theEvent |
266 | { |
267 | getMouseCoords (self, theEvent, X_ButtonPress, Y_ButtonPress); |
268 | VT_ProcessButton3Press(); // Start rotation |
269 | } |
270 | |
271 | // ======================================================================= |
272 | // function : rightMouseUp |
273 | // purpose : |
274 | // ======================================================================= |
275 | - (void )rightMouseUp: (NSEvent* )theEvent |
276 | { |
277 | VT_ProcessButton3Release(); |
278 | } |
279 | |
280 | // ======================================================================= |
281 | // function : rightMouseDragged |
282 | // purpose : |
283 | // ======================================================================= |
284 | - (void )rightMouseDragged: (NSEvent* )theEvent |
285 | { |
286 | if ([theEvent modifierFlags] & NSControlKeyMask) |
287 | { |
288 | getMouseCoords (self, theEvent, X_Motion, Y_Motion); |
289 | VT_ProcessControlButton3Motion(); |
290 | } |
291 | } |
292 | |
293 | // ======================================================================= |
294 | // function : scrollWheel |
295 | // purpose : |
296 | // ======================================================================= |
297 | - (void )scrollWheel: (NSEvent* )theEvent |
298 | { |
299 | float aDelta = [theEvent deltaY]; |
300 | if (Abs (aDelta) < 0.001) |
301 | { |
302 | // a lot of values near zero can be generated by touchpad |
303 | return; |
304 | } |
305 | |
306 | ViewerTest::CurrentView()->Zoom (0, 0, aDelta, aDelta); |
307 | } |
308 | |
309 | // ======================================================================= |
310 | // function : keyDown |
311 | // purpose : |
312 | // ======================================================================= |
313 | - (void )keyDown: (NSEvent* )theEvent |
314 | { |
315 | NSString* aStringNs = [theEvent characters]; |
316 | if (aStringNs == NULL || [aStringNs length] == 0) |
317 | { |
318 | return; |
319 | } |
320 | |
321 | const Standard_CString aString = [aStringNs UTF8String]; |
322 | VT_ProcessKeyPress (aString); |
323 | } |
324 | |
325 | @end |
326 | |
327 | #endif |