mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
0032306: Draw Harness, ViewerTest - move window message processing to TKService
Aspect_WindowInputListener - basic mouse/keyboard/expose input methods have been moved out from AIS_ViewController to dedicated base interface. Added WNT_Window::ProcessMessage()/Xw_Window::ProcessMessage() methods redirecting Win32/X11 message to Aspect_WindowInputListener.
This commit is contained in:
parent
1294d5e39e
commit
e8e157df45
@ -82,8 +82,6 @@ AIS_ViewController::AIS_ViewController()
|
|||||||
myMouseActiveGesture (AIS_MouseGesture_NONE),
|
myMouseActiveGesture (AIS_MouseGesture_NONE),
|
||||||
myMouseActiveIdleRotation (false),
|
myMouseActiveIdleRotation (false),
|
||||||
myMouseClickCounter (0),
|
myMouseClickCounter (0),
|
||||||
myMousePressed (Aspect_VKeyMouse_NONE),
|
|
||||||
myMouseModifiers (Aspect_VKeyFlags_NONE),
|
|
||||||
myMouseSingleButton (-1),
|
myMouseSingleButton (-1),
|
||||||
myMouseStopDragOnUnclick (false),
|
myMouseStopDragOnUnclick (false),
|
||||||
//
|
//
|
||||||
@ -99,16 +97,8 @@ AIS_ViewController::AIS_ViewController()
|
|||||||
myUpdateStartPointRot (true),
|
myUpdateStartPointRot (true),
|
||||||
myUpdateStartPointZRot (true),
|
myUpdateStartPointZRot (true),
|
||||||
//
|
//
|
||||||
my3dMouseNoRotate (false, false, false),
|
|
||||||
my3dMouseToReverse (true, false, false),
|
|
||||||
my3dMouseAccelTrans (2.0f),
|
|
||||||
my3dMouseAccelRotate (4.0f),
|
|
||||||
my3dMouseIsQuadric (true),
|
|
||||||
//
|
|
||||||
myPanPnt3d (Precision::Infinite(), 0.0, 0.0)
|
myPanPnt3d (Precision::Infinite(), 0.0, 0.0)
|
||||||
{
|
{
|
||||||
memset(my3dMouseButtonState, 0, sizeof(my3dMouseButtonState));
|
|
||||||
myEventTimer.Start();
|
|
||||||
myViewAnimation->SetOwnDuration (0.5);
|
myViewAnimation->SetOwnDuration (0.5);
|
||||||
|
|
||||||
myAnchorPointPrs1 = new AIS_Point (new Geom_CartesianPoint (0.0, 0.0, 0.0));
|
myAnchorPointPrs1 = new AIS_Point (new Geom_CartesianPoint (0.0, 0.0, 0.0));
|
||||||
@ -1119,104 +1109,11 @@ bool AIS_ViewController::Update3dMouse (const WNT_HIDSpaceMouse& theEvent)
|
|||||||
{
|
{
|
||||||
bool toUpdate = false;
|
bool toUpdate = false;
|
||||||
toUpdate = update3dMouseTranslation (theEvent) || toUpdate;
|
toUpdate = update3dMouseTranslation (theEvent) || toUpdate;
|
||||||
toUpdate = update3dMouseRotation (theEvent) || toUpdate;
|
toUpdate = (myToAllowRotation && update3dMouseRotation (theEvent)) || toUpdate;
|
||||||
toUpdate = update3dMouseKeys (theEvent) || toUpdate;
|
toUpdate = update3dMouseKeys (theEvent) || toUpdate;
|
||||||
return toUpdate;
|
return toUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : update3dMouseTranslation
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
bool AIS_ViewController::update3dMouseTranslation (const WNT_HIDSpaceMouse& theEvent)
|
|
||||||
{
|
|
||||||
if (!theEvent.IsTranslation())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isIdle = true;
|
|
||||||
const double aTimeStamp = EventTime();
|
|
||||||
const Graphic3d_Vec3d aTrans = theEvent.Translation (isIdle, my3dMouseIsQuadric) * my3dMouseAccelTrans;
|
|
||||||
myKeys.KeyFromAxis (Aspect_VKey_NavSlideLeft, Aspect_VKey_NavSlideRight, aTimeStamp, aTrans.x());
|
|
||||||
myKeys.KeyFromAxis (Aspect_VKey_NavForward, Aspect_VKey_NavBackward, aTimeStamp, aTrans.y());
|
|
||||||
myKeys.KeyFromAxis (Aspect_VKey_NavSlideUp, Aspect_VKey_NavSlideDown, aTimeStamp, aTrans.z());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : update3dMouseRotation
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
bool AIS_ViewController::update3dMouseRotation (const WNT_HIDSpaceMouse& theEvent)
|
|
||||||
{
|
|
||||||
if (!theEvent.IsRotation()
|
|
||||||
|| !myToAllowRotation)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isIdle = true, toUpdate = false;
|
|
||||||
const double aTimeStamp = EventTime();
|
|
||||||
const Graphic3d_Vec3d aRot3 = theEvent.Rotation (isIdle, my3dMouseIsQuadric) * my3dMouseAccelRotate;
|
|
||||||
if (!my3dMouseNoRotate.x())
|
|
||||||
{
|
|
||||||
KeyFromAxis (Aspect_VKey_NavLookUp, Aspect_VKey_NavLookDown, aTimeStamp, !my3dMouseToReverse.x() ? aRot3.x() : -aRot3.x());
|
|
||||||
toUpdate = true;
|
|
||||||
}
|
|
||||||
if (!my3dMouseNoRotate.y())
|
|
||||||
{
|
|
||||||
KeyFromAxis (Aspect_VKey_NavRollCW, Aspect_VKey_NavRollCCW, aTimeStamp, !my3dMouseToReverse.y() ? aRot3.y() : -aRot3.y());
|
|
||||||
toUpdate = true;
|
|
||||||
}
|
|
||||||
if (!my3dMouseNoRotate.z())
|
|
||||||
{
|
|
||||||
KeyFromAxis (Aspect_VKey_NavLookLeft, Aspect_VKey_NavLookRight, aTimeStamp, !my3dMouseToReverse.z() ? aRot3.z() : -aRot3.z());
|
|
||||||
toUpdate = true;
|
|
||||||
}
|
|
||||||
return toUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : update3dMouseKeys
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
bool AIS_ViewController::update3dMouseKeys (const WNT_HIDSpaceMouse& theEvent)
|
|
||||||
{
|
|
||||||
bool toUpdate = false;
|
|
||||||
const double aTimeStamp = EventTime();
|
|
||||||
if (theEvent.IsKeyState())
|
|
||||||
{
|
|
||||||
const uint32_t aKeyState = theEvent.KeyState();
|
|
||||||
for (unsigned short aKeyBit = 0; aKeyBit < 32; ++aKeyBit)
|
|
||||||
{
|
|
||||||
const bool isPressed = (aKeyState & (1 << aKeyBit)) != 0;
|
|
||||||
const bool isReleased = my3dMouseButtonState[aKeyBit] && !isPressed;
|
|
||||||
//const bool isRepeated = my3dMouseButtonState[aKeyBit] && isPressed;
|
|
||||||
my3dMouseButtonState[aKeyBit] = isPressed;
|
|
||||||
if (!isReleased && !isPressed)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Aspect_VKey aVKey = theEvent.HidToSpaceKey (aKeyBit);
|
|
||||||
if (aVKey != Aspect_VKey_UNKNOWN)
|
|
||||||
{
|
|
||||||
toUpdate = true;
|
|
||||||
if (isPressed)
|
|
||||||
{
|
|
||||||
KeyDown (aVKey, aTimeStamp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
KeyUp (aVKey, aTimeStamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return toUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : SetNavigationMode
|
// function : SetNavigationMode
|
||||||
// purpose :
|
// purpose :
|
||||||
@ -1240,7 +1137,7 @@ void AIS_ViewController::KeyDown (Aspect_VKey theKey,
|
|||||||
double theTime,
|
double theTime,
|
||||||
double thePressure)
|
double thePressure)
|
||||||
{
|
{
|
||||||
myKeys.KeyDown (theKey, theTime, thePressure);
|
Aspect_WindowInputListener::KeyDown (theKey, theTime, thePressure);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@ -1250,7 +1147,7 @@ void AIS_ViewController::KeyDown (Aspect_VKey theKey,
|
|||||||
void AIS_ViewController::KeyUp (Aspect_VKey theKey,
|
void AIS_ViewController::KeyUp (Aspect_VKey theKey,
|
||||||
double theTime)
|
double theTime)
|
||||||
{
|
{
|
||||||
myKeys.KeyUp (theKey, theTime);
|
Aspect_WindowInputListener::KeyUp (theKey, theTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@ -1262,7 +1159,7 @@ void AIS_ViewController::KeyFromAxis (Aspect_VKey theNegative,
|
|||||||
double theTime,
|
double theTime,
|
||||||
double thePressure)
|
double thePressure)
|
||||||
{
|
{
|
||||||
myKeys.KeyFromAxis (theNegative, thePositive, theTime, thePressure);
|
Aspect_WindowInputListener::KeyFromAxis (theNegative, thePositive, theTime, thePressure);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <Aspect_VKeySet.hxx>
|
#include <Aspect_VKeySet.hxx>
|
||||||
#include <Aspect_TouchMap.hxx>
|
#include <Aspect_TouchMap.hxx>
|
||||||
|
#include <Aspect_WindowInputListener.hxx>
|
||||||
#include <Aspect_XRHapticActionData.hxx>
|
#include <Aspect_XRHapticActionData.hxx>
|
||||||
#include <Aspect_XRTrackedDeviceRole.hxx>
|
#include <Aspect_XRTrackedDeviceRole.hxx>
|
||||||
#include <AIS_DragAction.hxx>
|
#include <AIS_DragAction.hxx>
|
||||||
@ -51,7 +52,7 @@ class WNT_HIDSpaceMouse;
|
|||||||
//! - Mapping mouse/multi-touch input to View camera manipulations (panning/rotating/zooming).
|
//! - Mapping mouse/multi-touch input to View camera manipulations (panning/rotating/zooming).
|
||||||
//! - Input events are not applied immediately but queued for separate processing from two working threads
|
//! - Input events are not applied immediately but queued for separate processing from two working threads
|
||||||
//! UI thread receiving user input and Rendering thread for OCCT 3D Viewer drawing.
|
//! UI thread receiving user input and Rendering thread for OCCT 3D Viewer drawing.
|
||||||
class AIS_ViewController
|
class AIS_ViewController : public Aspect_WindowInputListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -221,30 +222,30 @@ public: //! @name global parameters
|
|||||||
|
|
||||||
public: //! @name keyboard input
|
public: //! @name keyboard input
|
||||||
|
|
||||||
//! Return keyboard state.
|
using Aspect_WindowInputListener::Keys;
|
||||||
const Aspect_VKeySet& Keys() const { return myKeys; }
|
using Aspect_WindowInputListener::ChangeKeys;
|
||||||
|
|
||||||
//! Return keyboard state.
|
|
||||||
Aspect_VKeySet& ChangeKeys() { return myKeys; }
|
|
||||||
|
|
||||||
//! Press key.
|
//! Press key.
|
||||||
|
//! Default implementation updates internal cache.
|
||||||
//! @param theKey key pressed
|
//! @param theKey key pressed
|
||||||
//! @param theTime event timestamp
|
//! @param theTime event timestamp
|
||||||
Standard_EXPORT virtual void KeyDown (Aspect_VKey theKey,
|
Standard_EXPORT virtual void KeyDown (Aspect_VKey theKey,
|
||||||
double theTime,
|
double theTime,
|
||||||
double thePressure = 1.0);
|
double thePressure = 1.0) Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Release key.
|
//! Release key.
|
||||||
|
//! Default implementation updates internal cache.
|
||||||
//! @param theKey key pressed
|
//! @param theKey key pressed
|
||||||
//! @param theTime event timestamp
|
//! @param theTime event timestamp
|
||||||
Standard_EXPORT virtual void KeyUp (Aspect_VKey theKey,
|
Standard_EXPORT virtual void KeyUp (Aspect_VKey theKey,
|
||||||
double theTime);
|
double theTime) Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Simulate key up/down events from axis value.
|
//! Simulate key up/down events from axis value.
|
||||||
|
//! Default implementation updates internal cache.
|
||||||
Standard_EXPORT virtual void KeyFromAxis (Aspect_VKey theNegative,
|
Standard_EXPORT virtual void KeyFromAxis (Aspect_VKey theNegative,
|
||||||
Aspect_VKey thePositive,
|
Aspect_VKey thePositive,
|
||||||
double theTime,
|
double theTime,
|
||||||
double thePressure);
|
double thePressure) Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Fetch active navigation actions.
|
//! Fetch active navigation actions.
|
||||||
Standard_EXPORT AIS_WalkDelta FetchNavigationKeys (Standard_Real theCrouchRatio,
|
Standard_EXPORT AIS_WalkDelta FetchNavigationKeys (Standard_Real theCrouchRatio,
|
||||||
@ -313,7 +314,7 @@ public: //! @name mouse input
|
|||||||
//! This method is expected to be called from UI thread.
|
//! This method is expected to be called from UI thread.
|
||||||
//! @param theDelta mouse cursor position and delta
|
//! @param theDelta mouse cursor position and delta
|
||||||
//! @return TRUE if new event has been created or FALSE if existing one has been updated
|
//! @return TRUE if new event has been created or FALSE if existing one has been updated
|
||||||
Standard_EXPORT virtual bool UpdateMouseScroll (const Aspect_ScrollDelta& theDelta);
|
Standard_EXPORT virtual bool UpdateMouseScroll (const Aspect_ScrollDelta& theDelta) Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Handle mouse button press/release event.
|
//! Handle mouse button press/release event.
|
||||||
//! This method is expected to be called from UI thread.
|
//! This method is expected to be called from UI thread.
|
||||||
@ -326,7 +327,7 @@ public: //! @name mouse input
|
|||||||
Standard_EXPORT virtual bool UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
|
Standard_EXPORT virtual bool UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
|
||||||
Aspect_VKeyMouse theButtons,
|
Aspect_VKeyMouse theButtons,
|
||||||
Aspect_VKeyFlags theModifiers,
|
Aspect_VKeyFlags theModifiers,
|
||||||
bool theIsEmulated);
|
bool theIsEmulated) Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Handle mouse cursor movement event.
|
//! Handle mouse cursor movement event.
|
||||||
//! This method is expected to be called from UI thread.
|
//! This method is expected to be called from UI thread.
|
||||||
@ -339,40 +340,7 @@ public: //! @name mouse input
|
|||||||
Standard_EXPORT virtual bool UpdateMousePosition (const Graphic3d_Vec2i& thePoint,
|
Standard_EXPORT virtual bool UpdateMousePosition (const Graphic3d_Vec2i& thePoint,
|
||||||
Aspect_VKeyMouse theButtons,
|
Aspect_VKeyMouse theButtons,
|
||||||
Aspect_VKeyFlags theModifiers,
|
Aspect_VKeyFlags theModifiers,
|
||||||
bool theIsEmulated);
|
bool theIsEmulated) Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Handle mouse button press event.
|
|
||||||
//! This method is expected to be called from UI thread.
|
|
||||||
//! @param thePoint mouse cursor position
|
|
||||||
//! @param theButton pressed button
|
|
||||||
//! @param theModifiers key modifiers
|
|
||||||
//! @param theIsEmulated if TRUE then mouse event comes NOT from real mouse
|
|
||||||
//! but emulated from non-precise input like touch on screen
|
|
||||||
//! @return TRUE if View should be redrawn
|
|
||||||
bool PressMouseButton (const Graphic3d_Vec2i& thePoint,
|
|
||||||
Aspect_VKeyMouse theButton,
|
|
||||||
Aspect_VKeyFlags theModifiers,
|
|
||||||
bool theIsEmulated)
|
|
||||||
{
|
|
||||||
return UpdateMouseButtons (thePoint, myMousePressed | theButton, theModifiers, theIsEmulated);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Handle mouse button release event.
|
|
||||||
//! This method is expected to be called from UI thread.
|
|
||||||
//! @param thePoint mouse cursor position
|
|
||||||
//! @param theButton released button
|
|
||||||
//! @param theModifiers key modifiers
|
|
||||||
//! @param theIsEmulated if TRUE then mouse event comes NOT from real mouse
|
|
||||||
//! but emulated from non-precise input like touch on screen
|
|
||||||
//! @return TRUE if View should be redrawn
|
|
||||||
bool ReleaseMouseButton (const Graphic3d_Vec2i& thePoint,
|
|
||||||
Aspect_VKeyMouse theButton,
|
|
||||||
Aspect_VKeyFlags theModifiers,
|
|
||||||
bool theIsEmulated)
|
|
||||||
{
|
|
||||||
Aspect_VKeyMouse aButtons = myMousePressed & (~theButton);
|
|
||||||
return UpdateMouseButtons (thePoint, aButtons, theModifiers, theIsEmulated);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Handle mouse button click event (emulated by UpdateMouseButtons() while releasing single button).
|
//! Handle mouse button click event (emulated by UpdateMouseButtons() while releasing single button).
|
||||||
//! Note that as this method is called by UpdateMouseButtons(), it should be executed from UI thread.
|
//! Note that as this method is called by UpdateMouseButtons(), it should be executed from UI thread.
|
||||||
@ -388,14 +356,12 @@ public: //! @name mouse input
|
|||||||
Aspect_VKeyFlags theModifiers,
|
Aspect_VKeyFlags theModifiers,
|
||||||
bool theIsDoubleClick);
|
bool theIsDoubleClick);
|
||||||
|
|
||||||
//! Return currently pressed mouse buttons.
|
using Aspect_WindowInputListener::PressMouseButton;
|
||||||
Aspect_VKeyMouse PressedMouseButtons() const { return myMousePressed; }
|
using Aspect_WindowInputListener::ReleaseMouseButton;
|
||||||
|
|
||||||
//! Return active key modifiers passed with last mouse event.
|
using Aspect_WindowInputListener::PressedMouseButtons;
|
||||||
Aspect_VKeyFlags LastMouseFlags() const { return myMouseModifiers; }
|
using Aspect_WindowInputListener::LastMouseFlags;
|
||||||
|
using Aspect_WindowInputListener::LastMousePosition;
|
||||||
//! Return last mouse position.
|
|
||||||
const Graphic3d_Vec2i& LastMousePosition() const { return myMousePositionLast; }
|
|
||||||
|
|
||||||
public: //! @name multi-touch input
|
public: //! @name multi-touch input
|
||||||
|
|
||||||
@ -436,52 +402,40 @@ public: //! @name multi-touch input
|
|||||||
|
|
||||||
public: //! @name 3d mouse input
|
public: //! @name 3d mouse input
|
||||||
|
|
||||||
//! Return acceleration ratio for translation event; 2.0 by default.
|
|
||||||
float Get3dMouseTranslationScale() const { return my3dMouseAccelTrans; }
|
|
||||||
|
|
||||||
//! Set acceleration ratio for translation event.
|
|
||||||
void Set3dMouseTranslationScale (float theScale) { my3dMouseAccelTrans = theScale; }
|
|
||||||
|
|
||||||
//! Return acceleration ratio for rotation event; 4.0 by default.
|
|
||||||
float Get3dMouseRotationScale() const { return my3dMouseAccelRotate; }
|
|
||||||
|
|
||||||
//! Set acceleration ratio for rotation event.
|
|
||||||
void Set3dMouseRotationScale (float theScale) { my3dMouseAccelRotate = theScale; }
|
|
||||||
|
|
||||||
//! Return quadric acceleration flag; TRUE by default.
|
|
||||||
bool To3dMousePreciseInput() const { return my3dMouseIsQuadric; }
|
|
||||||
|
|
||||||
//! Set quadric acceleration flag.
|
|
||||||
void Set3dMousePreciseInput (bool theIsQuadric) { my3dMouseIsQuadric = theIsQuadric; }
|
|
||||||
|
|
||||||
//! Return 3d mouse rotation axes (tilt/roll/spin) ignore flag; (FALSE, FALSE, FALSE) by default.
|
|
||||||
const NCollection_Vec3<bool>& Get3dMouseIsNoRotate() const { return my3dMouseNoRotate; }
|
|
||||||
|
|
||||||
//! Return 3d mouse rotation axes (tilt/roll/spin) ignore flag; (FALSE, FALSE, FALSE) by default.
|
|
||||||
NCollection_Vec3<bool>& Change3dMouseIsNoRotate() { return my3dMouseNoRotate; }
|
|
||||||
|
|
||||||
//! Return 3d mouse rotation axes (tilt/roll/spin) reverse flag; (TRUE, FALSE, FALSE) by default.
|
|
||||||
const NCollection_Vec3<bool>& Get3dMouseToReverse() const { return my3dMouseToReverse; }
|
|
||||||
|
|
||||||
//! Return 3d mouse rotation axes (tilt/roll/spin) reverse flag; (TRUE, FALSE, FALSE) by default.
|
|
||||||
NCollection_Vec3<bool>& Change3dMouseToReverse() { return my3dMouseToReverse; }
|
|
||||||
|
|
||||||
//! Process 3d mouse input event (redirects to translation, rotation and keys).
|
//! Process 3d mouse input event (redirects to translation, rotation and keys).
|
||||||
Standard_EXPORT virtual bool Update3dMouse (const WNT_HIDSpaceMouse& theEvent);
|
Standard_EXPORT virtual bool Update3dMouse (const WNT_HIDSpaceMouse& theEvent) Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Process 3d mouse input translation event.
|
public: //! @name resize events
|
||||||
Standard_EXPORT virtual bool update3dMouseTranslation (const WNT_HIDSpaceMouse& theEvent);
|
|
||||||
|
|
||||||
//! Process 3d mouse input rotation event.
|
//! Handle expose event (window content has been invalidation and should be redrawn).
|
||||||
Standard_EXPORT virtual bool update3dMouseRotation (const WNT_HIDSpaceMouse& theEvent);
|
//! Default implementation does nothing.
|
||||||
|
virtual void ProcessExpose() Standard_OVERRIDE {}
|
||||||
|
|
||||||
//! Process 3d mouse input keys event.
|
//! Handle window resize event.
|
||||||
Standard_EXPORT virtual bool update3dMouseKeys (const WNT_HIDSpaceMouse& theEvent);
|
//! Default implementation does nothing.
|
||||||
|
virtual void ProcessConfigure (bool theIsResized) Standard_OVERRIDE
|
||||||
|
{
|
||||||
|
(void )theIsResized;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Handle window input event immediately.
|
||||||
|
//! Default implementation does nothing - input events are accumulated in internal buffer until explicit FlushViewEvents() call.
|
||||||
|
virtual void ProcessInput() Standard_OVERRIDE {}
|
||||||
|
|
||||||
|
//! Handle focus event.
|
||||||
|
//! Default implementation does nothing.
|
||||||
|
virtual void ProcessFocus (bool theIsActivated)
|
||||||
|
{
|
||||||
|
(void )theIsActivated;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Handle window close event.
|
||||||
|
//! Default implementation does nothing.
|
||||||
|
virtual void ProcessClose() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Return event time (e.g. current time).
|
using Aspect_WindowInputListener::EventTime;
|
||||||
double EventTime() const { return myEventTimer.ElapsedTime(); }
|
|
||||||
|
|
||||||
//! Reset input state (pressed keys, mouse buttons, etc.) e.g. on window focus loss.
|
//! Reset input state (pressed keys, mouse buttons, etc.) e.g. on window focus loss.
|
||||||
//! This method is expected to be called from UI thread.
|
//! This method is expected to be called from UI thread.
|
||||||
@ -712,7 +666,6 @@ protected:
|
|||||||
AIS_ViewInputBuffer myUI; //!< buffer for UI thread
|
AIS_ViewInputBuffer myUI; //!< buffer for UI thread
|
||||||
AIS_ViewInputBuffer myGL; //!< buffer for rendering thread
|
AIS_ViewInputBuffer myGL; //!< buffer for rendering thread
|
||||||
|
|
||||||
OSD_Timer myEventTimer; //!< timer for timestamping events
|
|
||||||
Standard_Real myLastEventsTime; //!< last fetched events timer value for computing delta/progress
|
Standard_Real myLastEventsTime; //!< last fetched events timer value for computing delta/progress
|
||||||
Standard_Boolean myToAskNextFrame; //!< flag indicating that another frame should be drawn right after this one
|
Standard_Boolean myToAskNextFrame; //!< flag indicating that another frame should be drawn right after this one
|
||||||
|
|
||||||
@ -764,10 +717,6 @@ protected: //! @name XR input variables
|
|||||||
Standard_Boolean myToDisplayXRAuxDevices; //!< flag to display auxiliary tracked XR devices
|
Standard_Boolean myToDisplayXRAuxDevices; //!< flag to display auxiliary tracked XR devices
|
||||||
Standard_Boolean myToDisplayXRHands; //!< flag to display XR hands
|
Standard_Boolean myToDisplayXRHands; //!< flag to display XR hands
|
||||||
|
|
||||||
protected: //! @name keyboard input variables
|
|
||||||
|
|
||||||
Aspect_VKeySet myKeys; //!< keyboard state
|
|
||||||
|
|
||||||
protected: //! @name mouse input variables
|
protected: //! @name mouse input variables
|
||||||
|
|
||||||
Standard_Real myMouseClickThreshold; //!< mouse click threshold in pixels; 3 by default
|
Standard_Real myMouseClickThreshold; //!< mouse click threshold in pixels; 3 by default
|
||||||
@ -779,13 +728,10 @@ protected: //! @name mouse input variables
|
|||||||
AIS_MouseSelectionSchemeMap
|
AIS_MouseSelectionSchemeMap
|
||||||
myMouseSelectionSchemes; //!< map defining selection schemes bound to mouse + modifiers
|
myMouseSelectionSchemes; //!< map defining selection schemes bound to mouse + modifiers
|
||||||
Standard_Boolean myMouseActiveIdleRotation; //!< flag indicating view idle rotation state
|
Standard_Boolean myMouseActiveIdleRotation; //!< flag indicating view idle rotation state
|
||||||
Graphic3d_Vec2i myMousePositionLast; //!< last mouse position
|
|
||||||
Graphic3d_Vec2i myMousePressPoint; //!< mouse position where active gesture was been initiated
|
Graphic3d_Vec2i myMousePressPoint; //!< mouse position where active gesture was been initiated
|
||||||
Graphic3d_Vec2i myMouseProgressPoint; //!< gesture progress
|
Graphic3d_Vec2i myMouseProgressPoint; //!< gesture progress
|
||||||
OSD_Timer myMouseClickTimer; //!< timer for handling double-click event
|
OSD_Timer myMouseClickTimer; //!< timer for handling double-click event
|
||||||
Standard_Integer myMouseClickCounter; //!< counter for handling double-click event
|
Standard_Integer myMouseClickCounter; //!< counter for handling double-click event
|
||||||
Aspect_VKeyMouse myMousePressed; //!< active mouse buttons
|
|
||||||
Aspect_VKeyFlags myMouseModifiers; //!< active key modifiers passed with last mouse event
|
|
||||||
Standard_Integer myMouseSingleButton; //!< index of mouse button pressed alone (>0)
|
Standard_Integer myMouseSingleButton; //!< index of mouse button pressed alone (>0)
|
||||||
Standard_Boolean myMouseStopDragOnUnclick; //!< queue stop dragging even with at next mouse unclick
|
Standard_Boolean myMouseStopDragOnUnclick; //!< queue stop dragging even with at next mouse unclick
|
||||||
|
|
||||||
@ -806,15 +752,6 @@ protected: //! @name multi-touch input variables
|
|||||||
Standard_Boolean myUpdateStartPointRot; //!< flag indicating that new gravity point should be picked for starting rotation gesture
|
Standard_Boolean myUpdateStartPointRot; //!< flag indicating that new gravity point should be picked for starting rotation gesture
|
||||||
Standard_Boolean myUpdateStartPointZRot; //!< flag indicating that new gravity point should be picked for starting Z-rotation gesture
|
Standard_Boolean myUpdateStartPointZRot; //!< flag indicating that new gravity point should be picked for starting Z-rotation gesture
|
||||||
|
|
||||||
protected: //! @name 3d mouse input variables
|
|
||||||
|
|
||||||
bool my3dMouseButtonState[32];//!< cached button state
|
|
||||||
NCollection_Vec3<bool> my3dMouseNoRotate; //!< ignore 3d mouse rotation axes
|
|
||||||
NCollection_Vec3<bool> my3dMouseToReverse; //!< reverse 3d mouse rotation axes
|
|
||||||
float my3dMouseAccelTrans; //!< acceleration ratio for translation event
|
|
||||||
float my3dMouseAccelRotate; //!< acceleration ratio for rotation event
|
|
||||||
bool my3dMouseIsQuadric; //!< quadric acceleration
|
|
||||||
|
|
||||||
protected: //! @name rotation/panning transient state variables
|
protected: //! @name rotation/panning transient state variables
|
||||||
|
|
||||||
Handle(AIS_Point) myAnchorPointPrs1; //!< anchor point presentation (Graphic3d_ZLayerId_Top)
|
Handle(AIS_Point) myAnchorPointPrs1; //!< anchor point presentation (Graphic3d_ZLayerId_Top)
|
||||||
|
168
src/Aspect/Aspect_WindowInputListener.cxx
Normal file
168
src/Aspect/Aspect_WindowInputListener.cxx
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
// Copyright (c) 2021 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#include <Aspect_WindowInputListener.hxx>
|
||||||
|
|
||||||
|
#include <WNT_HIDSpaceMouse.hxx>
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : Aspect_WindowInputListener
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Aspect_WindowInputListener::Aspect_WindowInputListener()
|
||||||
|
: myMousePressed (Aspect_VKeyMouse_NONE),
|
||||||
|
myMouseModifiers (Aspect_VKeyFlags_NONE),
|
||||||
|
//
|
||||||
|
my3dMouseNoRotate (false, false, false),
|
||||||
|
my3dMouseToReverse (true, false, false),
|
||||||
|
my3dMouseAccelTrans (2.0f),
|
||||||
|
my3dMouseAccelRotate (4.0f),
|
||||||
|
my3dMouseIsQuadric (true)
|
||||||
|
{
|
||||||
|
memset(my3dMouseButtonState, 0, sizeof(my3dMouseButtonState));
|
||||||
|
myEventTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : ~Aspect_WindowInputListener
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Aspect_WindowInputListener::~Aspect_WindowInputListener()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : KeyDown
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Aspect_WindowInputListener::KeyDown (Aspect_VKey theKey,
|
||||||
|
double theTime,
|
||||||
|
double thePressure)
|
||||||
|
{
|
||||||
|
myKeys.KeyDown (theKey, theTime, thePressure);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : KeyUp
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Aspect_WindowInputListener::KeyUp (Aspect_VKey theKey,
|
||||||
|
double theTime)
|
||||||
|
{
|
||||||
|
myKeys.KeyUp (theKey, theTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : KeyFromAxis
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Aspect_WindowInputListener::KeyFromAxis (Aspect_VKey theNegative,
|
||||||
|
Aspect_VKey thePositive,
|
||||||
|
double theTime,
|
||||||
|
double thePressure)
|
||||||
|
{
|
||||||
|
myKeys.KeyFromAxis (theNegative, thePositive, theTime, thePressure);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : update3dMouseTranslation
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Aspect_WindowInputListener::update3dMouseTranslation (const WNT_HIDSpaceMouse& theEvent)
|
||||||
|
{
|
||||||
|
if (!theEvent.IsTranslation())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isIdle = true;
|
||||||
|
const double aTimeStamp = EventTime();
|
||||||
|
const Graphic3d_Vec3d aTrans = theEvent.Translation (isIdle, my3dMouseIsQuadric) * my3dMouseAccelTrans;
|
||||||
|
myKeys.KeyFromAxis (Aspect_VKey_NavSlideLeft, Aspect_VKey_NavSlideRight, aTimeStamp, aTrans.x());
|
||||||
|
myKeys.KeyFromAxis (Aspect_VKey_NavForward, Aspect_VKey_NavBackward, aTimeStamp, aTrans.y());
|
||||||
|
myKeys.KeyFromAxis (Aspect_VKey_NavSlideUp, Aspect_VKey_NavSlideDown, aTimeStamp, aTrans.z());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : update3dMouseRotation
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Aspect_WindowInputListener::update3dMouseRotation (const WNT_HIDSpaceMouse& theEvent)
|
||||||
|
{
|
||||||
|
if (!theEvent.IsRotation())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isIdle = true, toUpdate = false;
|
||||||
|
const double aTimeStamp = EventTime();
|
||||||
|
const Graphic3d_Vec3d aRot3 = theEvent.Rotation (isIdle, my3dMouseIsQuadric) * my3dMouseAccelRotate;
|
||||||
|
if (!my3dMouseNoRotate.x())
|
||||||
|
{
|
||||||
|
KeyFromAxis (Aspect_VKey_NavLookUp, Aspect_VKey_NavLookDown, aTimeStamp, !my3dMouseToReverse.x() ? aRot3.x() : -aRot3.x());
|
||||||
|
toUpdate = true;
|
||||||
|
}
|
||||||
|
if (!my3dMouseNoRotate.y())
|
||||||
|
{
|
||||||
|
KeyFromAxis (Aspect_VKey_NavRollCW, Aspect_VKey_NavRollCCW, aTimeStamp, !my3dMouseToReverse.y() ? aRot3.y() : -aRot3.y());
|
||||||
|
toUpdate = true;
|
||||||
|
}
|
||||||
|
if (!my3dMouseNoRotate.z())
|
||||||
|
{
|
||||||
|
KeyFromAxis (Aspect_VKey_NavLookLeft, Aspect_VKey_NavLookRight, aTimeStamp, !my3dMouseToReverse.z() ? aRot3.z() : -aRot3.z());
|
||||||
|
toUpdate = true;
|
||||||
|
}
|
||||||
|
return toUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : update3dMouseKeys
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Aspect_WindowInputListener::update3dMouseKeys (const WNT_HIDSpaceMouse& theEvent)
|
||||||
|
{
|
||||||
|
bool toUpdate = false;
|
||||||
|
const double aTimeStamp = EventTime();
|
||||||
|
if (theEvent.IsKeyState())
|
||||||
|
{
|
||||||
|
const uint32_t aKeyState = theEvent.KeyState();
|
||||||
|
for (unsigned short aKeyBit = 0; aKeyBit < 32; ++aKeyBit)
|
||||||
|
{
|
||||||
|
const bool isPressed = (aKeyState & (1 << aKeyBit)) != 0;
|
||||||
|
const bool isReleased = my3dMouseButtonState[aKeyBit] && !isPressed;
|
||||||
|
//const bool isRepeated = my3dMouseButtonState[aKeyBit] && isPressed;
|
||||||
|
my3dMouseButtonState[aKeyBit] = isPressed;
|
||||||
|
if (!isReleased && !isPressed)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Aspect_VKey aVKey = theEvent.HidToSpaceKey (aKeyBit);
|
||||||
|
if (aVKey != Aspect_VKey_UNKNOWN)
|
||||||
|
{
|
||||||
|
toUpdate = true;
|
||||||
|
if (isPressed)
|
||||||
|
{
|
||||||
|
KeyDown (aVKey, aTimeStamp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KeyUp (aVKey, aTimeStamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return toUpdate;
|
||||||
|
}
|
236
src/Aspect/Aspect_WindowInputListener.hxx
Normal file
236
src/Aspect/Aspect_WindowInputListener.hxx
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
// Copyright (c) 2021 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#ifndef _Aspect_WindowInputListener_HeaderFile
|
||||||
|
#define _Aspect_WindowInputListener_HeaderFile
|
||||||
|
|
||||||
|
#include <Aspect_VKeySet.hxx>
|
||||||
|
#include <Graphic3d_Vec.hxx>
|
||||||
|
#include <Standard.hxx>
|
||||||
|
#include <Standard_DefineAlloc.hxx>
|
||||||
|
|
||||||
|
struct Aspect_ScrollDelta;
|
||||||
|
class WNT_HIDSpaceMouse;
|
||||||
|
|
||||||
|
//! Defines a listener for window input events.
|
||||||
|
class Aspect_WindowInputListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
///DEFINE_STANDARD_ALLOC
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Destructor.
|
||||||
|
Standard_EXPORT virtual ~Aspect_WindowInputListener();
|
||||||
|
|
||||||
|
//! Return event time (e.g. current time).
|
||||||
|
double EventTime() const { return myEventTimer.ElapsedTime(); }
|
||||||
|
|
||||||
|
//! Handle expose event (window content has been invalidation and should be redrawn).
|
||||||
|
virtual void ProcessExpose() = 0;
|
||||||
|
|
||||||
|
//! Handle window resize event.
|
||||||
|
virtual void ProcessConfigure (bool theIsResized) = 0;
|
||||||
|
|
||||||
|
//! Handle window input event immediately (flush input buffer or ignore).
|
||||||
|
virtual void ProcessInput() = 0;
|
||||||
|
|
||||||
|
//! Handle focus event.
|
||||||
|
virtual void ProcessFocus (bool theIsActivated) = 0;
|
||||||
|
|
||||||
|
//! Handle window close event.
|
||||||
|
virtual void ProcessClose() = 0;
|
||||||
|
|
||||||
|
public: //! @name keyboard input
|
||||||
|
|
||||||
|
//! Return keyboard state.
|
||||||
|
const Aspect_VKeySet& Keys() const { return myKeys; }
|
||||||
|
|
||||||
|
//! Return keyboard state.
|
||||||
|
Aspect_VKeySet& ChangeKeys() { return myKeys; }
|
||||||
|
|
||||||
|
//! Press key.
|
||||||
|
//! Default implementation updates internal cache.
|
||||||
|
//! @param theKey key pressed
|
||||||
|
//! @param theTime event timestamp
|
||||||
|
Standard_EXPORT virtual void KeyDown (Aspect_VKey theKey,
|
||||||
|
double theTime,
|
||||||
|
double thePressure = 1.0) = 0;
|
||||||
|
|
||||||
|
//! Release key.
|
||||||
|
//! Default implementation updates internal cache.
|
||||||
|
//! @param theKey key pressed
|
||||||
|
//! @param theTime event timestamp
|
||||||
|
Standard_EXPORT virtual void KeyUp (Aspect_VKey theKey,
|
||||||
|
double theTime) = 0;
|
||||||
|
|
||||||
|
//! Simulate key up/down events from axis value.
|
||||||
|
//! Default implementation updates internal cache.
|
||||||
|
Standard_EXPORT virtual void KeyFromAxis (Aspect_VKey theNegative,
|
||||||
|
Aspect_VKey thePositive,
|
||||||
|
double theTime,
|
||||||
|
double thePressure) = 0;
|
||||||
|
|
||||||
|
public: //! @name mouse input
|
||||||
|
|
||||||
|
//! Update mouse scroll event.
|
||||||
|
//! This method is expected to be called from UI thread.
|
||||||
|
//! @param theDelta mouse cursor position and delta
|
||||||
|
//! @return TRUE if new event has been created or FALSE if existing one has been updated
|
||||||
|
virtual bool UpdateMouseScroll (const Aspect_ScrollDelta& theDelta) = 0;
|
||||||
|
|
||||||
|
//! Handle mouse button press/release event.
|
||||||
|
//! This method is expected to be called from UI thread.
|
||||||
|
//! @param thePoint mouse cursor position
|
||||||
|
//! @param theButtons pressed buttons
|
||||||
|
//! @param theModifiers key modifiers
|
||||||
|
//! @param theIsEmulated if TRUE then mouse event comes NOT from real mouse
|
||||||
|
//! but emulated from non-precise input like touch on screen
|
||||||
|
//! @return TRUE if window content should be redrawn
|
||||||
|
virtual bool UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
|
||||||
|
Aspect_VKeyMouse theButtons,
|
||||||
|
Aspect_VKeyFlags theModifiers,
|
||||||
|
bool theIsEmulated) = 0;
|
||||||
|
|
||||||
|
//! Handle mouse cursor movement event.
|
||||||
|
//! This method is expected to be called from UI thread.
|
||||||
|
//! Default implementation does nothing.
|
||||||
|
//! @param thePoint mouse cursor position
|
||||||
|
//! @param theButtons pressed buttons
|
||||||
|
//! @param theModifiers key modifiers
|
||||||
|
//! @param theIsEmulated if TRUE then mouse event comes NOT from real mouse
|
||||||
|
//! but emulated from non-precise input like touch on screen
|
||||||
|
//! @return TRUE if window content should be redrawn
|
||||||
|
virtual bool UpdateMousePosition (const Graphic3d_Vec2i& thePoint,
|
||||||
|
Aspect_VKeyMouse theButtons,
|
||||||
|
Aspect_VKeyFlags theModifiers,
|
||||||
|
bool theIsEmulated) = 0;
|
||||||
|
|
||||||
|
//! Handle mouse button press event.
|
||||||
|
//! This method is expected to be called from UI thread.
|
||||||
|
//! Default implementation redirects to UpdateMousePosition().
|
||||||
|
//! @param thePoint mouse cursor position
|
||||||
|
//! @param theButton pressed button
|
||||||
|
//! @param theModifiers key modifiers
|
||||||
|
//! @param theIsEmulated if TRUE then mouse event comes NOT from real mouse
|
||||||
|
//! but emulated from non-precise input like touch on screen
|
||||||
|
//! @return TRUE if window content should be redrawn
|
||||||
|
bool PressMouseButton (const Graphic3d_Vec2i& thePoint,
|
||||||
|
Aspect_VKeyMouse theButton,
|
||||||
|
Aspect_VKeyFlags theModifiers,
|
||||||
|
bool theIsEmulated)
|
||||||
|
{
|
||||||
|
return UpdateMouseButtons (thePoint, myMousePressed | theButton, theModifiers, theIsEmulated);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Handle mouse button release event.
|
||||||
|
//! This method is expected to be called from UI thread.
|
||||||
|
//! Default implementation redirects to UpdateMousePosition().
|
||||||
|
//! @param thePoint mouse cursor position
|
||||||
|
//! @param theButton released button
|
||||||
|
//! @param theModifiers key modifiers
|
||||||
|
//! @param theIsEmulated if TRUE then mouse event comes NOT from real mouse
|
||||||
|
//! but emulated from non-precise input like touch on screen
|
||||||
|
//! @return TRUE if window content should be redrawn
|
||||||
|
bool ReleaseMouseButton (const Graphic3d_Vec2i& thePoint,
|
||||||
|
Aspect_VKeyMouse theButton,
|
||||||
|
Aspect_VKeyFlags theModifiers,
|
||||||
|
bool theIsEmulated)
|
||||||
|
{
|
||||||
|
Aspect_VKeyMouse aButtons = myMousePressed & (~theButton);
|
||||||
|
return UpdateMouseButtons (thePoint, aButtons, theModifiers, theIsEmulated);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Return currently pressed mouse buttons.
|
||||||
|
Aspect_VKeyMouse PressedMouseButtons() const { return myMousePressed; }
|
||||||
|
|
||||||
|
//! Return active key modifiers passed with last mouse event.
|
||||||
|
Aspect_VKeyFlags LastMouseFlags() const { return myMouseModifiers; }
|
||||||
|
|
||||||
|
//! Return last mouse position.
|
||||||
|
const Graphic3d_Vec2i& LastMousePosition() const { return myMousePositionLast; }
|
||||||
|
|
||||||
|
public: //! @name 3d mouse input
|
||||||
|
|
||||||
|
//! Return acceleration ratio for translation event; 2.0 by default.
|
||||||
|
float Get3dMouseTranslationScale() const { return my3dMouseAccelTrans; }
|
||||||
|
|
||||||
|
//! Set acceleration ratio for translation event.
|
||||||
|
void Set3dMouseTranslationScale (float theScale) { my3dMouseAccelTrans = theScale; }
|
||||||
|
|
||||||
|
//! Return acceleration ratio for rotation event; 4.0 by default.
|
||||||
|
float Get3dMouseRotationScale() const { return my3dMouseAccelRotate; }
|
||||||
|
|
||||||
|
//! Set acceleration ratio for rotation event.
|
||||||
|
void Set3dMouseRotationScale (float theScale) { my3dMouseAccelRotate = theScale; }
|
||||||
|
|
||||||
|
//! Return quadric acceleration flag; TRUE by default.
|
||||||
|
bool To3dMousePreciseInput() const { return my3dMouseIsQuadric; }
|
||||||
|
|
||||||
|
//! Set quadric acceleration flag.
|
||||||
|
void Set3dMousePreciseInput (bool theIsQuadric) { my3dMouseIsQuadric = theIsQuadric; }
|
||||||
|
|
||||||
|
//! Return 3d mouse rotation axes (tilt/roll/spin) ignore flag; (FALSE, FALSE, FALSE) by default.
|
||||||
|
const NCollection_Vec3<bool>& Get3dMouseIsNoRotate() const { return my3dMouseNoRotate; }
|
||||||
|
|
||||||
|
//! Return 3d mouse rotation axes (tilt/roll/spin) ignore flag; (FALSE, FALSE, FALSE) by default.
|
||||||
|
NCollection_Vec3<bool>& Change3dMouseIsNoRotate() { return my3dMouseNoRotate; }
|
||||||
|
|
||||||
|
//! Return 3d mouse rotation axes (tilt/roll/spin) reverse flag; (TRUE, FALSE, FALSE) by default.
|
||||||
|
const NCollection_Vec3<bool>& Get3dMouseToReverse() const { return my3dMouseToReverse; }
|
||||||
|
|
||||||
|
//! Return 3d mouse rotation axes (tilt/roll/spin) reverse flag; (TRUE, FALSE, FALSE) by default.
|
||||||
|
NCollection_Vec3<bool>& Change3dMouseToReverse() { return my3dMouseToReverse; }
|
||||||
|
|
||||||
|
//! Process 3d mouse input event (redirects to translation, rotation and keys).
|
||||||
|
virtual bool Update3dMouse (const WNT_HIDSpaceMouse& theEvent) = 0;
|
||||||
|
|
||||||
|
//! Process 3d mouse input translation event.
|
||||||
|
Standard_EXPORT virtual bool update3dMouseTranslation (const WNT_HIDSpaceMouse& theEvent);
|
||||||
|
|
||||||
|
//! Process 3d mouse input rotation event.
|
||||||
|
Standard_EXPORT virtual bool update3dMouseRotation (const WNT_HIDSpaceMouse& theEvent);
|
||||||
|
|
||||||
|
//! Process 3d mouse input keys event.
|
||||||
|
Standard_EXPORT virtual bool update3dMouseKeys (const WNT_HIDSpaceMouse& theEvent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Empty constructor.
|
||||||
|
Standard_EXPORT Aspect_WindowInputListener();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
OSD_Timer myEventTimer; //!< timer for timestamping events
|
||||||
|
|
||||||
|
protected: //! @name keyboard input variables
|
||||||
|
|
||||||
|
Aspect_VKeySet myKeys; //!< keyboard state
|
||||||
|
|
||||||
|
protected: //! @name mouse input variables
|
||||||
|
|
||||||
|
Graphic3d_Vec2i myMousePositionLast; //!< last mouse position
|
||||||
|
Aspect_VKeyMouse myMousePressed; //!< active mouse buttons
|
||||||
|
Aspect_VKeyFlags myMouseModifiers; //!< active key modifiers passed with last mouse event
|
||||||
|
|
||||||
|
protected: //! @name 3d mouse input variables
|
||||||
|
|
||||||
|
bool my3dMouseButtonState[32];//!< cached button state
|
||||||
|
NCollection_Vec3<bool> my3dMouseNoRotate; //!< ignore 3d mouse rotation axes
|
||||||
|
NCollection_Vec3<bool> my3dMouseToReverse; //!< reverse 3d mouse rotation axes
|
||||||
|
float my3dMouseAccelTrans; //!< acceleration ratio for translation event
|
||||||
|
float my3dMouseAccelRotate; //!< acceleration ratio for rotation event
|
||||||
|
bool my3dMouseIsQuadric; //!< quadric acceleration
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _Aspect_WindowInputListener_HeaderFile
|
@ -66,6 +66,8 @@ Aspect_Window.cxx
|
|||||||
Aspect_Window.hxx
|
Aspect_Window.hxx
|
||||||
Aspect_WindowDefinitionError.hxx
|
Aspect_WindowDefinitionError.hxx
|
||||||
Aspect_WindowError.hxx
|
Aspect_WindowError.hxx
|
||||||
|
Aspect_WindowInputListener.cxx
|
||||||
|
Aspect_WindowInputListener.hxx
|
||||||
Aspect_XAtom.hxx
|
Aspect_XAtom.hxx
|
||||||
Aspect_XRAction.hxx
|
Aspect_XRAction.hxx
|
||||||
Aspect_XRActionSet.hxx
|
Aspect_XRActionSet.hxx
|
||||||
|
@ -167,15 +167,36 @@ void ViewerTest_EventManager::handleViewRedraw (const Handle(AIS_InteractiveCont
|
|||||||
//function : ProcessConfigure
|
//function : ProcessConfigure
|
||||||
//purpose :
|
//purpose :
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
void ViewerTest_EventManager::ProcessConfigure()
|
void ViewerTest_EventManager::ProcessConfigure (bool theIsResized)
|
||||||
{
|
{
|
||||||
if (!myView.IsNull())
|
if (!myView.IsNull())
|
||||||
{
|
{
|
||||||
|
if (!theIsResized
|
||||||
|
// track window moves to reverse stereo pair
|
||||||
|
&& myView->RenderingParams().StereoMode != Graphic3d_StereoMode_RowInterlaced
|
||||||
|
&& myView->RenderingParams().StereoMode != Graphic3d_StereoMode_ColumnInterlaced
|
||||||
|
&& myView->RenderingParams().StereoMode != Graphic3d_StereoMode_ChessBoard)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
myView->MustBeResized();
|
myView->MustBeResized();
|
||||||
FlushViewEvents (myCtx, myView, true);
|
FlushViewEvents (myCtx, myView, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
//function : ProcessInput
|
||||||
|
//purpose :
|
||||||
|
//==============================================================================
|
||||||
|
void ViewerTest_EventManager::ProcessInput()
|
||||||
|
{
|
||||||
|
if (!myView.IsNull())
|
||||||
|
{
|
||||||
|
FlushViewEvents (myCtx, myView, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : navigationKeyModifierSwitch
|
// function : navigationKeyModifierSwitch
|
||||||
// purpose :
|
// purpose :
|
||||||
|
@ -91,14 +91,17 @@ public:
|
|||||||
double theTime) Standard_OVERRIDE;
|
double theTime) Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Redraw the View on an Expose Event
|
//! Redraw the View on an Expose Event
|
||||||
Standard_EXPORT virtual void ProcessExpose();
|
Standard_EXPORT virtual void ProcessExpose() Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Handle redraw.
|
//! Handle redraw.
|
||||||
Standard_EXPORT virtual void handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
|
Standard_EXPORT virtual void handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
|
||||||
const Handle(V3d_View)& theView) Standard_OVERRIDE;
|
const Handle(V3d_View)& theView) Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Resize View.
|
//! Resize View.
|
||||||
Standard_EXPORT virtual void ProcessConfigure();
|
Standard_EXPORT virtual void ProcessConfigure (bool theIsResized = true) Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Handle window input event immediately (flush input buffer).
|
||||||
|
Standard_EXPORT virtual void ProcessInput() Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Handle KeyPress event.
|
//! Handle KeyPress event.
|
||||||
Standard_EXPORT void ProcessKeyPress (Aspect_VKey theKey);
|
Standard_EXPORT void ProcessKeyPress (Aspect_VKey theKey);
|
||||||
|
@ -1390,19 +1390,9 @@ namespace
|
|||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static LRESULT WINAPI ViewerWindowProc(
|
static LRESULT WINAPI AdvViewerWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
HWND hwnd,
|
|
||||||
UINT uMsg,
|
|
||||||
WPARAM wParam,
|
|
||||||
LPARAM lParam );
|
|
||||||
static LRESULT WINAPI AdvViewerWindowProc(
|
|
||||||
HWND hwnd,
|
|
||||||
UINT uMsg,
|
|
||||||
WPARAM wParam,
|
|
||||||
LPARAM lParam );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
//function : WClass
|
//function : WClass
|
||||||
//purpose :
|
//purpose :
|
||||||
@ -3247,7 +3237,7 @@ static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
|
|||||||
{
|
{
|
||||||
if (ViewerTest_myViews.IsEmpty())
|
if (ViewerTest_myViews.IsEmpty())
|
||||||
{
|
{
|
||||||
return ViewerWindowProc (theWinHandle, theMsg, wParam, lParam);
|
return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (theMsg)
|
switch (theMsg)
|
||||||
@ -3271,215 +3261,32 @@ static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
|
|||||||
ActivateView (FindViewIdByWindowHandle (theWinHandle));
|
ActivateView (FindViewIdByWindowHandle (theWinHandle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
{
|
|
||||||
return ViewerWindowProc (theWinHandle, theMsg, wParam, lParam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static LRESULT WINAPI ViewerWindowProc (HWND theWinHandle,
|
|
||||||
UINT theMsg,
|
|
||||||
WPARAM wParam,
|
|
||||||
LPARAM lParam)
|
|
||||||
{
|
|
||||||
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
|
|
||||||
if (aView.IsNull())
|
|
||||||
{
|
|
||||||
return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (theMsg)
|
|
||||||
{
|
|
||||||
case WM_PAINT:
|
|
||||||
{
|
|
||||||
PAINTSTRUCT aPaint;
|
|
||||||
BeginPaint(theWinHandle, &aPaint);
|
|
||||||
EndPaint (theWinHandle, &aPaint);
|
|
||||||
ViewerTest::CurrentEventManager()->ProcessExpose();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WM_SIZE:
|
|
||||||
{
|
|
||||||
ViewerTest::CurrentEventManager()->ProcessConfigure();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WM_MOVE:
|
|
||||||
case WM_MOVING:
|
|
||||||
case WM_SIZING:
|
|
||||||
{
|
|
||||||
switch (aView->RenderingParams().StereoMode)
|
|
||||||
{
|
|
||||||
case Graphic3d_StereoMode_RowInterlaced:
|
|
||||||
case Graphic3d_StereoMode_ColumnInterlaced:
|
|
||||||
case Graphic3d_StereoMode_ChessBoard:
|
|
||||||
{
|
|
||||||
// track window moves to reverse stereo pair
|
|
||||||
aView->MustBeResized();
|
|
||||||
aView->Update();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WM_KEYUP:
|
|
||||||
case WM_KEYDOWN:
|
|
||||||
{
|
|
||||||
const Aspect_VKey aVKey = WNT_Window::VirtualKeyFromNative ((Standard_Integer )wParam);
|
|
||||||
if (aVKey != Aspect_VKey_UNKNOWN)
|
|
||||||
{
|
|
||||||
const double aTimeStamp = ViewerTest::CurrentEventManager()->EventTime();
|
|
||||||
if (theMsg == WM_KEYDOWN)
|
|
||||||
{
|
|
||||||
ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
|
|
||||||
}
|
|
||||||
ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WM_LBUTTONUP:
|
|
||||||
case WM_MBUTTONUP:
|
|
||||||
case WM_RBUTTONUP:
|
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
case WM_MBUTTONDOWN:
|
|
||||||
case WM_RBUTTONDOWN:
|
|
||||||
{
|
{
|
||||||
const Graphic3d_Vec2i aPos (LOWORD(lParam), HIWORD(lParam));
|
TheIsAnimating = Standard_False;
|
||||||
const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (wParam);
|
|
||||||
Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
|
|
||||||
switch (theMsg)
|
|
||||||
{
|
|
||||||
case WM_LBUTTONUP:
|
|
||||||
case WM_LBUTTONDOWN:
|
|
||||||
aButton = Aspect_VKeyMouse_LeftButton;
|
|
||||||
break;
|
|
||||||
case WM_MBUTTONUP:
|
|
||||||
case WM_MBUTTONDOWN:
|
|
||||||
aButton = Aspect_VKeyMouse_MiddleButton;
|
|
||||||
break;
|
|
||||||
case WM_RBUTTONUP:
|
|
||||||
case WM_RBUTTONDOWN:
|
|
||||||
aButton = Aspect_VKeyMouse_RightButton;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (theMsg == WM_LBUTTONDOWN
|
|
||||||
|| theMsg == WM_MBUTTONDOWN
|
|
||||||
|| theMsg == WM_RBUTTONDOWN)
|
|
||||||
{
|
|
||||||
if (aButton == Aspect_VKeyMouse_LeftButton)
|
|
||||||
{
|
|
||||||
TheIsAnimating = Standard_False;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetFocus (theWinHandle);
|
|
||||||
SetCapture(theWinHandle);
|
|
||||||
ViewerTest::CurrentEventManager()->PressMouseButton (aPos, aButton, aFlags, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ReleaseCapture();
|
|
||||||
ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, aButton, aFlags, false);
|
|
||||||
}
|
|
||||||
ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WM_MOUSEWHEEL:
|
|
||||||
{
|
|
||||||
const int aDelta = GET_WHEEL_DELTA_WPARAM (wParam);
|
|
||||||
const Standard_Real aDeltaF = Standard_Real(aDelta) / Standard_Real(WHEEL_DELTA);
|
|
||||||
const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (wParam);
|
|
||||||
Graphic3d_Vec2i aPos (int(short(LOWORD(lParam))), int(short(HIWORD(lParam))));
|
|
||||||
POINT aCursorPnt = { aPos.x(), aPos.y() };
|
|
||||||
if (ScreenToClient (theWinHandle, &aCursorPnt))
|
|
||||||
{
|
|
||||||
aPos.SetValues (aCursorPnt.x, aCursorPnt.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
ViewerTest::CurrentEventManager()->UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
|
|
||||||
ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WM_MOUSEMOVE:
|
|
||||||
{
|
|
||||||
Graphic3d_Vec2i aPos (LOWORD(lParam), HIWORD(lParam));
|
|
||||||
Aspect_VKeyMouse aButtons = WNT_Window::MouseButtonsFromEvent (wParam);
|
|
||||||
Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent(wParam);
|
|
||||||
|
|
||||||
// don't make a slide-show from input events - fetch the actual mouse cursor position
|
|
||||||
CURSORINFO aCursor;
|
|
||||||
aCursor.cbSize = sizeof(aCursor);
|
|
||||||
if (::GetCursorInfo (&aCursor) != FALSE)
|
|
||||||
{
|
|
||||||
POINT aCursorPnt = { aCursor.ptScreenPos.x, aCursor.ptScreenPos.y };
|
|
||||||
if (ScreenToClient (theWinHandle, &aCursorPnt))
|
|
||||||
{
|
|
||||||
// as we override mouse position, we need overriding also mouse state
|
|
||||||
aPos.SetValues (aCursorPnt.x, aCursorPnt.y);
|
|
||||||
aButtons = WNT_Window::MouseButtonsAsync();
|
|
||||||
aFlags = WNT_Window::MouseKeyFlagsAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VT_GetWindow().IsNull()
|
|
||||||
|| (HWND )VT_GetWindow()->HWindow() != theWinHandle)
|
|
||||||
{
|
|
||||||
// mouse move events come also for inactive windows
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
|
|
||||||
ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WM_INPUT:
|
|
||||||
{
|
|
||||||
UINT aSize = 0;
|
|
||||||
::GetRawInputData ((HRAWINPUT )lParam, RID_INPUT, NULL, &aSize, sizeof(RAWINPUTHEADER));
|
|
||||||
NCollection_LocalArray<BYTE> aRawData (aSize);
|
|
||||||
if (aSize == 0 || ::GetRawInputData ((HRAWINPUT )lParam, RID_INPUT, aRawData, &aSize, sizeof(RAWINPUTHEADER)) != aSize)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const RAWINPUT* aRawInput = (RAWINPUT* )(BYTE* )aRawData;
|
|
||||||
if (aRawInput->header.dwType != RIM_TYPEHID)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
RID_DEVICE_INFO aDevInfo;
|
|
||||||
aDevInfo.cbSize = sizeof(RID_DEVICE_INFO);
|
|
||||||
UINT aDevInfoSize = sizeof(RID_DEVICE_INFO);
|
|
||||||
if (::GetRawInputDeviceInfoW (aRawInput->header.hDevice, RIDI_DEVICEINFO, &aDevInfo, &aDevInfoSize) != sizeof(RID_DEVICE_INFO)
|
|
||||||
|| (aDevInfo.hid.dwVendorId != WNT_HIDSpaceMouse::VENDOR_ID_LOGITECH
|
|
||||||
&& aDevInfo.hid.dwVendorId != WNT_HIDSpaceMouse::VENDOR_ID_3DCONNEXION))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
WNT_HIDSpaceMouse aSpaceData (aDevInfo.hid.dwProductId, aRawInput->data.hid.bRawData, aRawInput->data.hid.dwSizeHid);
|
|
||||||
if (ViewerTest::CurrentEventManager()->Update3dMouse (aSpaceData)
|
|
||||||
&& !VT_GetWindow().IsNull())
|
|
||||||
{
|
|
||||||
VT_GetWindow()->InvalidateContent();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
Standard_FALLTHROUGH
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
|
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
|
||||||
|
if (!aView.IsNull()
|
||||||
|
&& !VT_GetWindow().IsNull())
|
||||||
|
{
|
||||||
|
MSG aMsg = {};
|
||||||
|
aMsg.hwnd = theWinHandle;
|
||||||
|
aMsg.message = theMsg;
|
||||||
|
aMsg.wParam = wParam;
|
||||||
|
aMsg.lParam = lParam;
|
||||||
|
if (VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aMsg))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0L;
|
return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
@ -3518,22 +3325,6 @@ int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
|
|||||||
|
|
||||||
#elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
|
#elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
|
||||||
|
|
||||||
int min( int a, int b )
|
|
||||||
{
|
|
||||||
if( a<b )
|
|
||||||
return a;
|
|
||||||
else
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int max( int a, int b )
|
|
||||||
{
|
|
||||||
if( a>b )
|
|
||||||
return a;
|
|
||||||
else
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
|
int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
|
||||||
{
|
{
|
||||||
static XEvent aReport;
|
static XEvent aReport;
|
||||||
@ -3573,170 +3364,22 @@ int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Expose:
|
|
||||||
{
|
|
||||||
Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
|
|
||||||
if (anXWindow == aReport.xexpose.window)
|
|
||||||
{
|
|
||||||
ViewerTest::CurrentEventManager()->ProcessExpose();
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove all the ExposureMask and process them at once
|
|
||||||
for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
|
|
||||||
{
|
|
||||||
if (!XCheckWindowEvent (aDisplay, anXWindow, ExposureMask, &aReport))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ConfigureNotify:
|
|
||||||
{
|
|
||||||
// remove all the StructureNotifyMask and process them at once
|
|
||||||
Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
|
|
||||||
for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
|
|
||||||
{
|
|
||||||
if (!XCheckWindowEvent (aDisplay, anXWindow, StructureNotifyMask, &aReport))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (anXWindow == aReport.xconfigure.window)
|
|
||||||
{
|
|
||||||
ViewerTest::CurrentEventManager()->ProcessConfigure();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case KeyPress:
|
|
||||||
case KeyRelease:
|
|
||||||
{
|
|
||||||
XKeyEvent* aKeyEvent = (XKeyEvent* )&aReport;
|
|
||||||
const KeySym aKeySym = XLookupKeysym (aKeyEvent, 0);
|
|
||||||
const Aspect_VKey aVKey = Xw_Window::VirtualKeyFromNative (aKeySym);
|
|
||||||
if (aVKey != Aspect_VKey_UNKNOWN)
|
|
||||||
{
|
|
||||||
const double aTimeStamp = ViewerTest::CurrentEventManager()->EventTime();
|
|
||||||
if (aReport.type == KeyPress)
|
|
||||||
{
|
|
||||||
ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
|
|
||||||
}
|
|
||||||
ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
case ButtonRelease:
|
|
||||||
{
|
{
|
||||||
const Graphic3d_Vec2i aPos (aReport.xbutton.x, aReport.xbutton.y);
|
|
||||||
Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
|
|
||||||
Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
|
|
||||||
if (aReport.xbutton.button == Button1)
|
if (aReport.xbutton.button == Button1)
|
||||||
{
|
{
|
||||||
aButton = Aspect_VKeyMouse_LeftButton;
|
TheIsAnimating = Standard_False;
|
||||||
}
|
}
|
||||||
if (aReport.xbutton.button == Button2)
|
|
||||||
{
|
|
||||||
aButton = Aspect_VKeyMouse_MiddleButton;
|
|
||||||
}
|
|
||||||
if (aReport.xbutton.button == Button3)
|
|
||||||
{
|
|
||||||
aButton = Aspect_VKeyMouse_RightButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aReport.xbutton.state & ControlMask)
|
|
||||||
{
|
|
||||||
aFlags |= Aspect_VKeyFlags_CTRL;
|
|
||||||
}
|
|
||||||
if (aReport.xbutton.state & ShiftMask)
|
|
||||||
{
|
|
||||||
aFlags |= Aspect_VKeyFlags_SHIFT;
|
|
||||||
}
|
|
||||||
if (ViewerTest::CurrentEventManager()->Keys().IsKeyDown (Aspect_VKey_Alt))
|
|
||||||
{
|
|
||||||
aFlags |= Aspect_VKeyFlags_ALT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aReport.xbutton.button == Button4
|
|
||||||
|| aReport.xbutton.button == Button5)
|
|
||||||
{
|
|
||||||
if (aReport.type != ButtonPress)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const double aDeltaF = (aReport.xbutton.button == Button4 ? 1.0 : -1.0);
|
|
||||||
ViewerTest::CurrentEventManager()->UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
|
|
||||||
}
|
|
||||||
else if (aReport.type == ButtonPress)
|
|
||||||
{
|
|
||||||
if (aButton == Aspect_VKeyMouse_LeftButton)
|
|
||||||
{
|
|
||||||
TheIsAnimating = Standard_False;
|
|
||||||
}
|
|
||||||
ViewerTest::CurrentEventManager()->PressMouseButton (aPos, aButton, aFlags, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, aButton, aFlags, false);
|
|
||||||
}
|
|
||||||
ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case MotionNotify:
|
Standard_FALLTHROUGH
|
||||||
|
default:
|
||||||
{
|
{
|
||||||
Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
|
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
|
||||||
if (anXWindow != aReport.xmotion.window)
|
if (!aView.IsNull()
|
||||||
|
&& !VT_GetWindow().IsNull())
|
||||||
{
|
{
|
||||||
break;
|
VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aReport);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove all the ButtonMotionMask and process them at once
|
|
||||||
for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
|
|
||||||
{
|
|
||||||
if (!XCheckWindowEvent (aDisplay, anXWindow, ButtonMotionMask | PointerMotionMask, &aReport))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Graphic3d_Vec2i aPos (aReport.xmotion.x, aReport.xmotion.y);
|
|
||||||
Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE;
|
|
||||||
Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
|
|
||||||
if ((aReport.xmotion.state & Button1Mask) != 0)
|
|
||||||
{
|
|
||||||
aButtons |= Aspect_VKeyMouse_LeftButton;
|
|
||||||
}
|
|
||||||
else if ((aReport.xmotion.state & Button2Mask) != 0)
|
|
||||||
{
|
|
||||||
aButtons |= Aspect_VKeyMouse_MiddleButton;
|
|
||||||
}
|
|
||||||
else if ((aReport.xmotion.state & Button3Mask) != 0)
|
|
||||||
{
|
|
||||||
aButtons |= Aspect_VKeyMouse_RightButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aReport.xmotion.state & ControlMask)
|
|
||||||
{
|
|
||||||
aFlags |= Aspect_VKeyFlags_CTRL;
|
|
||||||
}
|
|
||||||
if (aReport.xmotion.state & ShiftMask)
|
|
||||||
{
|
|
||||||
aFlags |= Aspect_VKeyFlags_SHIFT;
|
|
||||||
}
|
|
||||||
if (ViewerTest::CurrentEventManager()->Keys().IsKeyDown (Aspect_VKey_Alt))
|
|
||||||
{
|
|
||||||
aFlags |= Aspect_VKeyFlags_ALT;
|
|
||||||
}
|
|
||||||
|
|
||||||
ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
|
|
||||||
ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,4 @@ WNT_WClass.cxx
|
|||||||
WNT_WClass.hxx
|
WNT_WClass.hxx
|
||||||
WNT_Window.cxx
|
WNT_Window.cxx
|
||||||
WNT_Window.hxx
|
WNT_Window.hxx
|
||||||
WNT_Window.lxx
|
|
||||||
WNT_WindowPtr.hxx
|
WNT_WindowPtr.hxx
|
||||||
|
@ -22,12 +22,15 @@
|
|||||||
#if defined(_WIN32) && !defined(OCCT_UWP)
|
#if defined(_WIN32) && !defined(OCCT_UWP)
|
||||||
|
|
||||||
#include <Aspect_Convert.hxx>
|
#include <Aspect_Convert.hxx>
|
||||||
|
#include <Aspect_ScrollDelta.hxx>
|
||||||
#include <Aspect_WindowDefinitionError.hxx>
|
#include <Aspect_WindowDefinitionError.hxx>
|
||||||
#include <Aspect_WindowError.hxx>
|
#include <Aspect_WindowError.hxx>
|
||||||
|
#include <Aspect_WindowInputListener.hxx>
|
||||||
#include <Message.hxx>
|
#include <Message.hxx>
|
||||||
#include <Standard_Type.hxx>
|
#include <NCollection_LocalArray.hxx>
|
||||||
#include <TCollection_ExtendedString.hxx>
|
#include <TCollection_ExtendedString.hxx>
|
||||||
#include <WNT_WClass.hxx>
|
#include <WNT_WClass.hxx>
|
||||||
|
#include <WNT_HIDSpaceMouse.hxx>
|
||||||
|
|
||||||
IMPLEMENT_STANDARD_RTTIEXT(WNT_Window, Aspect_Window)
|
IMPLEMENT_STANDARD_RTTIEXT(WNT_Window, Aspect_Window)
|
||||||
|
|
||||||
@ -47,11 +50,13 @@ WNT_Window::WNT_Window (const Standard_CString theTitle,
|
|||||||
const Aspect_Handle theMenu,
|
const Aspect_Handle theMenu,
|
||||||
const Standard_Address theClientStruct)
|
const Standard_Address theClientStruct)
|
||||||
: Aspect_Window(),
|
: Aspect_Window(),
|
||||||
aXLeft (thePxLeft),
|
|
||||||
aYTop (thePxTop),
|
|
||||||
aXRight (thePxLeft + thePxWidth),
|
|
||||||
aYBottom (thePxTop + thePxHeight),
|
|
||||||
myWClass (theClass),
|
myWClass (theClass),
|
||||||
|
myHWindow (NULL),
|
||||||
|
myHParentWindow (NULL),
|
||||||
|
myXLeft (thePxLeft),
|
||||||
|
myYTop (thePxTop),
|
||||||
|
myXRight (thePxLeft + thePxWidth),
|
||||||
|
myYBottom (thePxTop + thePxHeight),
|
||||||
myIsForeign (Standard_False)
|
myIsForeign (Standard_False)
|
||||||
{
|
{
|
||||||
if (thePxWidth <= 0 || thePxHeight <= 0)
|
if (thePxWidth <= 0 || thePxHeight <= 0)
|
||||||
@ -71,22 +76,22 @@ WNT_Window::WNT_Window (const Standard_CString theTitle,
|
|||||||
|
|
||||||
// include decorations in the window dimensions to reproduce same behavior of Xw_Window
|
// include decorations in the window dimensions to reproduce same behavior of Xw_Window
|
||||||
RECT aRect;
|
RECT aRect;
|
||||||
aRect.top = aYTop;
|
aRect.top = myYTop;
|
||||||
aRect.bottom = aYBottom;
|
aRect.bottom = myYBottom;
|
||||||
aRect.left = aXLeft;
|
aRect.left = myXLeft;
|
||||||
aRect.right = aXRight;
|
aRect.right = myXRight;
|
||||||
AdjustWindowRect (&aRect, aStyle, theMenu != NULL ? TRUE : FALSE);
|
AdjustWindowRect (&aRect, aStyle, theMenu != NULL ? TRUE : FALSE);
|
||||||
aXLeft = aRect.left;
|
myXLeft = aRect.left;
|
||||||
aYTop = aRect.top;
|
myYTop = aRect.top;
|
||||||
aXRight = aRect.right;
|
myXRight = aRect.right;
|
||||||
aYBottom = aRect.bottom;
|
myYBottom = aRect.bottom;
|
||||||
|
|
||||||
const TCollection_ExtendedString aTitleW (theTitle);
|
const TCollection_ExtendedString aTitleW (theTitle);
|
||||||
const TCollection_ExtendedString aClassNameW (myWClass->Name());
|
const TCollection_ExtendedString aClassNameW (myWClass->Name());
|
||||||
myHWindow = CreateWindowW (aClassNameW.ToWideString(), aTitleW.ToWideString(),
|
myHWindow = CreateWindowW (aClassNameW.ToWideString(), aTitleW.ToWideString(),
|
||||||
aStyle,
|
aStyle,
|
||||||
aXLeft, aYTop,
|
myXLeft, myYTop,
|
||||||
(aXRight - aXLeft), (aYBottom - aYTop),
|
(myXRight - myXLeft), (myYBottom - myYTop),
|
||||||
(HWND )theParent,
|
(HWND )theParent,
|
||||||
(HMENU )theMenu,
|
(HMENU )theMenu,
|
||||||
(HINSTANCE )myWClass->Instance(),
|
(HINSTANCE )myWClass->Instance(),
|
||||||
@ -106,21 +111,24 @@ WNT_Window::WNT_Window (const Standard_CString theTitle,
|
|||||||
// =======================================================================
|
// =======================================================================
|
||||||
WNT_Window::WNT_Window (const Aspect_Handle theHandle,
|
WNT_Window::WNT_Window (const Aspect_Handle theHandle,
|
||||||
const Quantity_NameOfColor theBackColor)
|
const Quantity_NameOfColor theBackColor)
|
||||||
: myIsForeign (Standard_True)
|
: myHWindow (theHandle),
|
||||||
|
myHParentWindow (GetParent ((HWND )theHandle)),
|
||||||
|
myXLeft (0),
|
||||||
|
myYTop (0),
|
||||||
|
myXRight (0),
|
||||||
|
myYBottom (0),
|
||||||
|
myIsForeign (Standard_True)
|
||||||
{
|
{
|
||||||
myHWindow = theHandle;
|
|
||||||
myHParentWindow = GetParent ((HWND )theHandle);
|
|
||||||
|
|
||||||
SetBackground (theBackColor);
|
SetBackground (theBackColor);
|
||||||
|
|
||||||
WINDOWPLACEMENT aPlace;
|
WINDOWPLACEMENT aPlace = {};
|
||||||
aPlace.length = sizeof (WINDOWPLACEMENT);
|
aPlace.length = sizeof(WINDOWPLACEMENT);
|
||||||
::GetWindowPlacement ((HWND )myHWindow, &aPlace);
|
::GetWindowPlacement ((HWND )myHWindow, &aPlace);
|
||||||
|
|
||||||
aXLeft = aPlace.rcNormalPosition.left;
|
myXLeft = aPlace.rcNormalPosition.left;
|
||||||
aYTop = aPlace.rcNormalPosition.top;
|
myYTop = aPlace.rcNormalPosition.top;
|
||||||
aXRight = aPlace.rcNormalPosition.right;
|
myXRight = aPlace.rcNormalPosition.right;
|
||||||
aYBottom = aPlace.rcNormalPosition.bottom;
|
myYBottom = aPlace.rcNormalPosition.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@ -159,8 +167,8 @@ Standard_Boolean WNT_Window::IsMapped() const
|
|||||||
return Standard_True;
|
return Standard_True;
|
||||||
}
|
}
|
||||||
|
|
||||||
WINDOWPLACEMENT aPlace;
|
WINDOWPLACEMENT aPlace = {};
|
||||||
aPlace.length = sizeof (WINDOWPLACEMENT);
|
aPlace.length = sizeof(WINDOWPLACEMENT);
|
||||||
::GetWindowPlacement ((HWND )myHWindow, &aPlace);
|
::GetWindowPlacement ((HWND )myHWindow, &aPlace);
|
||||||
return !(aPlace.showCmd == SW_HIDE
|
return !(aPlace.showCmd == SW_HIDE
|
||||||
|| aPlace.showCmd == SW_MINIMIZE);
|
|| aPlace.showCmd == SW_MINIMIZE);
|
||||||
@ -213,60 +221,37 @@ Aspect_TypeOfResize WNT_Window::DoResize()
|
|||||||
return Aspect_TOR_UNKNOWN;
|
return Aspect_TOR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mask = 0;
|
WINDOWPLACEMENT aPlace = {};
|
||||||
Aspect_TypeOfResize mode = Aspect_TOR_UNKNOWN;
|
aPlace.length = sizeof(WINDOWPLACEMENT);
|
||||||
WINDOWPLACEMENT wp;
|
GetWindowPlacement ((HWND )myHWindow, &aPlace);
|
||||||
|
if (aPlace.showCmd == SW_SHOWMINIMIZED)
|
||||||
wp.length = sizeof ( WINDOWPLACEMENT );
|
|
||||||
GetWindowPlacement ( ( HWND )myHWindow, &wp );
|
|
||||||
|
|
||||||
if (wp.showCmd != SW_SHOWMINIMIZED)
|
|
||||||
{
|
{
|
||||||
if (Abs ((int )wp.rcNormalPosition.left - aXLeft ) > 2) mask |= 1;
|
return Aspect_TOR_UNKNOWN;
|
||||||
if (Abs ((int )wp.rcNormalPosition.right - aXRight ) > 2) mask |= 2;
|
|
||||||
if (Abs ((int )wp.rcNormalPosition.top - aYTop ) > 2) mask |= 4;
|
|
||||||
if (Abs ((int )wp.rcNormalPosition.bottom - aYBottom) > 2) mask |= 8;
|
|
||||||
|
|
||||||
switch (mask)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
mode = Aspect_TOR_NO_BORDER;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
mode = Aspect_TOR_LEFT_BORDER;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
mode = Aspect_TOR_RIGHT_BORDER;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
mode = Aspect_TOR_TOP_BORDER;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
mode = Aspect_TOR_LEFT_AND_TOP_BORDER;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
mode = Aspect_TOR_TOP_AND_RIGHT_BORDER;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
mode = Aspect_TOR_BOTTOM_BORDER;
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
mode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER;
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
mode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
} // end switch
|
|
||||||
|
|
||||||
aXLeft = wp.rcNormalPosition.left;
|
|
||||||
aXRight = wp.rcNormalPosition.right;
|
|
||||||
aYTop = wp.rcNormalPosition.top;
|
|
||||||
aYBottom = wp.rcNormalPosition.bottom;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mode;
|
int aMask = 0;
|
||||||
|
if (Abs ((int )aPlace.rcNormalPosition.left - myXLeft ) > 2) { aMask |= 1; }
|
||||||
|
if (Abs ((int )aPlace.rcNormalPosition.right - myXRight ) > 2) { aMask |= 2; }
|
||||||
|
if (Abs ((int )aPlace.rcNormalPosition.top - myYTop ) > 2) { aMask |= 4; }
|
||||||
|
if (Abs ((int )aPlace.rcNormalPosition.bottom - myYBottom) > 2) { aMask |= 8; }
|
||||||
|
|
||||||
|
myXLeft = aPlace.rcNormalPosition.left;
|
||||||
|
myXRight = aPlace.rcNormalPosition.right;
|
||||||
|
myYTop = aPlace.rcNormalPosition.top;
|
||||||
|
myYBottom = aPlace.rcNormalPosition.bottom;
|
||||||
|
switch (aMask)
|
||||||
|
{
|
||||||
|
case 0: return Aspect_TOR_NO_BORDER;
|
||||||
|
case 1: return Aspect_TOR_LEFT_BORDER;
|
||||||
|
case 2: return Aspect_TOR_RIGHT_BORDER;
|
||||||
|
case 4: return Aspect_TOR_TOP_BORDER;
|
||||||
|
case 5: return Aspect_TOR_LEFT_AND_TOP_BORDER;
|
||||||
|
case 6: return Aspect_TOR_TOP_AND_RIGHT_BORDER;
|
||||||
|
case 8: return Aspect_TOR_BOTTOM_BORDER;
|
||||||
|
case 9: return Aspect_TOR_BOTTOM_AND_LEFT_BORDER;
|
||||||
|
case 10: return Aspect_TOR_RIGHT_AND_BOTTOM_BORDER;
|
||||||
|
}
|
||||||
|
return Aspect_TOR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@ -277,10 +262,10 @@ Standard_Real WNT_Window::Ratio() const
|
|||||||
{
|
{
|
||||||
if (IsVirtual())
|
if (IsVirtual())
|
||||||
{
|
{
|
||||||
return Standard_Real(aXRight - aXLeft)/ Standard_Real(aYBottom - aYTop);
|
return Standard_Real(myXRight - myXLeft)/ Standard_Real(myYBottom - myYTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT aRect;
|
RECT aRect = {};
|
||||||
GetClientRect ((HWND )myHWindow, &aRect);
|
GetClientRect ((HWND )myHWindow, &aRect);
|
||||||
return Standard_Real(aRect.right - aRect.left) / Standard_Real(aRect.bottom - aRect.top);
|
return Standard_Real(aRect.right - aRect.left) / Standard_Real(aRect.bottom - aRect.top);
|
||||||
}
|
}
|
||||||
@ -294,14 +279,14 @@ void WNT_Window::Position (Standard_Integer& theX1, Standard_Integer& theY1,
|
|||||||
{
|
{
|
||||||
if (IsVirtual())
|
if (IsVirtual())
|
||||||
{
|
{
|
||||||
theX1 = aXLeft;
|
theX1 = myXLeft;
|
||||||
theX2 = aXRight;
|
theX2 = myXRight;
|
||||||
theY1 = aYTop;
|
theY1 = myYTop;
|
||||||
theY2 = aYBottom;
|
theY2 = myYBottom;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT aRect;
|
RECT aRect = {};
|
||||||
::GetClientRect ((HWND )myHWindow, &aRect);
|
::GetClientRect ((HWND )myHWindow, &aRect);
|
||||||
|
|
||||||
POINT aPntLeft, aPntRight;
|
POINT aPntLeft, aPntRight;
|
||||||
@ -332,12 +317,12 @@ void WNT_Window::Size (Standard_Integer& theWidth,
|
|||||||
{
|
{
|
||||||
if (IsVirtual())
|
if (IsVirtual())
|
||||||
{
|
{
|
||||||
theWidth = aXRight - aXLeft;
|
theWidth = myXRight - myXLeft;
|
||||||
theHeight = aYBottom - aYTop;
|
theHeight = myYBottom - myYTop;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT aRect;
|
RECT aRect = {};
|
||||||
::GetClientRect ((HWND )myHWindow, &aRect);
|
::GetClientRect ((HWND )myHWindow, &aRect);
|
||||||
theWidth = aRect.right;
|
theWidth = aRect.right;
|
||||||
theHeight = aRect.bottom;
|
theHeight = aRect.bottom;
|
||||||
@ -350,10 +335,10 @@ void WNT_Window::Size (Standard_Integer& theWidth,
|
|||||||
void WNT_Window::SetPos (const Standard_Integer theX, const Standard_Integer theY,
|
void WNT_Window::SetPos (const Standard_Integer theX, const Standard_Integer theY,
|
||||||
const Standard_Integer theX1, const Standard_Integer theY1)
|
const Standard_Integer theX1, const Standard_Integer theY1)
|
||||||
{
|
{
|
||||||
aXLeft = theX;
|
myXLeft = theX;
|
||||||
aYTop = theY;
|
myYTop = theY;
|
||||||
aXRight = theX1;
|
myXRight = theX1;
|
||||||
aYBottom = theY1;
|
myYBottom = theY1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@ -699,4 +684,197 @@ int WNT_Window::RegisterRawInputDevices (unsigned int theRawDeviceMask)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : ProcessMessage
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool WNT_Window::ProcessMessage (Aspect_WindowInputListener& theListener,
|
||||||
|
MSG& theMsg)
|
||||||
|
{
|
||||||
|
switch (theMsg.message)
|
||||||
|
{
|
||||||
|
case WM_CLOSE:
|
||||||
|
{
|
||||||
|
if (theMsg.hwnd == (HWND )myHWindow)
|
||||||
|
{
|
||||||
|
theListener.ProcessClose();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case WM_ACTIVATE:
|
||||||
|
{
|
||||||
|
if (theMsg.hwnd == (HWND )myHWindow)
|
||||||
|
{
|
||||||
|
theListener.ProcessFocus (LOWORD(theMsg.wParam) == WA_CLICKACTIVE
|
||||||
|
|| LOWORD(theMsg.wParam) == WA_ACTIVE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case WM_PAINT:
|
||||||
|
{
|
||||||
|
PAINTSTRUCT aPaint;
|
||||||
|
BeginPaint(theMsg.hwnd, &aPaint);
|
||||||
|
EndPaint (theMsg.hwnd, &aPaint);
|
||||||
|
theListener.ProcessExpose();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case WM_SIZE:
|
||||||
|
case WM_MOVE:
|
||||||
|
case WM_MOVING:
|
||||||
|
case WM_SIZING:
|
||||||
|
{
|
||||||
|
theListener.ProcessConfigure (theMsg.message == WM_SIZE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case WM_KEYUP:
|
||||||
|
case WM_KEYDOWN:
|
||||||
|
{
|
||||||
|
const Aspect_VKey aVKey = WNT_Window::VirtualKeyFromNative ((Standard_Integer )theMsg.wParam);
|
||||||
|
if (aVKey != Aspect_VKey_UNKNOWN)
|
||||||
|
{
|
||||||
|
const double aTimeStamp = theListener.EventTime();
|
||||||
|
if (theMsg.message == WM_KEYDOWN)
|
||||||
|
{
|
||||||
|
theListener.KeyDown (aVKey, aTimeStamp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
theListener.KeyUp (aVKey, aTimeStamp);
|
||||||
|
}
|
||||||
|
theListener.ProcessInput();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case WM_LBUTTONUP:
|
||||||
|
case WM_MBUTTONUP:
|
||||||
|
case WM_RBUTTONUP:
|
||||||
|
case WM_LBUTTONDOWN:
|
||||||
|
case WM_MBUTTONDOWN:
|
||||||
|
case WM_RBUTTONDOWN:
|
||||||
|
{
|
||||||
|
const Graphic3d_Vec2i aPos (LOWORD(theMsg.lParam), HIWORD(theMsg.lParam));
|
||||||
|
const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theMsg.wParam);
|
||||||
|
Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
|
||||||
|
switch (theMsg.message)
|
||||||
|
{
|
||||||
|
case WM_LBUTTONUP:
|
||||||
|
case WM_LBUTTONDOWN:
|
||||||
|
aButton = Aspect_VKeyMouse_LeftButton;
|
||||||
|
break;
|
||||||
|
case WM_MBUTTONUP:
|
||||||
|
case WM_MBUTTONDOWN:
|
||||||
|
aButton = Aspect_VKeyMouse_MiddleButton;
|
||||||
|
break;
|
||||||
|
case WM_RBUTTONUP:
|
||||||
|
case WM_RBUTTONDOWN:
|
||||||
|
aButton = Aspect_VKeyMouse_RightButton;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (theMsg.message == WM_LBUTTONDOWN
|
||||||
|
|| theMsg.message == WM_MBUTTONDOWN
|
||||||
|
|| theMsg.message == WM_RBUTTONDOWN)
|
||||||
|
{
|
||||||
|
SetFocus (theMsg.hwnd);
|
||||||
|
SetCapture(theMsg.hwnd);
|
||||||
|
theListener.PressMouseButton (aPos, aButton, aFlags, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReleaseCapture();
|
||||||
|
theListener.ReleaseMouseButton (aPos, aButton, aFlags, false);
|
||||||
|
}
|
||||||
|
theListener.ProcessInput();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case WM_MOUSEWHEEL:
|
||||||
|
{
|
||||||
|
const int aDelta = GET_WHEEL_DELTA_WPARAM (theMsg.wParam);
|
||||||
|
const Standard_Real aDeltaF = Standard_Real(aDelta) / Standard_Real(WHEEL_DELTA);
|
||||||
|
const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (theMsg.wParam);
|
||||||
|
Graphic3d_Vec2i aPos (int(short(LOWORD(theMsg.lParam))), int(short(HIWORD(theMsg.lParam))));
|
||||||
|
POINT aCursorPnt = { aPos.x(), aPos.y() };
|
||||||
|
if (ScreenToClient (theMsg.hwnd, &aCursorPnt))
|
||||||
|
{
|
||||||
|
aPos.SetValues (aCursorPnt.x, aCursorPnt.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theMsg.hwnd != (HWND )myHWindow)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
theListener.UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
|
||||||
|
theListener.ProcessInput();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case WM_MOUSEMOVE:
|
||||||
|
{
|
||||||
|
Graphic3d_Vec2i aPos (LOWORD(theMsg.lParam), HIWORD(theMsg.lParam));
|
||||||
|
Aspect_VKeyMouse aButtons = WNT_Window::MouseButtonsFromEvent (theMsg.wParam);
|
||||||
|
Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent(theMsg.wParam);
|
||||||
|
|
||||||
|
// don't make a slide-show from input events - fetch the actual mouse cursor position
|
||||||
|
CURSORINFO aCursor;
|
||||||
|
aCursor.cbSize = sizeof(aCursor);
|
||||||
|
if (::GetCursorInfo (&aCursor) != FALSE)
|
||||||
|
{
|
||||||
|
POINT aCursorPnt = { aCursor.ptScreenPos.x, aCursor.ptScreenPos.y };
|
||||||
|
if (ScreenToClient (theMsg.hwnd, &aCursorPnt))
|
||||||
|
{
|
||||||
|
// as we override mouse position, we need overriding also mouse state
|
||||||
|
aPos.SetValues (aCursorPnt.x, aCursorPnt.y);
|
||||||
|
aButtons = WNT_Window::MouseButtonsAsync();
|
||||||
|
aFlags = WNT_Window::MouseKeyFlagsAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theMsg.hwnd != (HWND )myHWindow)
|
||||||
|
{
|
||||||
|
// mouse move events come also for inactive windows
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
theListener.UpdateMousePosition (aPos, aButtons, aFlags, false);
|
||||||
|
theListener.ProcessInput();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case WM_INPUT:
|
||||||
|
{
|
||||||
|
UINT aSize = 0;
|
||||||
|
::GetRawInputData ((HRAWINPUT )theMsg.lParam, RID_INPUT, NULL, &aSize, sizeof(RAWINPUTHEADER));
|
||||||
|
NCollection_LocalArray<BYTE> aRawData (aSize);
|
||||||
|
if (aSize == 0 || ::GetRawInputData ((HRAWINPUT )theMsg.lParam, RID_INPUT, aRawData, &aSize, sizeof(RAWINPUTHEADER)) != aSize)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RAWINPUT* aRawInput = (RAWINPUT* )(BYTE* )aRawData;
|
||||||
|
if (aRawInput->header.dwType != RIM_TYPEHID)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RID_DEVICE_INFO aDevInfo;
|
||||||
|
aDevInfo.cbSize = sizeof(RID_DEVICE_INFO);
|
||||||
|
UINT aDevInfoSize = sizeof(RID_DEVICE_INFO);
|
||||||
|
if (::GetRawInputDeviceInfoW (aRawInput->header.hDevice, RIDI_DEVICEINFO, &aDevInfo, &aDevInfoSize) != sizeof(RID_DEVICE_INFO)
|
||||||
|
|| (aDevInfo.hid.dwVendorId != WNT_HIDSpaceMouse::VENDOR_ID_LOGITECH
|
||||||
|
&& aDevInfo.hid.dwVendorId != WNT_HIDSpaceMouse::VENDOR_ID_3DCONNEXION))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
WNT_HIDSpaceMouse aSpaceData (aDevInfo.hid.dwProductId, aRawInput->data.hid.bRawData, aRawInput->data.hid.dwSizeHid);
|
||||||
|
if (theListener.Update3dMouse (aSpaceData))
|
||||||
|
{
|
||||||
|
InvalidateContent (Handle(Aspect_DisplayConnection)());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
@ -24,16 +24,18 @@
|
|||||||
#include <Aspect_Drawable.hxx>
|
#include <Aspect_Drawable.hxx>
|
||||||
#include <Aspect_VKey.hxx>
|
#include <Aspect_VKey.hxx>
|
||||||
#include <Aspect_Handle.hxx>
|
#include <Aspect_Handle.hxx>
|
||||||
#include <Standard_Type.hxx>
|
|
||||||
#include <WNT_Dword.hxx>
|
#include <WNT_Dword.hxx>
|
||||||
|
|
||||||
|
class Aspect_WindowInputListener;
|
||||||
class WNT_WClass;
|
class WNT_WClass;
|
||||||
|
typedef struct tagMSG MSG;
|
||||||
|
|
||||||
DEFINE_STANDARD_HANDLE(WNT_Window, Aspect_Window)
|
DEFINE_STANDARD_HANDLE(WNT_Window, Aspect_Window)
|
||||||
|
|
||||||
//! This class defines Windows NT window
|
//! This class defines Windows NT window
|
||||||
class WNT_Window : public Aspect_Window
|
class WNT_Window : public Aspect_Window
|
||||||
{
|
{
|
||||||
|
DEFINE_STANDARD_RTTIEXT(WNT_Window, Aspect_Window)
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Convert WInAPI virtual key (VK_ enumeration) into Aspect_VKey.
|
//! Convert WInAPI virtual key (VK_ enumeration) into Aspect_VKey.
|
||||||
@ -53,31 +55,35 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Creates a Window defined by his position and size
|
//! Creates a Window defined by his position and size in pixels from the Parent Window.
|
||||||
//! in pixles from the Parent Window.
|
//! Trigger: Raises WindowDefinitionError if the Position out of the Screen Space or the window creation failed.
|
||||||
//! Trigger: Raises WindowDefinitionError if the Position out of the
|
Standard_EXPORT WNT_Window (const Standard_CString theTitle,
|
||||||
//! Screen Space or the window creation failed.
|
const Handle(WNT_WClass)& theClass,
|
||||||
Standard_EXPORT WNT_Window(const Standard_CString theTitle, const Handle(WNT_WClass)& theClass, const WNT_Dword& theStyle, const Standard_Integer thePxLeft, const Standard_Integer thePxTop, const Standard_Integer thePxWidth, const Standard_Integer thePxHeight, const Quantity_NameOfColor theBackColor = Quantity_NOC_MATRAGRAY, const Aspect_Handle theParent = 0, const Aspect_Handle theMenu = 0, const Standard_Address theClientStruct = 0);
|
const WNT_Dword& theStyle,
|
||||||
|
const Standard_Integer thePxLeft, const Standard_Integer thePxTop,
|
||||||
|
const Standard_Integer thePxWidth, const Standard_Integer thePxHeight,
|
||||||
|
const Quantity_NameOfColor theBackColor = Quantity_NOC_MATRAGRAY,
|
||||||
|
const Aspect_Handle theParent = 0,
|
||||||
|
const Aspect_Handle theMenu = 0,
|
||||||
|
const Standard_Address theClientStruct = 0);
|
||||||
|
|
||||||
//! Creates a Window based on the existing window handle.
|
//! Creates a Window based on the existing window handle.
|
||||||
//! This handle equals ( aPart1 << 16 ) + aPart2.
|
Standard_EXPORT WNT_Window (const Aspect_Handle theHandle,
|
||||||
Standard_EXPORT WNT_Window(const Aspect_Handle aHandle, const Quantity_NameOfColor aBackColor = Quantity_NOC_MATRAGRAY);
|
const Quantity_NameOfColor theBackColor = Quantity_NOC_MATRAGRAY);
|
||||||
|
|
||||||
//! Destroys the Window and all resourses attached to it.
|
//! Destroys the Window and all resources attached to it.
|
||||||
Standard_EXPORT ~WNT_Window();
|
Standard_EXPORT virtual ~WNT_Window();
|
||||||
|
|
||||||
//! Sets cursor <aCursor> for ENTIRE WINDOW CLASS to which
|
//! Sets cursor for ENTIRE WINDOW CLASS to which the Window belongs.
|
||||||
//! the Window belongs.
|
Standard_EXPORT void SetCursor (const Aspect_Handle theCursor) const;
|
||||||
Standard_EXPORT void SetCursor (const Aspect_Handle aCursor) const;
|
|
||||||
|
|
||||||
//! Opens the window <me>.
|
//! Opens the window <me>.
|
||||||
Standard_EXPORT virtual void Map() const Standard_OVERRIDE;
|
Standard_EXPORT virtual void Map() const Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Opens a window <me> according to <aMapMode>.
|
//! Opens a window according to the map mode.
|
||||||
//! This method is specific to Windows NT.
|
//! This method is specific to Windows NT.
|
||||||
//! <aMapMode> can be one of SW_xxx constants defined
|
//! @param theMapMode [in] can be one of SW_xxx constants defined in <windows.h>
|
||||||
//! in <windows.h>. See documentation.
|
Standard_EXPORT void Map (const Standard_Integer theMapMode) const;
|
||||||
Standard_EXPORT void Map (const Standard_Integer aMapMode) const;
|
|
||||||
|
|
||||||
//! Closes the window <me>.
|
//! Closes the window <me>.
|
||||||
Standard_EXPORT virtual void Unmap() const Standard_OVERRIDE;
|
Standard_EXPORT virtual void Unmap() const Standard_OVERRIDE;
|
||||||
@ -85,9 +91,8 @@ public:
|
|||||||
//! Applies the resizing to the window <me>.
|
//! Applies the resizing to the window <me>.
|
||||||
Standard_EXPORT virtual Aspect_TypeOfResize DoResize() Standard_OVERRIDE;
|
Standard_EXPORT virtual Aspect_TypeOfResize DoResize() Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Apply the mapping change to the window <me>
|
//! Does nothing on Windows.
|
||||||
//! and returns TRUE if the window is mapped at screen.
|
virtual Standard_Boolean DoMapping() const Standard_OVERRIDE { return Standard_True; }
|
||||||
virtual Standard_Boolean DoMapping() const Standard_OVERRIDE;
|
|
||||||
|
|
||||||
//! Changes variables due to window position.
|
//! Changes variables due to window position.
|
||||||
Standard_EXPORT void SetPos (const Standard_Integer X, const Standard_Integer Y, const Standard_Integer X1, const Standard_Integer Y1);
|
Standard_EXPORT void SetPos (const Standard_Integer X, const Standard_Integer Y, const Standard_Integer X1, const Standard_Integer Y1);
|
||||||
@ -106,17 +111,11 @@ public:
|
|||||||
//! Returns The Window SIZE in PIXEL
|
//! Returns The Window SIZE in PIXEL
|
||||||
Standard_EXPORT virtual void Size (Standard_Integer& Width, Standard_Integer& Height) const Standard_OVERRIDE;
|
Standard_EXPORT virtual void Size (Standard_Integer& Width, Standard_Integer& Height) const Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Returns the Windows NT handle of the created window <me>.
|
|
||||||
Aspect_Handle HWindow() const;
|
|
||||||
|
|
||||||
//! Returns the Windows NT handle parent of the created window <me>.
|
|
||||||
Aspect_Handle HParentWindow() const;
|
|
||||||
|
|
||||||
//! Returns native Window handle (HWND)
|
//! Returns native Window handle (HWND)
|
||||||
virtual Aspect_Drawable NativeHandle() const Standard_OVERRIDE;
|
virtual Aspect_Drawable NativeHandle() const Standard_OVERRIDE { return (Aspect_Drawable )myHWindow; }
|
||||||
|
|
||||||
//! Returns parent of native Window handle (HWND on Windows, Window with Xlib, and so on)
|
//! Returns parent of native Window handle (HWND on Windows).
|
||||||
virtual Aspect_Drawable NativeParentHandle() const Standard_OVERRIDE;
|
virtual Aspect_Drawable NativeParentHandle() const Standard_OVERRIDE { return (Aspect_Drawable )myHParentWindow; }
|
||||||
|
|
||||||
//! Returns nothing on Windows
|
//! Returns nothing on Windows
|
||||||
virtual Aspect_FBConfig NativeFBConfig() const Standard_OVERRIDE { return NULL; }
|
virtual Aspect_FBConfig NativeFBConfig() const Standard_OVERRIDE { return NULL; }
|
||||||
@ -126,7 +125,15 @@ public:
|
|||||||
|
|
||||||
//! Invalidate entire window content by calling InvalidateRect() WinAPI function, resulting in WM_PAINT event put into window message loop.
|
//! Invalidate entire window content by calling InvalidateRect() WinAPI function, resulting in WM_PAINT event put into window message loop.
|
||||||
//! Method can be called from non-window thread, and system will also automatically aggregate multiple events into single one.
|
//! Method can be called from non-window thread, and system will also automatically aggregate multiple events into single one.
|
||||||
Standard_EXPORT virtual void InvalidateContent (const Handle(Aspect_DisplayConnection)& theDisp = NULL) Standard_OVERRIDE;
|
Standard_EXPORT virtual void InvalidateContent (const Handle(Aspect_DisplayConnection)& theDisp = Handle(Aspect_DisplayConnection)()) Standard_OVERRIDE;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Returns the Windows NT handle of the created window <me>.
|
||||||
|
Aspect_Handle HWindow() const { return myHWindow; }
|
||||||
|
|
||||||
|
//! Returns the Windows NT handle parent of the created window <me>.
|
||||||
|
Aspect_Handle HParentWindow() const { return myHParentWindow; }
|
||||||
|
|
||||||
//! Raw input flags.
|
//! Raw input flags.
|
||||||
enum RawInputMask
|
enum RawInputMask
|
||||||
@ -140,22 +147,25 @@ public:
|
|||||||
//! @return number of actually registered device types
|
//! @return number of actually registered device types
|
||||||
Standard_EXPORT int RegisterRawInputDevices (unsigned int theRawDeviceMask);
|
Standard_EXPORT int RegisterRawInputDevices (unsigned int theRawDeviceMask);
|
||||||
|
|
||||||
DEFINE_STANDARD_RTTIEXT(WNT_Window,Aspect_Window)
|
//! Process a single window message.
|
||||||
|
//! @param theListener [in][out] listener to redirect message
|
||||||
|
//! @param theMsg [in][out] message to process
|
||||||
|
//! @return TRUE if message has been processed
|
||||||
|
Standard_EXPORT virtual bool ProcessMessage (Aspect_WindowInputListener& theListener,
|
||||||
|
MSG& theMsg);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Standard_Integer aXLeft;
|
|
||||||
Standard_Integer aYTop;
|
|
||||||
Standard_Integer aXRight;
|
|
||||||
Standard_Integer aYBottom;
|
|
||||||
Handle(WNT_WClass) myWClass;
|
Handle(WNT_WClass) myWClass;
|
||||||
Aspect_Handle myHWindow;
|
Aspect_Handle myHWindow;
|
||||||
Aspect_Handle myHParentWindow;
|
Aspect_Handle myHParentWindow;
|
||||||
|
Standard_Integer myXLeft;
|
||||||
|
Standard_Integer myYTop;
|
||||||
|
Standard_Integer myXRight;
|
||||||
|
Standard_Integer myYBottom;
|
||||||
Standard_Boolean myIsForeign;
|
Standard_Boolean myIsForeign;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#include <WNT_Window.lxx>
|
|
||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
#endif // _WNT_Window_HeaderFile
|
#endif // _WNT_Window_HeaderFile
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
// Copyright (c) 1996-1999 Matra Datavision
|
|
||||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// This file is part of Open CASCADE Technology software library.
|
|
||||||
//
|
|
||||||
// This library is free software; you can redistribute it and/or modify it under
|
|
||||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
||||||
// by the Free Software Foundation, with special exception defined in the file
|
|
||||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
||||||
// distribution for complete text of the license and disclaimer of any warranty.
|
|
||||||
//
|
|
||||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
||||||
// commercial license or contractual agreement.
|
|
||||||
|
|
||||||
inline Standard_Boolean WNT_Window::DoMapping() const
|
|
||||||
{
|
|
||||||
// DO nothing on WNT
|
|
||||||
return Standard_True;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Aspect_Handle WNT_Window::HWindow() const
|
|
||||||
{
|
|
||||||
return myHWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Aspect_Handle WNT_Window::HParentWindow() const
|
|
||||||
{
|
|
||||||
return myHParentWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Aspect_Drawable WNT_Window::NativeHandle() const
|
|
||||||
{
|
|
||||||
return (Aspect_Drawable )myHWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Aspect_Drawable WNT_Window::NativeParentHandle() const
|
|
||||||
{
|
|
||||||
return (Aspect_Drawable )myHParentWindow;
|
|
||||||
}
|
|
@ -18,7 +18,9 @@
|
|||||||
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
|
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
|
||||||
|
|
||||||
#include <Aspect_Convert.hxx>
|
#include <Aspect_Convert.hxx>
|
||||||
|
#include <Aspect_ScrollDelta.hxx>
|
||||||
#include <Aspect_WindowDefinitionError.hxx>
|
#include <Aspect_WindowDefinitionError.hxx>
|
||||||
|
#include <Aspect_WindowInputListener.hxx>
|
||||||
#include <Message.hxx>
|
#include <Message.hxx>
|
||||||
#include <Message_Messenger.hxx>
|
#include <Message_Messenger.hxx>
|
||||||
|
|
||||||
@ -531,4 +533,168 @@ Aspect_VKey Xw_Window::VirtualKeyFromNative (unsigned long theKey)
|
|||||||
return Aspect_VKey_UNKNOWN;
|
return Aspect_VKey_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : ProcessMessage
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Xw_Window::ProcessMessage (Aspect_WindowInputListener& theListener,
|
||||||
|
XEvent& theMsg)
|
||||||
|
{
|
||||||
|
Display* aDisplay = myDisplay->GetDisplay();
|
||||||
|
|
||||||
|
// Handle event for the chosen display connection
|
||||||
|
switch (theMsg.type)
|
||||||
|
{
|
||||||
|
case ClientMessage:
|
||||||
|
{
|
||||||
|
if ((Atom)theMsg.xclient.data.l[0] == myDisplay->GetAtom (Aspect_XA_DELETE_WINDOW)
|
||||||
|
&& theMsg.xclient.window == myXWindow)
|
||||||
|
{
|
||||||
|
theListener.ProcessClose();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case FocusIn:
|
||||||
|
case FocusOut:
|
||||||
|
{
|
||||||
|
if (theMsg.xfocus.window == myXWindow)
|
||||||
|
{
|
||||||
|
theListener.ProcessFocus (theMsg.type == FocusIn);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case Expose:
|
||||||
|
{
|
||||||
|
if (theMsg.xexpose.window == myXWindow)
|
||||||
|
{
|
||||||
|
theListener.ProcessExpose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove all the ExposureMask and process them at once
|
||||||
|
for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
|
||||||
|
{
|
||||||
|
if (!XCheckWindowEvent (aDisplay, myXWindow, ExposureMask, &theMsg))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case ConfigureNotify:
|
||||||
|
{
|
||||||
|
// remove all the StructureNotifyMask and process them at once
|
||||||
|
for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
|
||||||
|
{
|
||||||
|
if (!XCheckWindowEvent (aDisplay, myXWindow, StructureNotifyMask, &theMsg))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theMsg.xconfigure.window == myXWindow)
|
||||||
|
{
|
||||||
|
theListener.ProcessConfigure (true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case KeyPress:
|
||||||
|
case KeyRelease:
|
||||||
|
{
|
||||||
|
XKeyEvent* aKeyEvent = (XKeyEvent* )&theMsg;
|
||||||
|
const KeySym aKeySym = XLookupKeysym (aKeyEvent, 0);
|
||||||
|
const Aspect_VKey aVKey = Xw_Window::VirtualKeyFromNative (aKeySym);
|
||||||
|
if (aVKey != Aspect_VKey_UNKNOWN)
|
||||||
|
{
|
||||||
|
const double aTimeStamp = theListener.EventTime();
|
||||||
|
if (theMsg.type == KeyPress)
|
||||||
|
{
|
||||||
|
theListener.KeyDown (aVKey, aTimeStamp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
theListener.KeyUp (aVKey, aTimeStamp);
|
||||||
|
}
|
||||||
|
theListener.ProcessInput();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case ButtonPress:
|
||||||
|
case ButtonRelease:
|
||||||
|
{
|
||||||
|
const Graphic3d_Vec2i aPos (theMsg.xbutton.x, theMsg.xbutton.y);
|
||||||
|
Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
|
||||||
|
Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
|
||||||
|
if (theMsg.xbutton.button == Button1) { aButton = Aspect_VKeyMouse_LeftButton; }
|
||||||
|
if (theMsg.xbutton.button == Button2) { aButton = Aspect_VKeyMouse_MiddleButton; }
|
||||||
|
if (theMsg.xbutton.button == Button3) { aButton = Aspect_VKeyMouse_RightButton; }
|
||||||
|
|
||||||
|
if ((theMsg.xbutton.state & ControlMask) != 0) { aFlags |= Aspect_VKeyFlags_CTRL; }
|
||||||
|
if ((theMsg.xbutton.state & ShiftMask) != 0) { aFlags |= Aspect_VKeyFlags_SHIFT; }
|
||||||
|
if (theListener.Keys().IsKeyDown (Aspect_VKey_Alt))
|
||||||
|
{
|
||||||
|
aFlags |= Aspect_VKeyFlags_ALT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theMsg.xbutton.button == Button4
|
||||||
|
|| theMsg.xbutton.button == Button5)
|
||||||
|
{
|
||||||
|
if (theMsg.type != ButtonPress)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const double aDeltaF = (theMsg.xbutton.button == Button4 ? 1.0 : -1.0);
|
||||||
|
theListener.UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
|
||||||
|
}
|
||||||
|
else if (theMsg.type == ButtonPress)
|
||||||
|
{
|
||||||
|
theListener.PressMouseButton (aPos, aButton, aFlags, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
theListener.ReleaseMouseButton (aPos, aButton, aFlags, false);
|
||||||
|
}
|
||||||
|
theListener.ProcessInput();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case MotionNotify:
|
||||||
|
{
|
||||||
|
if (theMsg.xmotion.window != myXWindow)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove all the ButtonMotionMask and process them at once
|
||||||
|
for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
|
||||||
|
{
|
||||||
|
if (!XCheckWindowEvent (aDisplay, myXWindow, ButtonMotionMask | PointerMotionMask, &theMsg))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphic3d_Vec2i aPos (theMsg.xmotion.x, theMsg.xmotion.y);
|
||||||
|
Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE;
|
||||||
|
Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
|
||||||
|
if ((theMsg.xmotion.state & Button1Mask) != 0) { aButtons |= Aspect_VKeyMouse_LeftButton; }
|
||||||
|
if ((theMsg.xmotion.state & Button2Mask) != 0) { aButtons |= Aspect_VKeyMouse_MiddleButton; }
|
||||||
|
if ((theMsg.xmotion.state & Button3Mask) != 0) { aButtons |= Aspect_VKeyMouse_RightButton; }
|
||||||
|
|
||||||
|
if ((theMsg.xmotion.state & ControlMask) != 0) { aFlags |= Aspect_VKeyFlags_CTRL; }
|
||||||
|
if ((theMsg.xmotion.state & ShiftMask) != 0) { aFlags |= Aspect_VKeyFlags_SHIFT; }
|
||||||
|
if (theListener.Keys().IsKeyDown (Aspect_VKey_Alt))
|
||||||
|
{
|
||||||
|
aFlags |= Aspect_VKeyFlags_ALT;
|
||||||
|
}
|
||||||
|
|
||||||
|
theListener.UpdateMousePosition (aPos, aButtons, aFlags, false);
|
||||||
|
theListener.ProcessInput();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // Win32 or Mac OS X
|
#endif // Win32 or Mac OS X
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
class Aspect_WindowDefinitionError;
|
class Aspect_WindowDefinitionError;
|
||||||
class Aspect_WindowError;
|
class Aspect_WindowError;
|
||||||
|
class Aspect_WindowInputListener;
|
||||||
class Aspect_Background;
|
class Aspect_Background;
|
||||||
class Quantity_Color;
|
class Quantity_Color;
|
||||||
class Aspect_GradientBackground;
|
class Aspect_GradientBackground;
|
||||||
@ -125,6 +126,13 @@ public:
|
|||||||
//! for this working thread to avoid race conditions, since Xlib display connection is not thread-safe by default.
|
//! for this working thread to avoid race conditions, since Xlib display connection is not thread-safe by default.
|
||||||
Standard_EXPORT virtual void InvalidateContent (const Handle(Aspect_DisplayConnection)& theDisp) Standard_OVERRIDE;
|
Standard_EXPORT virtual void InvalidateContent (const Handle(Aspect_DisplayConnection)& theDisp) Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Process a single window message.
|
||||||
|
//! @param theListener [in][out] listener to redirect message
|
||||||
|
//! @param theMsg [in][out] message to process
|
||||||
|
//! @return TRUE if message has been processed
|
||||||
|
Standard_EXPORT virtual bool ProcessMessage (Aspect_WindowInputListener& theListener,
|
||||||
|
XEvent& theMsg);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Handle(Aspect_DisplayConnection) myDisplay; //!< X Display connection
|
Handle(Aspect_DisplayConnection) myDisplay; //!< X Display connection
|
||||||
|
Loading…
x
Reference in New Issue
Block a user