0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / ViewerTest / ViewerTest_ViewerCommands_1.mm
CommitLineData
d5f74e42 1// Copyright (c) 2013-2014 OPEN CASCADE SAS
4fe56619 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
4fe56619 4//
d5f74e42 5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
4fe56619 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
4fe56619 13
14#if defined(__APPLE__) && !defined(MACOSX_USE_GLX)
15
16#import <Cocoa/Cocoa.h>
17
18#include <Cocoa_Window.hxx>
19#include <ViewerTest.hxx>
49582f9d 20#include <ViewerTest_EventManager.hxx>
4fe56619 21#include <V3d_View.hxx>
22#include <V3d_Viewer.hxx>
23#include <AIS_InteractiveContext.hxx>
18d715bd 24#include <TCollection_AsciiString.hxx>
25#include <NCollection_DoubleMap.hxx>
4fe56619 26
e2b4dea2 27#if !defined(MAC_OS_X_VERSION_10_12) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12)
28 // replacements for macOS versions before 10.12
c64135f7 29 #define NSEventModifierFlagControl NSControlKeyMask
30 #define NSEventModifierFlagShift NSShiftKeyMask
31 #define NSEventModifierFlagOption NSAlternateKeyMask
32 #define NSEventModifierFlagCommand NSCommandKeyMask
33 #define NSEventModifierFlagFunction NSFunctionKeyMask
e2b4dea2 34#endif
35
4fe56619 36//! Custom Cocoa view to handle events
37@interface ViewerTest_CocoaEventManagerView : NSView
38@end
39
18d715bd 40//! Custom Cocoa window delegate to handle window events
41@interface Cocoa_WindowController : NSObject <NSWindowDelegate>
42@end
43
e084dbbc 44extern void ActivateView (const TCollection_AsciiString& theViewName,
45 Standard_Boolean theToUpdate = Standard_True);
4fe56619 46
18d715bd 47extern NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
18d715bd 48
49// =======================================================================
50// function : GetCocoaScreenResolution
51// purpose :
52// =======================================================================
53void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight)
54{
55 NSRect aRect = [[NSScreen mainScreen] visibleFrame];
56 theWidth = (Standard_Integer )aRect.size.width;
57 theHeight = (Standard_Integer )aRect.size.height;
58}
59
60// =======================================================================
61// function : FindViewId
62// purpose :
63// =======================================================================
64TCollection_AsciiString FindViewId (const NSWindow* theWindow)
65{
66 TCollection_AsciiString aViewId = "";
67 NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter(ViewerTest_myViews);
68 for (;anIter.More();anIter.Next())
69 {
70 NSView* aView = Handle(Cocoa_Window)::DownCast
71 (anIter.Value()->Window())->HView();
72 NSWindow* aWindow = [aView window];
73 if (aWindow == theWindow)
74 {
75 aViewId = anIter.Key1();
76 return aViewId;
77 }
78 }
79 return aViewId;
80}
81
82@implementation Cocoa_WindowController
83
84- (void )windowWillClose: (NSNotification* )theNotification
85{
5ef127d0 86 (void )theNotification;
18d715bd 87 TCollection_AsciiString aViewId = "";
88 if (ViewerTest_myViews.IsBound2 (ViewerTest::CurrentView()))
89 {
90 aViewId = ViewerTest_myViews.Find2 (ViewerTest::CurrentView());
91 }
92 ViewerTest::RemoveView (aViewId);
93}
94
95- (void )windowDidBecomeKey: (NSNotification* )theNotification
96{
97 NSWindow *aWindow = [theNotification object];
98 ActivateView (FindViewId (aWindow));
99}
100
101@end
102
4fe56619 103// =======================================================================
104// function : ViewerMainLoop
105// purpose :
106// =======================================================================
107int ViewerMainLoop (Standard_Integer, const char** )
108{
109 // unused
110 return 0;
111}
112
113// =======================================================================
114// function : ViewerTest_SetCocoaEventManagerView
115// purpose :
116// =======================================================================
117void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow)
118{
119 if (theWindow.IsNull())
120 {
121 return;
122 }
123
124 NSWindow* aWin = [theWindow->HView() window];
125 NSRect aBounds = [[aWin contentView] bounds];
126
127 ViewerTest_CocoaEventManagerView* aView = [[ViewerTest_CocoaEventManagerView alloc] initWithFrame: aBounds];
128
129 // replace content view in the window
130 theWindow->SetHView (aView);
131
18d715bd 132 // set delegate for window
133 Cocoa_WindowController* aWindowController = [[[Cocoa_WindowController alloc] init] autorelease];
134 [aWin setDelegate: aWindowController];
135
4fe56619 136 // make view as first responder in winow to capture all useful events
137 [aWin makeFirstResponder: aView];
138 [aWin setAcceptsMouseMovedEvents: YES];
139
140 // should be retained by parent NSWindow
141 [aView release];
142}
143
49582f9d 144//! Retrieve cursor position
145static Graphic3d_Vec2i getMouseCoords (NSView* theView,
146 NSEvent* theEvent)
4fe56619 147{
148 NSPoint aMouseLoc = [theView convertPoint: [theEvent locationInWindow] fromView: nil];
149 NSRect aBounds = [theView bounds];
49582f9d 150 return Graphic3d_Vec2i (Standard_Integer(aMouseLoc.x),
151 Standard_Integer(aBounds.size.height - aMouseLoc.y));
152}
4fe56619 153
49582f9d 154//! Convert key flags from mouse event.
155static Aspect_VKeyFlags getMouseKeyFlags (NSEvent* theEvent)
156{
157 Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
158 if (([theEvent modifierFlags] & NSEventModifierFlagShift) != 0)
159 {
160 aFlags |= Aspect_VKeyFlags_SHIFT;
161 }
162 if (([theEvent modifierFlags] & NSEventModifierFlagControl) != 0)
163 {
164 aFlags |= Aspect_VKeyFlags_CTRL;
165 }
166 if (([theEvent modifierFlags] & NSEventModifierFlagOption) != 0)
167 {
168 aFlags |= Aspect_VKeyFlags_ALT;
169 }
170 if (([theEvent modifierFlags] & NSEventModifierFlagFunction) != 0)
171 {
172 //aFlags |= Aspect_VKeyFlags_FUNC;
173 }
174 if (([theEvent modifierFlags] & NSEventModifierFlagCommand) != 0)
175 {
176 //aFlags |= Aspect_VKeyFlags_CMD;
177 }
178 return aFlags;
4fe56619 179}
180
181@implementation ViewerTest_CocoaEventManagerView
182
183// =======================================================================
184// function : setFrameSize
185// purpose :
186// =======================================================================
187- (void )setFrameSize: (NSSize )theNewSize
188{
189 [super setFrameSize: theNewSize];
49582f9d 190 ViewerTest::CurrentEventManager()->ProcessConfigure();
4fe56619 191}
192
193// =======================================================================
194// function : drawRect
195// purpose :
196// =======================================================================
197- (void )drawRect: (NSRect )theDirtyRect
198{
5ef127d0 199 (void )theDirtyRect;
49582f9d 200 if (!ViewerTest::CurrentEventManager().IsNull())
201 {
202 ViewerTest::CurrentEventManager()->ProcessExpose();
203 }
4fe56619 204}
205
206// =======================================================================
207// function : mouseMoved
208// purpose :
209// =======================================================================
210- (void )mouseMoved: (NSEvent* )theEvent
211{
49582f9d 212 const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
213 const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
214 const Aspect_VKeyMouse aButtons = ViewerTest::CurrentEventManager()->PressedMouseButtons();
215 ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
216 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
4fe56619 217}
218
219// =======================================================================
220// function : acceptsFirstResponder
221// purpose :
222// =======================================================================
223- (BOOL )acceptsFirstResponder
224{
225 return YES;
226}
227
228// =======================================================================
229// function : mouseDown
230// purpose :
231// =======================================================================
232- (void )mouseDown: (NSEvent* )theEvent
233{
49582f9d 234 const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
235 const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
236 ViewerTest::CurrentEventManager()->PressMouseButton (aPos, Aspect_VKeyMouse_LeftButton, aFlags, false);
237 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
4fe56619 238}
239
240// =======================================================================
241// function : mouseUp
242// purpose :
243// =======================================================================
244- (void )mouseUp: (NSEvent* )theEvent
245{
49582f9d 246 const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
247 const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
248 ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, Aspect_VKeyMouse_LeftButton, aFlags, false);
249 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
4fe56619 250}
251
4fe56619 252// =======================================================================
253// function : mouseDragged
254// purpose :
255// =======================================================================
256- (void )mouseDragged: (NSEvent* )theEvent
257{
49582f9d 258 const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
259 const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
260 const Aspect_VKeyMouse aButtons = ViewerTest::CurrentEventManager()->PressedMouseButtons();
261 ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
262 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
4fe56619 263}
264
265// =======================================================================
266// function : rightMouseDown
267// purpose :
268// =======================================================================
269- (void )rightMouseDown: (NSEvent* )theEvent
270{
49582f9d 271 const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
272 const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
273 ViewerTest::CurrentEventManager()->PressMouseButton (aPos, Aspect_VKeyMouse_RightButton, aFlags, false);
274 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
4fe56619 275}
276
277// =======================================================================
278// function : rightMouseUp
279// purpose :
280// =======================================================================
281- (void )rightMouseUp: (NSEvent* )theEvent
282{
49582f9d 283 const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
284 const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
285 ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, Aspect_VKeyMouse_RightButton, aFlags, false);
286 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
4fe56619 287}
288
289// =======================================================================
290// function : rightMouseDragged
291// purpose :
292// =======================================================================
293- (void )rightMouseDragged: (NSEvent* )theEvent
294{
49582f9d 295 const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
296 const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
297 const Aspect_VKeyMouse aButtons = ViewerTest::CurrentEventManager()->PressedMouseButtons();
298 ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
299 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
4fe56619 300}
301
302// =======================================================================
303// function : scrollWheel
304// purpose :
305// =======================================================================
306- (void )scrollWheel: (NSEvent* )theEvent
307{
49582f9d 308 const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
309 const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
310
311 const Standard_Real aDelta = [theEvent deltaY];
4fe56619 312 if (Abs (aDelta) < 0.001)
313 {
314 // a lot of values near zero can be generated by touchpad
315 return;
316 }
317
49582f9d 318 ViewerTest::CurrentEventManager()->UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDelta, aFlags));
319 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
4fe56619 320}
321
322// =======================================================================
323// function : keyDown
324// purpose :
325// =======================================================================
326- (void )keyDown: (NSEvent* )theEvent
327{
49582f9d 328 unsigned int aKeyCode = [theEvent keyCode];
329 const Aspect_VKey aVKey = Cocoa_Window::VirtualKeyFromNative (aKeyCode);
330 if (aVKey != Aspect_VKey_UNKNOWN)
4fe56619 331 {
49582f9d 332 const double aTimeStamp = [theEvent timestamp];
333 ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
334 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
4fe56619 335 }
336
49582f9d 337 //NSString* aStringNs = [theEvent characters];
338 //if (aStringNs != NULL && [aStringNs length] != 1)
339 //{
340 // const Standard_CString aString = [aStringNs UTF8String];
341 //}
342}
343
344// =======================================================================
345// function : keyUp
346// purpose :
347// =======================================================================
348- (void )keyUp: (NSEvent* )theEvent
349{
350 unsigned int aKeyCode = [theEvent keyCode];
351 const Aspect_VKey aVKey = Cocoa_Window::VirtualKeyFromNative (aKeyCode);
352 if (aVKey != Aspect_VKey_UNKNOWN)
353 {
354 const double aTimeStamp = [theEvent timestamp];
355 ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
356 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
357 }
4fe56619 358}
359
360@end
361
362#endif