myMouseActiveGesture (AIS_MouseGesture_NONE),
myMouseActiveIdleRotation (false),
myMouseClickCounter (0),
- myMousePressed (Aspect_VKeyMouse_NONE),
- myMouseModifiers (Aspect_VKeyFlags_NONE),
myMouseSingleButton (-1),
myMouseStopDragOnUnclick (false),
//
myUpdateStartPointRot (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)
{
- memset(my3dMouseButtonState, 0, sizeof(my3dMouseButtonState));
- myEventTimer.Start();
myViewAnimation->SetOwnDuration (0.5);
myAnchorPointPrs1 = new AIS_Point (new Geom_CartesianPoint (0.0, 0.0, 0.0));
{
bool toUpdate = false;
toUpdate = update3dMouseTranslation (theEvent) || toUpdate;
- toUpdate = update3dMouseRotation (theEvent) || toUpdate;
+ toUpdate = (myToAllowRotation && update3dMouseRotation (theEvent)) || toUpdate;
toUpdate = update3dMouseKeys (theEvent) || 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
// purpose :
double theTime,
double thePressure)
{
- myKeys.KeyDown (theKey, theTime, thePressure);
+ Aspect_WindowInputListener::KeyDown (theKey, theTime, thePressure);
}
// =======================================================================
void AIS_ViewController::KeyUp (Aspect_VKey theKey,
double theTime)
{
- myKeys.KeyUp (theKey, theTime);
+ Aspect_WindowInputListener::KeyUp (theKey, theTime);
}
// =======================================================================
double theTime,
double thePressure)
{
- myKeys.KeyFromAxis (theNegative, thePositive, theTime, thePressure);
+ Aspect_WindowInputListener::KeyFromAxis (theNegative, thePositive, theTime, thePressure);
}
// =======================================================================
#include <Aspect_VKeySet.hxx>
#include <Aspect_TouchMap.hxx>
+#include <Aspect_WindowInputListener.hxx>
#include <Aspect_XRHapticActionData.hxx>
#include <Aspect_XRTrackedDeviceRole.hxx>
#include <AIS_DragAction.hxx>
//! - 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
//! UI thread receiving user input and Rendering thread for OCCT 3D Viewer drawing.
-class AIS_ViewController
+class AIS_ViewController : public Aspect_WindowInputListener
{
public:
public: //! @name keyboard input
- //! Return keyboard state.
- const Aspect_VKeySet& Keys() const { return myKeys; }
-
- //! Return keyboard state.
- Aspect_VKeySet& ChangeKeys() { return myKeys; }
+ using Aspect_WindowInputListener::Keys;
+ using Aspect_WindowInputListener::ChangeKeys;
//! 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);
+ double thePressure = 1.0) Standard_OVERRIDE;
//! 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);
+ double theTime) Standard_OVERRIDE;
//! 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);
+ double thePressure) Standard_OVERRIDE;
//! Fetch active navigation actions.
Standard_EXPORT AIS_WalkDelta FetchNavigationKeys (Standard_Real theCrouchRatio,
//! 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
- 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.
//! This method is expected to be called from UI thread.
Standard_EXPORT virtual bool UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
Aspect_VKeyMouse theButtons,
Aspect_VKeyFlags theModifiers,
- bool theIsEmulated);
+ bool theIsEmulated) Standard_OVERRIDE;
//! Handle mouse cursor movement event.
//! This method is expected to be called from UI thread.
Standard_EXPORT virtual bool UpdateMousePosition (const Graphic3d_Vec2i& thePoint,
Aspect_VKeyMouse theButtons,
Aspect_VKeyFlags theModifiers,
- bool theIsEmulated);
-
- //! 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);
- }
+ bool theIsEmulated) Standard_OVERRIDE;
//! 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.
Aspect_VKeyFlags theModifiers,
bool theIsDoubleClick);
- //! Return currently pressed mouse buttons.
- Aspect_VKeyMouse PressedMouseButtons() const { return myMousePressed; }
+ using Aspect_WindowInputListener::PressMouseButton;
+ using Aspect_WindowInputListener::ReleaseMouseButton;
- //! 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; }
+ using Aspect_WindowInputListener::PressedMouseButtons;
+ using Aspect_WindowInputListener::LastMouseFlags;
+ using Aspect_WindowInputListener::LastMousePosition;
public: //! @name multi-touch 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; }
+ //! Process 3d mouse input event (redirects to translation, rotation and keys).
+ Standard_EXPORT virtual bool Update3dMouse (const WNT_HIDSpaceMouse& theEvent) Standard_OVERRIDE;
- //! Return 3d mouse rotation axes (tilt/roll/spin) reverse flag; (TRUE, FALSE, FALSE) by default.
- const NCollection_Vec3<bool>& Get3dMouseToReverse() const { return my3dMouseToReverse; }
+public: //! @name resize events
- //! Return 3d mouse rotation axes (tilt/roll/spin) reverse flag; (TRUE, FALSE, FALSE) by default.
- NCollection_Vec3<bool>& Change3dMouseToReverse() { return my3dMouseToReverse; }
+ //! Handle expose event (window content has been invalidation and should be redrawn).
+ //! Default implementation does nothing.
+ virtual void ProcessExpose() Standard_OVERRIDE {}
- //! Process 3d mouse input event (redirects to translation, rotation and keys).
- Standard_EXPORT virtual bool Update3dMouse (const WNT_HIDSpaceMouse& theEvent);
+ //! Handle window resize event.
+ //! Default implementation does nothing.
+ virtual void ProcessConfigure (bool theIsResized) Standard_OVERRIDE
+ {
+ (void )theIsResized;
+ }
- //! Process 3d mouse input translation event.
- Standard_EXPORT virtual bool update3dMouseTranslation (const WNT_HIDSpaceMouse& theEvent);
+ //! 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 {}
- //! Process 3d mouse input rotation event.
- Standard_EXPORT virtual bool update3dMouseRotation (const WNT_HIDSpaceMouse& theEvent);
+ //! Handle focus event.
+ //! Default implementation does nothing.
+ virtual void ProcessFocus (bool theIsActivated)
+ {
+ (void )theIsActivated;
+ }
- //! Process 3d mouse input keys event.
- Standard_EXPORT virtual bool update3dMouseKeys (const WNT_HIDSpaceMouse& theEvent);
+ //! Handle window close event.
+ //! Default implementation does nothing.
+ virtual void ProcessClose() {}
public:
- //! Return event time (e.g. current time).
- double EventTime() const { return myEventTimer.ElapsedTime(); }
+ using Aspect_WindowInputListener::EventTime;
//! Reset input state (pressed keys, mouse buttons, etc.) e.g. on window focus loss.
//! This method is expected to be called from UI thread.
AIS_ViewInputBuffer myUI; //!< buffer for UI 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_Boolean myToAskNextFrame; //!< flag indicating that another frame should be drawn right after this one
Standard_Boolean myToDisplayXRAuxDevices; //!< flag to display auxiliary tracked XR devices
Standard_Boolean myToDisplayXRHands; //!< flag to display XR hands
-protected: //! @name keyboard input variables
-
- Aspect_VKeySet myKeys; //!< keyboard state
-
protected: //! @name mouse input variables
Standard_Real myMouseClickThreshold; //!< mouse click threshold in pixels; 3 by default
AIS_MouseSelectionSchemeMap
myMouseSelectionSchemes; //!< map defining selection schemes bound to mouse + modifiers
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 myMouseProgressPoint; //!< gesture progress
OSD_Timer myMouseClickTimer; //!< timer 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_Boolean myMouseStopDragOnUnclick; //!< queue stop dragging even with at next mouse unclick
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
-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
Handle(AIS_Point) myAnchorPointPrs1; //!< anchor point presentation (Graphic3d_ZLayerId_Top)
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
Aspect_Window.hxx
Aspect_WindowDefinitionError.hxx
Aspect_WindowError.hxx
+Aspect_WindowInputListener.cxx
+Aspect_WindowInputListener.hxx
Aspect_XAtom.hxx
Aspect_XRAction.hxx
Aspect_XRActionSet.hxx
//function : ProcessConfigure
//purpose :
//==============================================================================
-void ViewerTest_EventManager::ProcessConfigure()
+void ViewerTest_EventManager::ProcessConfigure (bool theIsResized)
{
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();
FlushViewEvents (myCtx, myView, true);
}
}
+//==============================================================================
+//function : ProcessInput
+//purpose :
+//==============================================================================
+void ViewerTest_EventManager::ProcessInput()
+{
+ if (!myView.IsNull())
+ {
+ FlushViewEvents (myCtx, myView, true);
+ }
+}
+
// =======================================================================
// function : navigationKeyModifierSwitch
// purpose :
double theTime) Standard_OVERRIDE;
//! Redraw the View on an Expose Event
- Standard_EXPORT virtual void ProcessExpose();
+ Standard_EXPORT virtual void ProcessExpose() Standard_OVERRIDE;
//! Handle redraw.
Standard_EXPORT virtual void handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
const Handle(V3d_View)& theView) Standard_OVERRIDE;
//! 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.
Standard_EXPORT void ProcessKeyPress (Aspect_VKey theKey);
//==============================================================================
#ifdef _WIN32
-static LRESULT WINAPI ViewerWindowProc(
- HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam );
-static LRESULT WINAPI AdvViewerWindowProc(
- HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam );
+static LRESULT WINAPI AdvViewerWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#endif
-
//==============================================================================
//function : WClass
//purpose :
{
if (ViewerTest_myViews.IsEmpty())
{
- return ViewerWindowProc (theWinHandle, theMsg, wParam, lParam);
+ return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
}
switch (theMsg)
ActivateView (FindViewIdByWindowHandle (theWinHandle));
}
}
- break;
- }
- 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;
+ return 0;
}
- case WM_LBUTTONUP:
- case WM_MBUTTONUP:
- case WM_RBUTTONUP:
case WM_LBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_RBUTTONDOWN:
{
- const Graphic3d_Vec2i aPos (LOWORD(lParam), HIWORD(lParam));
- 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;
+ TheIsAnimating = Standard_False;
}
- 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:
+ Standard_FALLTHROUGH
+ default:
{
- 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)
+ const Handle(V3d_View)& aView = ViewerTest::CurrentView();
+ if (!aView.IsNull()
+ && !VT_GetWindow().IsNull())
{
- POINT aCursorPnt = { aCursor.ptScreenPos.x, aCursor.ptScreenPos.y };
- if (ScreenToClient (theWinHandle, &aCursorPnt))
+ MSG aMsg = {};
+ aMsg.hwnd = theWinHandle;
+ aMsg.message = theMsg;
+ aMsg.wParam = wParam;
+ aMsg.lParam = lParam;
+ if (VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aMsg))
{
- // 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();
+ return 0;
}
}
-
- 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;
- }
- default:
- {
- return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
}
}
- return 0L;
+ return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
}
//==============================================================================
#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)
{
static XEvent aReport;
}
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 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)
{
- 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;
- if (anXWindow != aReport.xmotion.window)
- {
- break;
- }
-
- // 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)
+ const Handle(V3d_View)& aView = ViewerTest::CurrentView();
+ if (!aView.IsNull()
+ && !VT_GetWindow().IsNull())
{
- aButtons |= Aspect_VKeyMouse_LeftButton;
+ VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aReport);
}
- 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;
}
}
WNT_WClass.hxx
WNT_Window.cxx
WNT_Window.hxx
-WNT_Window.lxx
WNT_WindowPtr.hxx
#if defined(_WIN32) && !defined(OCCT_UWP)
#include <Aspect_Convert.hxx>
+#include <Aspect_ScrollDelta.hxx>
#include <Aspect_WindowDefinitionError.hxx>
#include <Aspect_WindowError.hxx>
+#include <Aspect_WindowInputListener.hxx>
#include <Message.hxx>
-#include <Standard_Type.hxx>
+#include <NCollection_LocalArray.hxx>
#include <TCollection_ExtendedString.hxx>
#include <WNT_WClass.hxx>
+#include <WNT_HIDSpaceMouse.hxx>
IMPLEMENT_STANDARD_RTTIEXT(WNT_Window, Aspect_Window)
const Aspect_Handle theMenu,
const Standard_Address theClientStruct)
: Aspect_Window(),
- aXLeft (thePxLeft),
- aYTop (thePxTop),
- aXRight (thePxLeft + thePxWidth),
- aYBottom (thePxTop + thePxHeight),
myWClass (theClass),
+ myHWindow (NULL),
+ myHParentWindow (NULL),
+ myXLeft (thePxLeft),
+ myYTop (thePxTop),
+ myXRight (thePxLeft + thePxWidth),
+ myYBottom (thePxTop + thePxHeight),
myIsForeign (Standard_False)
{
if (thePxWidth <= 0 || thePxHeight <= 0)
// include decorations in the window dimensions to reproduce same behavior of Xw_Window
RECT aRect;
- aRect.top = aYTop;
- aRect.bottom = aYBottom;
- aRect.left = aXLeft;
- aRect.right = aXRight;
+ aRect.top = myYTop;
+ aRect.bottom = myYBottom;
+ aRect.left = myXLeft;
+ aRect.right = myXRight;
AdjustWindowRect (&aRect, aStyle, theMenu != NULL ? TRUE : FALSE);
- aXLeft = aRect.left;
- aYTop = aRect.top;
- aXRight = aRect.right;
- aYBottom = aRect.bottom;
+ myXLeft = aRect.left;
+ myYTop = aRect.top;
+ myXRight = aRect.right;
+ myYBottom = aRect.bottom;
const TCollection_ExtendedString aTitleW (theTitle);
const TCollection_ExtendedString aClassNameW (myWClass->Name());
myHWindow = CreateWindowW (aClassNameW.ToWideString(), aTitleW.ToWideString(),
aStyle,
- aXLeft, aYTop,
- (aXRight - aXLeft), (aYBottom - aYTop),
+ myXLeft, myYTop,
+ (myXRight - myXLeft), (myYBottom - myYTop),
(HWND )theParent,
(HMENU )theMenu,
(HINSTANCE )myWClass->Instance(),
// =======================================================================
WNT_Window::WNT_Window (const Aspect_Handle theHandle,
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);
- WINDOWPLACEMENT aPlace;
- aPlace.length = sizeof (WINDOWPLACEMENT);
+ WINDOWPLACEMENT aPlace = {};
+ aPlace.length = sizeof(WINDOWPLACEMENT);
::GetWindowPlacement ((HWND )myHWindow, &aPlace);
- aXLeft = aPlace.rcNormalPosition.left;
- aYTop = aPlace.rcNormalPosition.top;
- aXRight = aPlace.rcNormalPosition.right;
- aYBottom = aPlace.rcNormalPosition.bottom;
+ myXLeft = aPlace.rcNormalPosition.left;
+ myYTop = aPlace.rcNormalPosition.top;
+ myXRight = aPlace.rcNormalPosition.right;
+ myYBottom = aPlace.rcNormalPosition.bottom;
}
// =======================================================================
return Standard_True;
}
- WINDOWPLACEMENT aPlace;
- aPlace.length = sizeof (WINDOWPLACEMENT);
+ WINDOWPLACEMENT aPlace = {};
+ aPlace.length = sizeof(WINDOWPLACEMENT);
::GetWindowPlacement ((HWND )myHWindow, &aPlace);
return !(aPlace.showCmd == SW_HIDE
|| aPlace.showCmd == SW_MINIMIZE);
return Aspect_TOR_UNKNOWN;
}
- int mask = 0;
- Aspect_TypeOfResize mode = Aspect_TOR_UNKNOWN;
- WINDOWPLACEMENT wp;
-
- wp.length = sizeof ( WINDOWPLACEMENT );
- GetWindowPlacement ( ( HWND )myHWindow, &wp );
-
- if (wp.showCmd != SW_SHOWMINIMIZED)
+ WINDOWPLACEMENT aPlace = {};
+ aPlace.length = sizeof(WINDOWPLACEMENT);
+ GetWindowPlacement ((HWND )myHWindow, &aPlace);
+ if (aPlace.showCmd == SW_SHOWMINIMIZED)
{
- if (Abs ((int )wp.rcNormalPosition.left - aXLeft ) > 2) mask |= 1;
- 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;
+ return Aspect_TOR_UNKNOWN;
+ }
- 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;
}
// =======================================================================
{
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);
return Standard_Real(aRect.right - aRect.left) / Standard_Real(aRect.bottom - aRect.top);
}
{
if (IsVirtual())
{
- theX1 = aXLeft;
- theX2 = aXRight;
- theY1 = aYTop;
- theY2 = aYBottom;
+ theX1 = myXLeft;
+ theX2 = myXRight;
+ theY1 = myYTop;
+ theY2 = myYBottom;
return;
}
- RECT aRect;
+ RECT aRect = {};
::GetClientRect ((HWND )myHWindow, &aRect);
POINT aPntLeft, aPntRight;
{
if (IsVirtual())
{
- theWidth = aXRight - aXLeft;
- theHeight = aYBottom - aYTop;
+ theWidth = myXRight - myXLeft;
+ theHeight = myYBottom - myYTop;
return;
}
- RECT aRect;
+ RECT aRect = {};
::GetClientRect ((HWND )myHWindow, &aRect);
theWidth = aRect.right;
theHeight = aRect.bottom;
void WNT_Window::SetPos (const Standard_Integer theX, const Standard_Integer theY,
const Standard_Integer theX1, const Standard_Integer theY1)
{
- aXLeft = theX;
- aYTop = theY;
- aXRight = theX1;
- aYBottom = theY1;
+ myXLeft = theX;
+ myYTop = theY;
+ myXRight = theX1;
+ myYBottom = theY1;
}
// =======================================================================
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
#include <Aspect_Drawable.hxx>
#include <Aspect_VKey.hxx>
#include <Aspect_Handle.hxx>
-#include <Standard_Type.hxx>
#include <WNT_Dword.hxx>
+class Aspect_WindowInputListener;
class WNT_WClass;
+typedef struct tagMSG MSG;
DEFINE_STANDARD_HANDLE(WNT_Window, Aspect_Window)
//! This class defines Windows NT window
class WNT_Window : public Aspect_Window
{
+ DEFINE_STANDARD_RTTIEXT(WNT_Window, Aspect_Window)
public:
//! Convert WInAPI virtual key (VK_ enumeration) into Aspect_VKey.
public:
- //! Creates a Window defined by his position and size
- //! in pixles from the Parent Window.
- //! Trigger: Raises WindowDefinitionError if the Position out of the
- //! Screen Space or the window creation failed.
- 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);
-
+ //! Creates a Window defined by his position and size in pixels from the Parent Window.
+ //! Trigger: Raises WindowDefinitionError if the Position out of the Screen Space or the window creation failed.
+ 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);
+
//! Creates a Window based on the existing window handle.
- //! This handle equals ( aPart1 << 16 ) + aPart2.
- Standard_EXPORT WNT_Window(const Aspect_Handle aHandle, const Quantity_NameOfColor aBackColor = Quantity_NOC_MATRAGRAY);
-
- //! Destroys the Window and all resourses attached to it.
- Standard_EXPORT ~WNT_Window();
-
- //! Sets cursor <aCursor> for ENTIRE WINDOW CLASS to which
- //! the Window belongs.
- Standard_EXPORT void SetCursor (const Aspect_Handle aCursor) const;
-
+ Standard_EXPORT WNT_Window (const Aspect_Handle theHandle,
+ const Quantity_NameOfColor theBackColor = Quantity_NOC_MATRAGRAY);
+
+ //! Destroys the Window and all resources attached to it.
+ Standard_EXPORT virtual ~WNT_Window();
+
+ //! Sets cursor for ENTIRE WINDOW CLASS to which the Window belongs.
+ Standard_EXPORT void SetCursor (const Aspect_Handle theCursor) const;
+
//! Opens the window <me>.
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.
- //! <aMapMode> can be one of SW_xxx constants defined
- //! in <windows.h>. See documentation.
- Standard_EXPORT void Map (const Standard_Integer aMapMode) const;
-
+ //! @param theMapMode [in] can be one of SW_xxx constants defined in <windows.h>
+ Standard_EXPORT void Map (const Standard_Integer theMapMode) const;
+
//! Closes the window <me>.
Standard_EXPORT virtual void Unmap() const Standard_OVERRIDE;
//! Applies the resizing to the window <me>.
Standard_EXPORT virtual Aspect_TypeOfResize DoResize() Standard_OVERRIDE;
- //! Apply the mapping change to the window <me>
- //! and returns TRUE if the window is mapped at screen.
- virtual Standard_Boolean DoMapping() const Standard_OVERRIDE;
-
+ //! Does nothing on Windows.
+ virtual Standard_Boolean DoMapping() const Standard_OVERRIDE { return Standard_True; }
+
//! 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);
//! Returns The Window SIZE in PIXEL
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)
- 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)
- virtual Aspect_Drawable NativeParentHandle() const Standard_OVERRIDE;
+ //! Returns parent of native Window handle (HWND on Windows).
+ virtual Aspect_Drawable NativeParentHandle() const Standard_OVERRIDE { return (Aspect_Drawable )myHParentWindow; }
//! Returns nothing on Windows
virtual Aspect_FBConfig NativeFBConfig() const Standard_OVERRIDE { return NULL; }
//! 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.
- 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.
enum RawInputMask
//! @return number of actually registered device types
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:
- Standard_Integer aXLeft;
- Standard_Integer aYTop;
- Standard_Integer aXRight;
- Standard_Integer aYBottom;
Handle(WNT_WClass) myWClass;
- Aspect_Handle myHWindow;
- Aspect_Handle myHParentWindow;
+ Aspect_Handle myHWindow;
+ Aspect_Handle myHParentWindow;
+ Standard_Integer myXLeft;
+ Standard_Integer myYTop;
+ Standard_Integer myXRight;
+ Standard_Integer myYBottom;
Standard_Boolean myIsForeign;
};
-#include <WNT_Window.lxx>
-
#endif // _WIN32
#endif // _WNT_Window_HeaderFile
+++ /dev/null
-// 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;
-}
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
#include <Aspect_Convert.hxx>
+#include <Aspect_ScrollDelta.hxx>
#include <Aspect_WindowDefinitionError.hxx>
+#include <Aspect_WindowInputListener.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
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
class Aspect_WindowDefinitionError;
class Aspect_WindowError;
+class Aspect_WindowInputListener;
class Aspect_Background;
class Quantity_Color;
class Aspect_GradientBackground;
//! 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;
+ //! 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:
Handle(Aspect_DisplayConnection) myDisplay; //!< X Display connection