ed6478b81282923f77102c60e4102f80032e2543
[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 : update3dMouseTranslation
80 // purpose  :
81 // =======================================================================
82 bool Aspect_WindowInputListener::update3dMouseTranslation (const WNT_HIDSpaceMouse& theEvent)
83 {
84   if (!theEvent.IsTranslation())
85   {
86     return false;
87   }
88
89   bool isIdle = true;
90   const double aTimeStamp = EventTime();
91   const Graphic3d_Vec3d aTrans = theEvent.Translation (isIdle, my3dMouseIsQuadric) * my3dMouseAccelTrans;
92   myKeys.KeyFromAxis (Aspect_VKey_NavSlideLeft, Aspect_VKey_NavSlideRight, aTimeStamp, aTrans.x());
93   myKeys.KeyFromAxis (Aspect_VKey_NavForward,   Aspect_VKey_NavBackward,   aTimeStamp, aTrans.y());
94   myKeys.KeyFromAxis (Aspect_VKey_NavSlideUp,   Aspect_VKey_NavSlideDown,  aTimeStamp, aTrans.z());
95   return true;
96 }
97
98 // =======================================================================
99 // function : update3dMouseRotation
100 // purpose  :
101 // =======================================================================
102 bool Aspect_WindowInputListener::update3dMouseRotation (const WNT_HIDSpaceMouse& theEvent)
103 {
104   if (!theEvent.IsRotation())
105   {
106     return false;
107   }
108
109   bool isIdle = true, toUpdate = false;
110   const double aTimeStamp = EventTime();
111   const Graphic3d_Vec3d aRot3 = theEvent.Rotation (isIdle, my3dMouseIsQuadric) * my3dMouseAccelRotate;
112   if (!my3dMouseNoRotate.x())
113   {
114     KeyFromAxis (Aspect_VKey_NavLookUp,   Aspect_VKey_NavLookDown,  aTimeStamp, !my3dMouseToReverse.x() ? aRot3.x() : -aRot3.x());
115     toUpdate = true;
116   }
117   if (!my3dMouseNoRotate.y())
118   {
119     KeyFromAxis (Aspect_VKey_NavRollCW,   Aspect_VKey_NavRollCCW,   aTimeStamp, !my3dMouseToReverse.y() ? aRot3.y() : -aRot3.y());
120     toUpdate = true;
121   }
122   if (!my3dMouseNoRotate.z())
123   {
124     KeyFromAxis (Aspect_VKey_NavLookLeft, Aspect_VKey_NavLookRight, aTimeStamp, !my3dMouseToReverse.z() ? aRot3.z() : -aRot3.z());
125     toUpdate = true;
126   }
127   return toUpdate;
128 }
129
130 // =======================================================================
131 // function : update3dMouseKeys
132 // purpose  :
133 // =======================================================================
134 bool Aspect_WindowInputListener::update3dMouseKeys (const WNT_HIDSpaceMouse& theEvent)
135 {
136   bool toUpdate = false;
137   const double aTimeStamp = EventTime();
138   if (theEvent.IsKeyState())
139   {
140     const uint32_t aKeyState = theEvent.KeyState();
141     for (unsigned short aKeyBit = 0; aKeyBit < 32; ++aKeyBit)
142     {
143       const bool isPressed  = (aKeyState & (1 << aKeyBit)) != 0;
144       const bool isReleased = my3dMouseButtonState[aKeyBit] && !isPressed;
145       //const bool isRepeated = my3dMouseButtonState[aKeyBit] &&  isPressed;
146       my3dMouseButtonState[aKeyBit] = isPressed;
147       if (!isReleased && !isPressed)
148       {
149         continue;
150       }
151
152       const Aspect_VKey aVKey = theEvent.HidToSpaceKey (aKeyBit);
153       if (aVKey != Aspect_VKey_UNKNOWN)
154       {
155         toUpdate = true;
156         if (isPressed)
157         {
158           KeyDown (aVKey, aTimeStamp);
159         }
160         else
161         {
162           KeyUp (aVKey, aTimeStamp);
163         }
164       }
165     }
166   }
167   return toUpdate;
168 }