0032433: Visualization, TKService - introduce Wasm_Window implementing Aspect_Window...
[occt.git] / src / Aspect / Aspect_WindowInputListener.cxx
1 // Copyright (c) 2021 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
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
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.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <Aspect_WindowInputListener.hxx>
15
16 #include <WNT_HIDSpaceMouse.hxx>
17
18 // =======================================================================
19 // function : Aspect_WindowInputListener
20 // purpose  :
21 // =======================================================================
22 Aspect_WindowInputListener::Aspect_WindowInputListener()
23 : myMousePressed   (Aspect_VKeyMouse_NONE),
24   myMouseModifiers (Aspect_VKeyFlags_NONE),
25   //
26   my3dMouseNoRotate  (false, false, false),
27   my3dMouseToReverse (true,  false, false),
28   my3dMouseAccelTrans  (2.0f),
29   my3dMouseAccelRotate (4.0f),
30   my3dMouseIsQuadric   (true)
31 {
32   memset(my3dMouseButtonState, 0, sizeof(my3dMouseButtonState));
33   myEventTimer.Start();
34 }
35
36 // =======================================================================
37 // function : ~Aspect_WindowInputListener
38 // purpose  :
39 // =======================================================================
40 Aspect_WindowInputListener::~Aspect_WindowInputListener()
41 {
42   //
43 }
44
45 // =======================================================================
46 // function : KeyDown
47 // purpose  :
48 // =======================================================================
49 void Aspect_WindowInputListener::KeyDown (Aspect_VKey theKey,
50                                           double theTime,
51                                           double thePressure)
52 {
53   myKeys.KeyDown (theKey, theTime, thePressure);
54 }
55
56 // =======================================================================
57 // function : KeyUp
58 // purpose  :
59 // =======================================================================
60 void Aspect_WindowInputListener::KeyUp (Aspect_VKey theKey,
61                                         double theTime)
62 {
63   myKeys.KeyUp (theKey, theTime);
64 }
65
66 // =======================================================================
67 // function : KeyFromAxis
68 // purpose  :
69 // =======================================================================
70 void Aspect_WindowInputListener::KeyFromAxis (Aspect_VKey theNegative,
71                                               Aspect_VKey thePositive,
72                                               double theTime,
73                                               double thePressure)
74 {
75   myKeys.KeyFromAxis (theNegative, thePositive, theTime, thePressure);
76 }
77
78 // =======================================================================
79 // function : AddTouchPoint
80 // purpose  :
81 // =======================================================================
82 void Aspect_WindowInputListener::AddTouchPoint (Standard_Size theId,
83                                                 const Graphic3d_Vec2d& thePnt,
84                                                 Standard_Boolean theClearBefore)
85 {
86   if (theClearBefore)
87   {
88     RemoveTouchPoint ((Standard_Size )-1);
89   }
90
91   myTouchPoints.Add (theId, Aspect_Touch (thePnt, false));
92 }
93
94 // =======================================================================
95 // function : RemoveTouchPoint
96 // purpose  :
97 // =======================================================================
98 bool Aspect_WindowInputListener::RemoveTouchPoint (Standard_Size theId,
99                                                    Standard_Boolean theClearSelectPnts)
100 {
101   (void )theClearSelectPnts;
102   if (theId == (Standard_Size )-1)
103   {
104     myTouchPoints.Clear (false);
105   }
106   else
107   {
108     const Standard_Integer anOldExtent = myTouchPoints.Extent();
109     myTouchPoints.RemoveKey (theId);
110     if (myTouchPoints.Extent() == anOldExtent)
111     {
112       return false;
113     }
114   }
115
116   if (myTouchPoints.Extent() == 1)
117   {
118     // avoid incorrect transition from pinch to one finger
119     Aspect_Touch& aFirstTouch = myTouchPoints.ChangeFromIndex (1);
120     aFirstTouch.To = aFirstTouch.From;
121   }
122   return true;
123 }
124
125 // =======================================================================
126 // function : UpdateTouchPoint
127 // purpose  :
128 // =======================================================================
129 void Aspect_WindowInputListener::UpdateTouchPoint (Standard_Size theId,
130                                                    const Graphic3d_Vec2d& thePnt)
131 {
132   if (Aspect_Touch* aTouch = myTouchPoints.ChangeSeek (theId))
133   {
134     aTouch->To = thePnt;
135   }
136   else
137   {
138     AddTouchPoint (theId, thePnt);
139   }
140 }
141
142 // =======================================================================
143 // function : update3dMouseTranslation
144 // purpose  :
145 // =======================================================================
146 bool Aspect_WindowInputListener::update3dMouseTranslation (const WNT_HIDSpaceMouse& theEvent)
147 {
148   if (!theEvent.IsTranslation())
149   {
150     return false;
151   }
152
153   bool isIdle = true;
154   const double aTimeStamp = EventTime();
155   const Graphic3d_Vec3d aTrans = theEvent.Translation (isIdle, my3dMouseIsQuadric) * my3dMouseAccelTrans;
156   myKeys.KeyFromAxis (Aspect_VKey_NavSlideLeft, Aspect_VKey_NavSlideRight, aTimeStamp, aTrans.x());
157   myKeys.KeyFromAxis (Aspect_VKey_NavForward,   Aspect_VKey_NavBackward,   aTimeStamp, aTrans.y());
158   myKeys.KeyFromAxis (Aspect_VKey_NavSlideUp,   Aspect_VKey_NavSlideDown,  aTimeStamp, aTrans.z());
159   return true;
160 }
161
162 // =======================================================================
163 // function : update3dMouseRotation
164 // purpose  :
165 // =======================================================================
166 bool Aspect_WindowInputListener::update3dMouseRotation (const WNT_HIDSpaceMouse& theEvent)
167 {
168   if (!theEvent.IsRotation())
169   {
170     return false;
171   }
172
173   bool isIdle = true, toUpdate = false;
174   const double aTimeStamp = EventTime();
175   const Graphic3d_Vec3d aRot3 = theEvent.Rotation (isIdle, my3dMouseIsQuadric) * my3dMouseAccelRotate;
176   if (!my3dMouseNoRotate.x())
177   {
178     KeyFromAxis (Aspect_VKey_NavLookUp,   Aspect_VKey_NavLookDown,  aTimeStamp, !my3dMouseToReverse.x() ? aRot3.x() : -aRot3.x());
179     toUpdate = true;
180   }
181   if (!my3dMouseNoRotate.y())
182   {
183     KeyFromAxis (Aspect_VKey_NavRollCW,   Aspect_VKey_NavRollCCW,   aTimeStamp, !my3dMouseToReverse.y() ? aRot3.y() : -aRot3.y());
184     toUpdate = true;
185   }
186   if (!my3dMouseNoRotate.z())
187   {
188     KeyFromAxis (Aspect_VKey_NavLookLeft, Aspect_VKey_NavLookRight, aTimeStamp, !my3dMouseToReverse.z() ? aRot3.z() : -aRot3.z());
189     toUpdate = true;
190   }
191   return toUpdate;
192 }
193
194 // =======================================================================
195 // function : update3dMouseKeys
196 // purpose  :
197 // =======================================================================
198 bool Aspect_WindowInputListener::update3dMouseKeys (const WNT_HIDSpaceMouse& theEvent)
199 {
200   bool toUpdate = false;
201   const double aTimeStamp = EventTime();
202   if (theEvent.IsKeyState())
203   {
204     const uint32_t aKeyState = theEvent.KeyState();
205     for (unsigned short aKeyBit = 0; aKeyBit < 32; ++aKeyBit)
206     {
207       const bool isPressed  = (aKeyState & (1 << aKeyBit)) != 0;
208       const bool isReleased = my3dMouseButtonState[aKeyBit] && !isPressed;
209       //const bool isRepeated = my3dMouseButtonState[aKeyBit] &&  isPressed;
210       my3dMouseButtonState[aKeyBit] = isPressed;
211       if (!isReleased && !isPressed)
212       {
213         continue;
214       }
215
216       const Aspect_VKey aVKey = theEvent.HidToSpaceKey (aKeyBit);
217       if (aVKey != Aspect_VKey_UNKNOWN)
218       {
219         toUpdate = true;
220         if (isPressed)
221         {
222           KeyDown (aVKey, aTimeStamp);
223         }
224         else
225         {
226           KeyUp (aVKey, aTimeStamp);
227         }
228       }
229     }
230   }
231   return toUpdate;
232 }