0023670: Support for multiple 3D views: edited commands: vinit; added commands: vclos...
[occt.git] / src / ViewerTest / ViewerTest_ViewerCommands_1.mm
CommitLineData
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
39extern void ActivateView (const TCollection_AsciiString& theViewName);
4fe56619 40extern void VT_ProcessExpose();
41extern void VT_ProcessConfigure();
42extern void VT_ProcessKeyPress (const char* theBuffer);
43extern void VT_ProcessMotion();
44extern void VT_ProcessButton3Press();
45extern void VT_ProcessButton3Release();
46extern void VT_ProcessControlButton2Motion();
47extern void VT_ProcessControlButton3Motion();
48extern Standard_Boolean VT_ProcessButton1Press (Standard_Integer theArgsNb,
49 const char** theArgsVec,
50 Standard_Boolean theToPick,
51 Standard_Boolean theIsShift);
52extern void VT_ProcessButton1Release(Standard_Boolean theIsShift);
53
18d715bd 54extern NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
4fe56619 55extern int X_Motion; // Current cursor position
56extern int Y_Motion;
57extern int X_ButtonPress; // Last ButtonPress position
58extern int Y_ButtonPress;
59extern Standard_Boolean IsDragged;
60
18d715bd 61// =======================================================================
62// function : SetCocoaWindowTitle
63// purpose :
64// =======================================================================
65void 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// =======================================================================
80void 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// =======================================================================
91TCollection_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// =======================================================================
133int ViewerMainLoop (Standard_Integer, const char** )
134{
135 // unused
136 return 0;
137}
138
139// =======================================================================
140// function : ViewerTest_SetCocoaEventManagerView
141// purpose :
142// =======================================================================
143void 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// =======================================================================
174static 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