ViewerTest_EventManager now inherits AIS_ViewController.
Platform-dependent user input handling within ViewerTest has been revised
to process events in common way through AIS_ViewController.
The mouse navigation has been changed, so that left mouse clicked
without modifers now rotates View.
The rubber-band selection can be activated via Alt+LeftMouseButton.
Selection is now done on mouse unclick and keyboard short-cuts take effect on unclick.
Aspect_Window::SetTitle() - added new method configuring Window title.
Introduced new types Aspect_Touch, Aspect_VKey, Aspect_ScrollDelta
for processing window events in platform-independent way.
--- /dev/null
+// Copyright (c) 2018-2019 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 _AIS_DragAction_HeaderFile
+#define _AIS_DragAction_HeaderFile
+
+//! Dragging action.
+enum AIS_DragAction
+{
+ AIS_DragAction_Start, //!< (try) start dragging object
+ AIS_DragAction_Update, //!< perform dragging (update position)
+ AIS_DragAction_Stop, //!< stop dragging (save position)
+ AIS_DragAction_Abort, //!< abort dragging (restore initial position)
+};
+
+#endif // _AIS_DragAction_HeaderFile
anActiveViewIter.Value()->View()->InvalidateZLayerBoundingBox (aLayerId);
}
}
+
+//=======================================================================
+//function : GravityPoint
+//purpose :
+//=======================================================================
+gp_Pnt AIS_InteractiveContext::GravityPoint (const Handle(V3d_View)& theView) const
+{
+ return theView->GravityPoint();
+}
Standard_EXPORT void AddOrRemoveSelected (const Handle(AIS_InteractiveObject)& theObject,
const Standard_Boolean theToUpdateViewer);
+ //! Updates Selected state of specified owner without calling HilightSelected().
+ //! Has no effect if Selected state is not changed, and redirects to AddOrRemoveSelected() otherwise.
+ //! @param theOwner owner object to set selected state
+ //! @param theIsSelected new selected state
+ //! @return TRUE if Selected state has been changed
+ Standard_EXPORT Standard_Boolean SetSelectedState (const Handle(SelectMgr_EntityOwner)& theOwner,
+ const Standard_Boolean theIsSelected);
+
//! Highlights selected objects.
Standard_EXPORT void HilightSelected (const Standard_Boolean theToUpdateViewer);
//! returns the number of removed structures from the viewers.
Standard_EXPORT Standard_Integer PurgeDisplay();
+ //! Return rotation gravity point.
+ Standard_EXPORT virtual gp_Pnt GravityPoint (const Handle(V3d_View)& theView) const;
+
public: //! @name debug visualization
//! Visualization of sensitives - for debugging purposes!
UpdateCurrentViewer();
}
+// =======================================================================
+// function : SetSelectedState
+// purpose :
+// =======================================================================
+Standard_Boolean AIS_InteractiveContext::SetSelectedState (const Handle(SelectMgr_EntityOwner)& theEntity,
+ const Standard_Boolean theIsSelected)
+{
+ if (theEntity.IsNull())
+ {
+ throw Standard_ProgramError ("Internal error: AIS_InteractiveContext::SetSelectedState() called with NO object");
+ }
+
+ if (!theEntity->HasSelectable()
+ || mySelection->IsSelected (theEntity) == theIsSelected)
+ {
+ return false;
+ }
+
+ if (theEntity->IsAutoHilight())
+ {
+ AddOrRemoveSelected (theEntity, false);
+ return true;
+ }
+
+ if (theIsSelected)
+ {
+ const AIS_SelectStatus aSelStatus = mySelection->AddSelect (theEntity);
+ theEntity->SetSelected (true);
+ return aSelStatus == AIS_SS_Added;
+ }
+ else
+ {
+ const AIS_SelectStatus aSelStatus = mySelection->Select (theEntity);
+ theEntity->SetSelected (false);
+ return aSelStatus == AIS_SS_Removed;
+ }
+}
//=======================================================================
//function : IsSelected
--- /dev/null
+// Copyright (c) 2019 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 _AIS_MouseGesture_HeaderFile
+#define _AIS_MouseGesture_HeaderFile
+
+#include <NCollection_DataMap.hxx>
+
+//! Mouse gesture - only one can be active at one moment.
+enum AIS_MouseGesture
+{
+ AIS_MouseGesture_NONE, //!< no active gesture
+ //
+ AIS_MouseGesture_SelectRectangle, //!< rectangular selection
+ AIS_MouseGesture_SelectLasso, //!< polygonal selection
+ //
+ AIS_MouseGesture_Zoom, //!< view zoom gesture
+ AIS_MouseGesture_Pan, //!< view panning gesture
+ AIS_MouseGesture_RotateOrbit, //!< orbit rotation gesture
+ AIS_MouseGesture_RotateView, //!< view rotation gesture
+};
+
+//! Map defining mouse gestures.
+typedef NCollection_DataMap<unsigned int, AIS_MouseGesture> AIS_MouseGestureMap;
+
+#endif // _AIS_MouseGesture_HeaderFile
--- /dev/null
+// Copyright (c) 2019 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 _AIS_NavigationMode_HeaderFile
+#define _AIS_NavigationMode_HeaderFile
+
+//! Camera navigation mode.
+enum AIS_NavigationMode
+{
+ AIS_NavigationMode_Orbit, //!< orbit rotation
+ AIS_NavigationMode_FirstPersonFlight, //!< flight rotation (first person)
+ AIS_NavigationMode_FirstPersonWalk, //!< walking mode (first person)
+};
+
+enum
+{
+ AIS_NavigationMode_LOWER = 0,
+ AIS_NavigationMode_UPPER = AIS_NavigationMode_FirstPersonWalk
+};
+
+#endif // _V3d_NavigationMode_HeaderFile
--- /dev/null
+// Copyright (c) 2019 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 _AIS_RotationMode_HeaderFile
+#define _AIS_RotationMode_HeaderFile
+
+//! Camera rotation mode.
+enum AIS_RotationMode
+{
+ AIS_RotationMode_BndBoxActive, //!< default OCCT rotation
+ AIS_RotationMode_PickLast, //!< rotate around last picked point
+ AIS_RotationMode_PickCenter, //!< rotate around point at the center of window
+ AIS_RotationMode_CameraAt, //!< rotate around camera center
+ AIS_RotationMode_BndBoxScene, //!< rotate around scene center
+};
+
+enum
+{
+ AIS_RotationMode_LOWER = 0,
+ AIS_RotationMode_UPPER = AIS_RotationMode_BndBoxScene,
+};
+
+#endif // _AIS_RotationMode_HeaderFile
--- /dev/null
+// Copyright (c) 2016-2019 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 "AIS_ViewController.hxx"
+
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_Manipulator.hxx>
+#include <AIS_Point.hxx>
+#include <AIS_RubberBand.hxx>
+#include <Aspect_Grid.hxx>
+#include <Geom_CartesianPoint.hxx>
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <gp_Quaternion.hxx>
+#include <V3d_View.hxx>
+
+// =======================================================================
+// function : AIS_ViewController
+// purpose :
+// =======================================================================
+AIS_ViewController::AIS_ViewController()
+: myLastEventsTime (0.0),
+ myToAskNextFrame (false),
+ myMinCamDistance (1.0),
+ myRotationMode (AIS_RotationMode_BndBoxActive),
+ myNavigationMode (AIS_NavigationMode_Orbit),
+ myMouseAccel (1.0f),
+ myOrbitAccel (1.0f),
+ myToShowPanAnchorPoint (true),
+ myToShowRotateCenter (true),
+ myToLockOrbitZUp (false),
+ myToInvertPitch (false),
+ myToAllowTouchZRotation(false),
+ myToAllowRotation (true),
+ myToAllowPanning (true),
+ myToAllowZooming (true),
+ myToAllowZFocus (true),
+ myToAllowHighlight (true),
+ myToAllowDragging (true),
+ //
+ myWalkSpeedAbsolute (1.5f),
+ myWalkSpeedRelative (0.1f),
+ myThrustSpeed (0.0f),
+ myHasThrust (false),
+ //
+ myPrevMoveTo (-1, -1),
+ myHasHlrOnBeforeRotation (false),
+ //
+ myMouseClickThreshold (3.0),
+ myMouseDoubleClickInt (0.4),
+ myScrollZoomRatio (15.0f),
+ myMouseActiveGesture (AIS_MouseGesture_NONE),
+ myMouseActiveIdleRotation (false),
+ myMouseClickCounter (0),
+ myMousePressed (Aspect_VKeyMouse_NONE),
+ myMouseModifiers (Aspect_VKeyFlags_NONE),
+ myMouseSingleButton (-1),
+ //
+ myTouchToleranceScale (1.0f),
+ myTouchRotationThresholdPx (6.0f),
+ myTouchZRotationThreshold (float(2.0 * M_PI / 180.0)),
+ myTouchPanThresholdPx (4.0f),
+ myTouchZoomThresholdPx (6.0f),
+ myTouchZoomRatio (0.13f),
+ //
+ myNbTouchesLast (0),
+ myUpdateStartPointPan (true),
+ myUpdateStartPointRot (true),
+ myUpdateStartPointZRot (true),
+ //
+ myPanPnt3d (Precision::Infinite(), 0.0, 0.0)
+{
+ myEventTimer.Start();
+
+ myAnchorPointPrs1 = new AIS_Point (new Geom_CartesianPoint (0.0, 0.0, 0.0));
+ myAnchorPointPrs1->SetZLayer (Graphic3d_ZLayerId_Top);
+ myAnchorPointPrs1->SetMutable (true);
+
+ myAnchorPointPrs2 = new AIS_Point (new Geom_CartesianPoint (0.0, 0.0, 0.0));
+ myAnchorPointPrs2->SetZLayer (Graphic3d_ZLayerId_Topmost);
+ myAnchorPointPrs2->SetMutable (true);
+
+ myRubberBand = new AIS_RubberBand (Quantity_NOC_LIGHTBLUE, Aspect_TOL_SOLID, Quantity_NOC_LIGHTBLUE, 0.4, 1.0);
+ myRubberBand->SetZLayer (Graphic3d_ZLayerId_TopOSD);
+ myRubberBand->SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_UPPER));
+ myRubberBand->SetDisplayMode (0);
+ myRubberBand->SetMutable (true);
+
+ myMouseGestureMap.Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_RotateOrbit);
+ myMouseGestureMap.Bind (Aspect_VKeyMouse_LeftButton | Aspect_VKeyFlags_CTRL, AIS_MouseGesture_Zoom);
+ myMouseGestureMap.Bind (Aspect_VKeyMouse_LeftButton | Aspect_VKeyFlags_SHIFT, AIS_MouseGesture_Pan);
+ myMouseGestureMap.Bind (Aspect_VKeyMouse_LeftButton | Aspect_VKeyFlags_ALT, AIS_MouseGesture_SelectRectangle);
+
+ myMouseGestureMap.Bind (Aspect_VKeyMouse_RightButton, AIS_MouseGesture_Zoom);
+ myMouseGestureMap.Bind (Aspect_VKeyMouse_RightButton | Aspect_VKeyFlags_CTRL, AIS_MouseGesture_RotateOrbit);
+
+ myMouseGestureMap.Bind (Aspect_VKeyMouse_MiddleButton, AIS_MouseGesture_Pan);
+ myMouseGestureMap.Bind (Aspect_VKeyMouse_MiddleButton | Aspect_VKeyFlags_CTRL, AIS_MouseGesture_Pan);
+}
+
+// =======================================================================
+// function : ResetViewInput
+// purpose :
+// =======================================================================
+void AIS_ViewController::ResetViewInput()
+{
+ myKeys.Reset();
+ myMousePressed = Aspect_VKeyMouse_NONE;
+ myMouseModifiers = Aspect_VKeyFlags_NONE;
+ myMouseSingleButton = -1;
+ myUI.Dragging.ToAbort = true;
+ myMouseActiveGesture = AIS_MouseGesture_NONE;
+ myMouseClickTimer.Stop();
+ myMouseClickCounter = 0;
+}
+
+// =======================================================================
+// function : FlushViewEvents
+// purpose :
+// =======================================================================
+void AIS_ViewController::FlushViewEvents (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView,
+ Standard_Boolean theToHandle)
+{
+ flushBuffers (theCtx, theView);
+ flushGestures(theCtx, theView);
+ if (theToHandle)
+ {
+ HandleViewEvents (theCtx, theView);
+ }
+}
+
+// =======================================================================
+// function : flushBuffers
+// purpose :
+// =======================================================================
+void AIS_ViewController::flushBuffers (const Handle(AIS_InteractiveContext)& ,
+ const Handle(V3d_View)& )
+{
+ myToAskNextFrame = false;
+
+ myGL.IsNewGesture = myUI.IsNewGesture;
+ myUI.IsNewGesture = false;
+
+ myGL.ZoomActions.Clear();
+ myGL.ZoomActions.Append (myUI.ZoomActions);
+ myUI.ZoomActions.Clear();
+
+ myGL.Orientation.ToFitAll = myUI.Orientation.ToFitAll;
+ myUI.Orientation.ToFitAll = false;
+ if (myUI.Orientation.ToSetViewOrient)
+ {
+ myUI.Orientation.ToSetViewOrient = false;
+ myGL.Orientation.ToSetViewOrient = true;
+ myGL.Orientation.ViewOrient = myUI.Orientation.ViewOrient;
+ }
+
+ if (myUI.MoveTo.ToHilight)
+ {
+ myUI.MoveTo.ToHilight = false;
+ myGL.MoveTo.ToHilight = true;
+ myGL.MoveTo.Point = myUI.MoveTo.Point;
+ }
+
+ {
+ myGL.Selection.Tool = myUI.Selection.Tool;
+ myGL.Selection.IsXOR = myUI.Selection.IsXOR;
+ myGL.Selection.Points = myUI.Selection.Points;
+ myUI.Selection.IsXOR = false;
+ if (myUI.Selection.Tool == AIS_ViewSelectionTool_Picking)
+ {
+ myUI.Selection.Points.Clear();
+ }
+ }
+
+ if (myUI.Selection.ToApplyTool)
+ {
+ myGL.Selection.ToApplyTool = true;
+ myUI.Selection.ToApplyTool = false;
+ myUI.Selection.Points.Clear();
+ }
+
+ if (myUI.Panning.ToStart)
+ {
+ myUI.Panning.ToStart = false;
+ myGL.Panning.ToStart = true;
+ myGL.Panning.PointStart = myUI.Panning.PointStart;
+ }
+
+ if (myUI.Panning.ToPan)
+ {
+ myUI.Panning.ToPan = false;
+ myGL.Panning.ToPan = true;
+ myGL.Panning.Delta = myUI.Panning.Delta;
+ }
+
+ if (myUI.Dragging.ToAbort)
+ {
+ myUI.Dragging.ToAbort = false;
+ myGL.Dragging.ToAbort = true;
+ }
+ else if (myUI.Dragging.ToStop)
+ {
+ myUI.Dragging.ToStop = false;
+ myGL.Dragging.ToStop = true;
+ }
+ else if (myUI.Dragging.ToStart)
+ {
+ myUI.Dragging.ToStart = false;
+ myGL.Dragging.ToStart = true;
+ myGL.Dragging.PointStart = myUI.Dragging.PointStart;
+ }
+ myGL.Dragging.PointTo = myUI.Dragging.PointTo;
+
+ if (myUI.OrbitRotation.ToStart)
+ {
+ myUI.OrbitRotation.ToStart = false;
+ myGL.OrbitRotation.ToStart = true;
+ myGL.OrbitRotation.PointStart = myUI.OrbitRotation.PointStart;
+ }
+
+ if (myUI.OrbitRotation.ToRotate)
+ {
+ myUI.OrbitRotation.ToRotate = false;
+ myGL.OrbitRotation.ToRotate = true;
+ myGL.OrbitRotation.PointTo = myUI.OrbitRotation.PointTo;
+ }
+
+ if (myUI.ViewRotation.ToStart)
+ {
+ myUI.ViewRotation.ToStart = false;
+ myGL.ViewRotation.ToStart = true;
+ myGL.ViewRotation.PointStart = myUI.ViewRotation.PointStart;
+ }
+
+ if (myUI.ViewRotation.ToRotate)
+ {
+ myUI.ViewRotation.ToRotate = false;
+ myGL.ViewRotation.ToRotate = true;
+ myGL.ViewRotation.PointTo = myUI.ViewRotation.PointTo;
+ }
+
+ if (myUI.ZRotate.ToRotate)
+ {
+ myGL.ZRotate = myUI.ZRotate;
+ myUI.ZRotate.ToRotate = false;
+ }
+}
+
+// =======================================================================
+// function : flushGestures
+// purpose :
+// =======================================================================
+void AIS_ViewController::flushGestures (const Handle(AIS_InteractiveContext)& ,
+ const Handle(V3d_View)& theView)
+{
+ const Standard_Real aTolScale = myTouchToleranceScale;
+ const Standard_Integer aTouchNb = myTouchPoints.Extent();
+ if (myNbTouchesLast != aTouchNb)
+ {
+ myNbTouchesLast = aTouchNb;
+ myGL.IsNewGesture = true;
+ }
+ if (aTouchNb == 1) // touch
+ {
+ Aspect_Touch& aTouch = myTouchPoints.ChangeFromIndex (1);
+ if (myUpdateStartPointRot)
+ {
+ // skip rotation if have active dragged object
+ if (myNavigationMode == AIS_NavigationMode_Orbit)
+ {
+ myGL.OrbitRotation.ToStart = true;
+ myGL.OrbitRotation.PointStart = myStartRotCoord;
+ }
+ else
+ {
+ myGL.ViewRotation.ToStart = true;
+ myGL.ViewRotation.PointStart = myStartRotCoord;
+ }
+
+ myUpdateStartPointRot = false;
+ theView->Invalidate();
+ }
+
+ // rotation
+ const Standard_Real aRotTouchTol = !aTouch.IsPreciseDevice
+ ? aTolScale * myTouchRotationThresholdPx
+ : gp::Resolution();
+ if (Abs (aTouch.Delta().x()) + Abs(aTouch.Delta().y()) > aRotTouchTol)
+ {
+ const Standard_Real aRotAccel = myNavigationMode == AIS_NavigationMode_FirstPersonWalk ? myMouseAccel : myOrbitAccel;
+ if (myNavigationMode == AIS_NavigationMode_Orbit)
+ {
+ const Graphic3d_Vec2d aRotDelta = aTouch.To - myGL.OrbitRotation.PointStart;
+ myGL.OrbitRotation.ToRotate = true;
+ myGL.OrbitRotation.PointTo = myGL.OrbitRotation.PointStart + aRotDelta * aRotAccel;
+ myGL.Dragging.PointTo.SetValues ((int )aTouch.To.x(), (int )aTouch.To.y());
+ }
+ else
+ {
+ const Graphic3d_Vec2d aRotDelta = aTouch.To - myGL.ViewRotation.PointStart;
+ myGL.ViewRotation.ToRotate = true;
+ myGL.ViewRotation.PointTo = myGL.ViewRotation.PointStart + aRotDelta * aRotAccel;
+ myGL.Dragging.PointTo.SetValues ((int )aTouch.To.x(), (int )aTouch.To.y());
+ }
+
+ aTouch.From = aTouch.To;
+ }
+ }
+ else if (aTouchNb == 2) // pinch
+ {
+ Aspect_Touch& aFirstTouch = myTouchPoints.ChangeFromIndex (1);
+ Aspect_Touch& aLastTouch = myTouchPoints.ChangeFromIndex (2);
+ const Graphic3d_Vec2d aFrom[2] = { aFirstTouch.From, aLastTouch.From };
+ const Graphic3d_Vec2d aTo[2] = { aFirstTouch.To, aLastTouch.To };
+
+ Graphic3d_Vec2d aPinchCenterStart ((aFrom[0].x() + aFrom[1].x()) / 2.0,
+ (aFrom[0].y() + aFrom[1].y()) / 2.0);
+
+ Standard_Real aPinchCenterXEnd = (aTo[0].x() + aTo[1].x()) / 2.0;
+ Standard_Real aPinchCenterYEnd = (aTo[0].y() + aTo[1].y()) / 2.0;
+
+ Standard_Real aPinchCenterXDev = aPinchCenterXEnd - aPinchCenterStart.x();
+ Standard_Real aPinchCenterYDev = aPinchCenterYEnd - aPinchCenterStart.y();
+
+ Standard_Real aStartSize = (aFrom[0] - aFrom[1]).Modulus();
+ Standard_Real anEndSize = ( aTo[0] - aTo[1]).Modulus();
+
+ Standard_Real aDeltaSize = anEndSize - aStartSize;
+
+ bool anIsClearDev = false;
+
+ if (myToAllowTouchZRotation)
+ {
+ Standard_Real A1 = aFrom[0].y() - aFrom[1].y();
+ Standard_Real B1 = aFrom[1].x() - aFrom[0].x();
+
+ Standard_Real A2 = aTo[0].y() - aTo[1].y();
+ Standard_Real B2 = aTo[1].x() - aTo[0].x();
+
+ Standard_Real aRotAngle = 0.0;
+
+ Standard_Real aDenomenator = A1*A2 + B1*B2;
+ if (aDenomenator <= Precision::Confusion())
+ {
+ aRotAngle = 0.0;
+ }
+ else
+ {
+ Standard_Real aNumerator = A1*B2 - A2*B1;
+ aRotAngle = ATan (aNumerator / aDenomenator);
+ }
+
+ if (Abs(aRotAngle) > Standard_Real(myTouchZRotationThreshold))
+ {
+ myGL.ZRotate.ToRotate = true;
+ myGL.ZRotate.Angle = aRotAngle;
+ anIsClearDev = true;
+ }
+ }
+
+ if (Abs(aDeltaSize) > aTolScale * myTouchZoomThresholdPx)
+ {
+ // zoom
+ aDeltaSize *= Standard_Real(myTouchZoomRatio);
+ Aspect_ScrollDelta aParams (Graphic3d_Vec2i (aPinchCenterStart), aDeltaSize);
+ myGL.ZoomActions.Append (aParams);
+ anIsClearDev = true;
+ }
+
+ const Standard_Real aPanTouchTol = !aFirstTouch.IsPreciseDevice
+ ? aTolScale * myTouchPanThresholdPx
+ : gp::Resolution();
+ if (Abs(aPinchCenterXDev) + Abs(aPinchCenterYDev) > aPanTouchTol)
+ {
+ // pan
+ if (myUpdateStartPointPan)
+ {
+ myGL.Panning.ToStart = true;
+ myGL.Panning.PointStart = Graphic3d_Vec2i (myStartPanCoord);
+ myUpdateStartPointPan = false;
+ theView->Invalidate();
+ }
+
+ myGL.Panning.ToPan = true;
+ myGL.Panning.Delta.x() = int( aPinchCenterXDev);
+ myGL.Panning.Delta.y() = int(-aPinchCenterYDev);
+ anIsClearDev = true;
+ }
+
+ if (anIsClearDev)
+ {
+ aFirstTouch.From = aFirstTouch.To;
+ aLastTouch .From = aLastTouch.To;
+ }
+ }
+}
+
+// =======================================================================
+// function : UpdateViewOrientation
+// purpose :
+// =======================================================================
+void AIS_ViewController::UpdateViewOrientation (V3d_TypeOfOrientation theOrientation,
+ bool theToFitAll)
+{
+ myUI.Orientation.ToFitAll = theToFitAll;
+ myUI.Orientation.ToSetViewOrient = true;
+ myUI.Orientation.ViewOrient = theOrientation;
+}
+
+// =======================================================================
+// function : SelectInViewer
+// purpose :
+// =======================================================================
+void AIS_ViewController::SelectInViewer (const Graphic3d_Vec2i& thePnt,
+ const bool theIsXOR)
+{
+ if (myUI.Selection.Tool != AIS_ViewSelectionTool_Picking)
+ {
+ myUI.Selection.Tool = AIS_ViewSelectionTool_Picking;
+ myUI.Selection.Points.Clear();
+ }
+
+ myUI.Selection.IsXOR = theIsXOR;
+ myUI.Selection.Points.Append (thePnt);
+}
+
+// =======================================================================
+// function : SelectInViewer
+// purpose :
+// =======================================================================
+void AIS_ViewController::SelectInViewer (const NCollection_Sequence<Graphic3d_Vec2i>& thePnts,
+ const bool theIsXOR)
+{
+ myUI.Selection.IsXOR = theIsXOR;
+ myUI.Selection.Points = thePnts;
+ myUI.Selection.ToApplyTool = true;
+ if (thePnts.Length() == 1)
+ {
+ myUI.Selection.Tool = AIS_ViewSelectionTool_Picking;
+ }
+ else if (thePnts.Length() == 2)
+ {
+ myUI.Selection.Tool = AIS_ViewSelectionTool_RubberBand;
+ }
+ else
+ {
+ myUI.Selection.Tool = AIS_ViewSelectionTool_Polygon;
+ }
+}
+
+// =======================================================================
+// function : UpdateRubberBand
+// purpose :
+// =======================================================================
+void AIS_ViewController::UpdateRubberBand (const Graphic3d_Vec2i& thePntFrom,
+ const Graphic3d_Vec2i& thePntTo,
+ const bool theIsXOR)
+{
+ myUI.Selection.Tool = AIS_ViewSelectionTool_RubberBand;
+ myUI.Selection.IsXOR = theIsXOR;
+ myUI.Selection.Points.Clear();
+ myUI.Selection.Points.Append (thePntFrom);
+ myUI.Selection.Points.Append (thePntTo);
+}
+
+// =======================================================================
+// function : UpdatePolySelection
+// purpose :
+// =======================================================================
+void AIS_ViewController::UpdatePolySelection (const Graphic3d_Vec2i& thePnt,
+ bool theToAppend)
+{
+ if (myUI.Selection.Tool != AIS_ViewSelectionTool_Polygon)
+ {
+ myUI.Selection.Tool = AIS_ViewSelectionTool_Polygon;
+ myUI.Selection.Points.Clear();
+ }
+
+ if (myUI.Selection.Points.IsEmpty())
+ {
+ myUI.Selection.Points.Append (thePnt);
+ }
+ else if (theToAppend
+ && myUI.Selection.Points.Last() != thePnt)
+ {
+ myUI.Selection.Points.Append (thePnt);
+ }
+ else
+ {
+ myUI.Selection.Points.ChangeLast() = thePnt;
+ }
+}
+
+// =======================================================================
+// function : UpdateZoom
+// purpose :
+// =======================================================================
+bool AIS_ViewController::UpdateZoom (const Aspect_ScrollDelta& theDelta)
+{
+ if (!myUI.ZoomActions.IsEmpty())
+ {
+ if (myUI.ZoomActions.ChangeLast().Point == theDelta.Point)
+ {
+ myUI.ZoomActions.ChangeLast().Delta += theDelta.Delta;
+ return false;
+ }
+ }
+
+ myUI.ZoomActions.Append (theDelta);
+ return true;
+}
+
+// =======================================================================
+// function : UpdateZRotation
+// purpose :
+// =======================================================================
+bool AIS_ViewController::UpdateZRotation (double theAngle)
+{
+ if (!ToAllowTouchZRotation())
+ {
+ return false;
+ }
+
+ myUI.ZRotate.Angle = myUI.ZRotate.ToRotate
+ ? myUI.ZRotate.Angle + theAngle
+ : theAngle;
+ if (myUI.ZRotate.ToRotate)
+ {
+ return false;
+ }
+ myUI.ZRotate.ToRotate = true;
+ return true;
+}
+
+// =======================================================================
+// function : UpdateMouseScroll
+// purpose :
+// =======================================================================
+bool AIS_ViewController::UpdateMouseScroll (const Aspect_ScrollDelta& theDelta)
+{
+ Aspect_ScrollDelta aDelta = theDelta;
+ aDelta.Delta *= myScrollZoomRatio;
+ return UpdateZoom (aDelta);
+}
+
+// =======================================================================
+// function : UpdateMouseClick
+// purpose :
+// =======================================================================
+bool AIS_ViewController::UpdateMouseClick (const Graphic3d_Vec2i& thePoint,
+ Aspect_VKeyMouse theButton,
+ Aspect_VKeyFlags theModifiers,
+ bool theIsDoubleClick)
+{
+ (void )theIsDoubleClick;
+ if (theButton == Aspect_VKeyMouse_LeftButton)
+ {
+ SelectInViewer (thePoint, (theModifiers & Aspect_VKeyFlags_SHIFT) != 0);
+ return true;
+ }
+ return false;
+}
+
+// =======================================================================
+// function : UpdateMouseButtons
+// purpose :
+// =======================================================================
+bool AIS_ViewController::UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
+ Aspect_VKeyMouse theButtons,
+ Aspect_VKeyFlags theModifiers,
+ bool theIsEmulated)
+{
+ bool toUpdateView = false;
+ const double aTolClick = (theIsEmulated ? myTouchToleranceScale : 1.0) * myMouseClickThreshold;
+ if (theButtons == Aspect_VKeyMouse_NONE
+ && myMouseSingleButton > 0)
+ {
+ const Graphic3d_Vec2i aDelta = thePoint - myMousePressPoint;
+ if (double(aDelta.cwiseAbs().maxComp()) < aTolClick)
+ {
+ ++myMouseClickCounter;
+ const bool isDoubleClick = myMouseClickCounter == 2
+ && myMouseClickTimer.IsStarted()
+ && myMouseClickTimer.ElapsedTime() <= myMouseDoubleClickInt;
+
+ myMouseClickTimer.Stop();
+ myMouseClickTimer.Reset();
+ myMouseClickTimer.Start();
+ if (isDoubleClick)
+ {
+ myMouseClickCounter = 0;
+ }
+ toUpdateView = UpdateMouseClick (thePoint, (Aspect_VKeyMouse )myMouseSingleButton, theModifiers, isDoubleClick) || toUpdateView;
+ }
+ else
+ {
+ myMouseClickTimer.Stop();
+ myMouseClickCounter = 0;
+ myUI.Dragging.ToStop = true;
+ toUpdateView = true;
+ }
+ myMouseSingleButton = -1;
+ }
+ else if (theButtons == Aspect_VKeyMouse_NONE)
+ {
+ myMouseSingleButton = -1;
+ }
+ else if (myMouseSingleButton == -1)
+ {
+ if ((theButtons & Aspect_VKeyMouse_LeftButton) == Aspect_VKeyMouse_LeftButton)
+ {
+ myMouseSingleButton = Aspect_VKeyMouse_LeftButton;
+ }
+ else if ((theButtons & Aspect_VKeyMouse_RightButton) == Aspect_VKeyMouse_RightButton)
+ {
+ myMouseSingleButton = Aspect_VKeyMouse_RightButton;
+ }
+ else if ((theButtons & Aspect_VKeyMouse_MiddleButton) == Aspect_VKeyMouse_MiddleButton)
+ {
+ myMouseSingleButton = Aspect_VKeyMouse_MiddleButton;
+ }
+ else
+ {
+ myMouseSingleButton = 0;
+ }
+ if (myMouseSingleButton != 0)
+ {
+ if (myMouseClickCounter == 1)
+ {
+ const Graphic3d_Vec2i aDelta = thePoint - myMousePressPoint;
+ if (double(aDelta.cwiseAbs().maxComp()) >= aTolClick)
+ {
+ myMouseClickTimer.Stop();
+ myMouseClickCounter = 0;
+ }
+ }
+ myMousePressPoint = thePoint;
+ }
+ }
+ else
+ {
+ myMouseSingleButton = 0;
+
+ myUI.Dragging.ToAbort = true;
+ toUpdateView = true;
+ }
+
+ const AIS_MouseGesture aPrevGesture = myMouseActiveGesture;
+ myMouseModifiers = theModifiers;
+ myMousePressed = theButtons;
+ if (theIsEmulated
+ || myNavigationMode != AIS_NavigationMode_FirstPersonWalk)
+ {
+ myMouseActiveIdleRotation = false;
+ myMouseActiveGesture = AIS_MouseGesture_NONE;
+ if (theButtons != 0)
+ {
+ myMousePressPoint = thePoint;
+ myMouseProgressPoint = myMousePressPoint;
+ }
+
+ if (myMouseGestureMap.Find (theButtons | theModifiers, myMouseActiveGesture))
+ {
+ switch (myMouseActiveGesture)
+ {
+ case AIS_MouseGesture_RotateView:
+ case AIS_MouseGesture_RotateOrbit:
+ {
+ if (myToAllowRotation)
+ {
+ myUpdateStartPointRot = true;
+ }
+ else
+ {
+ myMouseActiveGesture = AIS_MouseGesture_NONE;
+ }
+ break;
+ }
+ case AIS_MouseGesture_Pan:
+ {
+ if (myToAllowPanning)
+ {
+ myUpdateStartPointPan = true;
+ }
+ else
+ {
+ myMouseActiveGesture = AIS_MouseGesture_NONE;
+ }
+ break;
+ }
+ case AIS_MouseGesture_Zoom:
+ {
+ if (!myToAllowZooming)
+ {
+ myMouseActiveGesture = AIS_MouseGesture_NONE;
+ }
+ break;
+ }
+ case AIS_MouseGesture_SelectRectangle:
+ {
+ break;
+ }
+ case AIS_MouseGesture_SelectLasso:
+ {
+ UpdatePolySelection (thePoint, true);
+ break;
+ }
+ case AIS_MouseGesture_NONE:
+ {
+ break;
+ }
+ }
+ }
+
+ if (theButtons == Aspect_VKeyMouse_LeftButton
+ && theModifiers == Aspect_VKeyFlags_NONE
+ && myToAllowDragging)
+ {
+ myUI.Dragging.ToStart = true;
+ myUI.Dragging.PointStart = thePoint;
+ }
+ }
+
+ if (aPrevGesture != myMouseActiveGesture)
+ {
+ if (aPrevGesture == AIS_MouseGesture_SelectRectangle
+ || aPrevGesture == AIS_MouseGesture_SelectLasso)
+ {
+ myUI.Selection.ToApplyTool = true;
+ }
+
+ myUI.IsNewGesture = true;
+ toUpdateView = true;
+ }
+ return toUpdateView;
+}
+
+// =======================================================================
+// function : UpdateMousePosition
+// purpose :
+// =======================================================================
+bool AIS_ViewController::UpdateMousePosition (const Graphic3d_Vec2i& thePoint,
+ Aspect_VKeyMouse theButtons,
+ Aspect_VKeyFlags theModifiers,
+ bool theIsEmulated)
+{
+ myMousePositionLast = thePoint;
+ if (myMouseSingleButton > 0)
+ {
+ const double aTolClick = (theIsEmulated ? myTouchToleranceScale : 1.0) * myMouseClickThreshold;
+ const Graphic3d_Vec2i aPressDelta = thePoint - myMousePressPoint;
+ if (double(aPressDelta.cwiseAbs().maxComp()) >= aTolClick)
+ {
+ myMouseClickTimer.Stop();
+ myMouseClickCounter = 0;
+ myMouseSingleButton = -1;
+ }
+ }
+
+ bool toUpdateView = false;
+ Graphic3d_Vec2i aDelta = thePoint - myMouseProgressPoint;
+ if (!theIsEmulated
+ && myNavigationMode == AIS_NavigationMode_FirstPersonWalk)
+ {
+ if (!myMouseActiveIdleRotation
+ || myMouseActiveGesture != AIS_MouseGesture_RotateView)
+ {
+ myMouseActiveIdleRotation = true;
+ myMouseActiveGesture = AIS_MouseGesture_RotateView;
+ myMousePressPoint = thePoint;
+ myMouseProgressPoint = thePoint;
+ myUpdateStartPointRot = false;
+ myUI.ViewRotation.ToStart = true;
+ myUI.ViewRotation.PointStart.SetValues (thePoint.x(), thePoint.y());
+ myUI.ViewRotation.ToRotate = false;
+ aDelta.SetValues (0, 0);
+ }
+ }
+ else
+ {
+ if (myMouseActiveIdleRotation
+ && myMouseActiveGesture == AIS_MouseGesture_RotateView)
+ {
+ myMouseActiveGesture = AIS_MouseGesture_NONE;
+ }
+ myMouseActiveIdleRotation = false;
+ }
+
+ if (myMouseModifiers != theModifiers
+ && UpdateMouseButtons (thePoint, theButtons, theModifiers, theIsEmulated))
+ {
+ toUpdateView = true;
+ }
+
+ switch (myMouseActiveGesture)
+ {
+ case AIS_MouseGesture_SelectRectangle:
+ {
+ UpdateRubberBand (myMousePressPoint, thePoint);
+ toUpdateView = true;
+ break;
+ }
+ case AIS_MouseGesture_SelectLasso:
+ {
+ UpdatePolySelection (thePoint, true);
+ toUpdateView = true;
+ break;
+ }
+ case AIS_MouseGesture_RotateOrbit:
+ case AIS_MouseGesture_RotateView:
+ {
+ if (!myToAllowRotation)
+ {
+ break;
+ }
+ if (myUpdateStartPointRot)
+ {
+ if (myMouseActiveGesture == AIS_MouseGesture_RotateOrbit)
+ {
+ myUI.OrbitRotation.ToStart = true;
+ myUI.OrbitRotation.PointStart.SetValues (myMousePressPoint.x(), myMousePressPoint.y());
+ }
+ else
+ {
+ myUI.ViewRotation.ToStart = true;
+ myUI.ViewRotation.PointStart.SetValues (myMousePressPoint.x(), myMousePressPoint.y());
+ }
+ myUpdateStartPointRot = false;
+ }
+
+ const double aRotTol = theIsEmulated
+ ? double(myTouchToleranceScale) * myTouchRotationThresholdPx
+ : 0.0;
+ if (double (Abs (aDelta.x()) + Abs (aDelta.y())) > aRotTol)
+ {
+ const double aRotAccel = myNavigationMode == AIS_NavigationMode_FirstPersonWalk ? myMouseAccel : myOrbitAccel;
+ const Graphic3d_Vec2i aRotDelta = thePoint - myMousePressPoint;
+ if (myMouseActiveGesture == AIS_MouseGesture_RotateOrbit)
+ {
+ myUI.OrbitRotation.ToRotate = true;
+ myUI.OrbitRotation.PointTo = Graphic3d_Vec2d (myMousePressPoint.x(), myMousePressPoint.y())
+ + Graphic3d_Vec2d (aRotDelta.x(), aRotDelta.y()) * aRotAccel;
+ }
+ else
+ {
+ myUI.ViewRotation.ToRotate = true;
+ myUI.ViewRotation.PointTo = Graphic3d_Vec2d (myMousePressPoint.x(), myMousePressPoint.y())
+ + Graphic3d_Vec2d (aRotDelta.x(), aRotDelta.y()) * aRotAccel;
+ }
+ myUI.Dragging.PointTo = thePoint;
+
+ myMouseProgressPoint = thePoint;
+ toUpdateView = true;
+ }
+ break;
+ }
+ case AIS_MouseGesture_Zoom:
+ {
+ if (!myToAllowZooming)
+ {
+ break;
+ }
+ const double aZoomTol = theIsEmulated
+ ? double(myTouchToleranceScale) * myTouchZoomThresholdPx
+ : 0.0;
+ if (double (Abs (aDelta.x())) > aZoomTol)
+ {
+ if (UpdateZoom (Aspect_ScrollDelta (aDelta.x())))
+ {
+ toUpdateView = true;
+ }
+ myMouseProgressPoint = thePoint;
+ }
+ break;
+ }
+ case AIS_MouseGesture_Pan:
+ {
+ if (!myToAllowPanning)
+ {
+ break;
+ }
+ const double aPanTol = theIsEmulated
+ ? double(myTouchToleranceScale) * myTouchPanThresholdPx
+ : 0.0;
+ if (double (Abs (aDelta.x()) + Abs (aDelta.y())) > aPanTol)
+ {
+ if (myUpdateStartPointPan)
+ {
+ myUI.Panning.ToStart = true;
+ myUI.Panning.PointStart.SetValues (myMousePressPoint.x(), myMousePressPoint.y());
+ myUpdateStartPointPan = false;
+ }
+
+ aDelta.y() = -aDelta.y();
+ myMouseProgressPoint = thePoint;
+ if (myUI.Panning.ToPan)
+ {
+ myUI.Panning.Delta += aDelta;
+ }
+ else
+ {
+ myUI.Panning.ToPan = true;
+ myUI.Panning.Delta = aDelta;
+ }
+ toUpdateView = true;
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ if (theButtons == Aspect_VKeyMouse_NONE
+ && myNavigationMode != AIS_NavigationMode_FirstPersonWalk
+ && !theIsEmulated
+ && !HasTouchPoints()
+ && myToAllowHighlight)
+ {
+ myUI.MoveTo.ToHilight = true;
+ myUI.MoveTo.Point = thePoint;
+ toUpdateView = true;
+ }
+ return toUpdateView;
+}
+
+// =======================================================================
+// function : AddTouchPoint
+// purpose :
+// =======================================================================
+void AIS_ViewController::AddTouchPoint (Standard_Size theId,
+ const Graphic3d_Vec2d& thePnt,
+ Standard_Boolean theClearBefore)
+{
+ myUI.MoveTo.ToHilight = false;
+ if (theClearBefore)
+ {
+ RemoveTouchPoint ((Standard_Size )-1);
+ }
+
+ myTouchPoints.Add (theId, Aspect_Touch (thePnt, false));
+ if (myTouchPoints.Extent() == 1)
+ {
+ myUpdateStartPointRot = true;
+ myStartRotCoord = thePnt;
+ if (myToAllowDragging)
+ {
+ myUI.Dragging.ToStart = true;
+ myUI.Dragging.PointStart.SetValues ((int )thePnt.x(), (int )thePnt.y());
+ }
+ }
+ else if (myTouchPoints.Extent() == 2)
+ {
+ myUI.Dragging.ToAbort = true;
+
+ myUpdateStartPointPan = true;
+ myStartPanCoord = thePnt;
+ }
+ myUI.IsNewGesture = true;
+}
+
+// =======================================================================
+// function : RemoveTouchPoint
+// purpose :
+// =======================================================================
+bool AIS_ViewController::RemoveTouchPoint (Standard_Size theId,
+ Standard_Boolean theClearSelectPnts)
+{
+ if (theId == (Standard_Size )-1)
+ {
+ myTouchPoints.Clear (false);
+ }
+ else
+ {
+ const Standard_Integer anOldExtent = myTouchPoints.Extent();
+ myTouchPoints.RemoveKey (theId);
+ if (myTouchPoints.Extent() == anOldExtent)
+ {
+ return false;
+ }
+ }
+
+ if (myTouchPoints.Extent() == 1)
+ {
+ // avoid incorrect transition from pinch to one finger
+ Aspect_Touch& aFirstTouch = myTouchPoints.ChangeFromIndex (1);
+ aFirstTouch.To = aFirstTouch.From;
+
+ myStartRotCoord = aFirstTouch.To;
+ myUpdateStartPointRot = true;
+ }
+ else if (myTouchPoints.Extent() == 2)
+ {
+ myStartPanCoord = myTouchPoints.FindFromIndex (1).To;
+ myUpdateStartPointPan = true;
+ }
+ else if (myTouchPoints.IsEmpty())
+ {
+ if (theClearSelectPnts)
+ {
+ myUI.Selection.ToApplyTool = true;
+ }
+
+ myUI.Dragging.ToStop = true;
+ }
+ myUI.IsNewGesture = true;
+ return true;
+}
+
+// =======================================================================
+// function : UpdateTouchPoint
+// purpose :
+// =======================================================================
+void AIS_ViewController::UpdateTouchPoint (Standard_Size theId,
+ const Graphic3d_Vec2d& thePnt)
+{
+ if (Aspect_Touch* aTouch = myTouchPoints.ChangeSeek (theId))
+ {
+ aTouch->To = thePnt;
+ }
+ else
+ {
+ AddTouchPoint (theId, thePnt);
+ }
+}
+
+// =======================================================================
+// function : SetNavigationMode
+// purpose :
+// =======================================================================
+void AIS_ViewController::SetNavigationMode (AIS_NavigationMode theMode)
+{
+ myNavigationMode = theMode;
+
+ // abort rotation
+ myUI.OrbitRotation.ToStart = false;
+ myUI.OrbitRotation.ToRotate = false;
+ myUI.ViewRotation.ToStart = false;
+ myUI.ViewRotation.ToRotate = false;
+}
+
+// =======================================================================
+// function : KeyDown
+// purpose :
+// =======================================================================
+void AIS_ViewController::KeyDown (Aspect_VKey theKey,
+ double theTime,
+ double thePressure)
+{
+ myKeys.KeyDown (theKey, theTime, thePressure);
+}
+
+// =======================================================================
+// function : KeyUp
+// purpose :
+// =======================================================================
+void AIS_ViewController::KeyUp (Aspect_VKey theKey,
+ double theTime)
+{
+ myKeys.KeyUp (theKey, theTime);
+}
+
+// =======================================================================
+// function : KeyFromAxis
+// purpose :
+// =======================================================================
+void AIS_ViewController::KeyFromAxis (Aspect_VKey theNegative,
+ Aspect_VKey thePositive,
+ double theTime,
+ double thePressure)
+{
+ myKeys.KeyFromAxis (theNegative, thePositive, theTime, thePressure);
+}
+
+// =======================================================================
+// function : FetchNavigationKeys
+// purpose :
+// =======================================================================
+AIS_WalkDelta AIS_ViewController::FetchNavigationKeys (Standard_Real theCrouchRatio,
+ Standard_Real theRunRatio)
+{
+ AIS_WalkDelta aWalk;
+
+ // navigation keys
+ double aPrevEventTime = 0.0, aNewEventTime = 0.0;
+ updateEventsTime (aPrevEventTime, aNewEventTime);
+
+ double aDuration = 0.0, aPressure = 1.0;
+ if (Abs (myThrustSpeed) > gp::Resolution())
+ {
+ if (myHasThrust)
+ {
+ aWalk[AIS_WalkTranslation_Forward].Value = myThrustSpeed * (aNewEventTime - aPrevEventTime);
+ }
+ myHasThrust = true;
+ myToAskNextFrame = true;
+ }
+ else
+ {
+ myHasThrust = false;
+ }
+
+ aWalk.SetRunning (theRunRatio > 1.0
+ && myKeys.IsKeyDown (Aspect_VKey_Shift));
+ if (myKeys.HoldDuration (Aspect_VKey_NavJump, aNewEventTime, aDuration))
+ {
+ myKeys.KeyUp (Aspect_VKey_NavJump, aNewEventTime);
+ aWalk.SetJumping (true);
+ }
+ if (!aWalk.IsJumping()
+ && theCrouchRatio < 1.0
+ && myKeys.HoldDuration (Aspect_VKey_NavCrouch, aNewEventTime, aDuration))
+ {
+ aWalk.SetRunning (false);
+ aWalk.SetCrouching (true);
+ }
+
+ const double aMaxDuration = aNewEventTime - aPrevEventTime;
+ const double aRunRatio = aWalk.IsRunning()
+ ? theRunRatio
+ : aWalk.IsCrouching()
+ ? theCrouchRatio
+ : 1.0;
+ if (myKeys.HoldDuration (Aspect_VKey_NavForward, aNewEventTime, aDuration, aPressure))
+ {
+ double aProgress = Abs (Min (aMaxDuration, aDuration));
+ aProgress *= aRunRatio;
+ aWalk[AIS_WalkTranslation_Forward].Value += aProgress;
+ aWalk[AIS_WalkTranslation_Forward].Pressure = aPressure;
+ aWalk[AIS_WalkTranslation_Forward].Duration = aDuration;
+ }
+ if (myKeys.HoldDuration (Aspect_VKey_NavBackward, aNewEventTime, aDuration, aPressure))
+ {
+ double aProgress = Abs (Min (aMaxDuration, aDuration));
+ aProgress *= aRunRatio;
+ aWalk[AIS_WalkTranslation_Forward].Value += -aProgress;
+ aWalk[AIS_WalkTranslation_Forward].Pressure = aPressure;
+ aWalk[AIS_WalkTranslation_Forward].Duration = aDuration;
+ }
+ if (myKeys.HoldDuration (Aspect_VKey_NavSlideLeft, aNewEventTime, aDuration, aPressure))
+ {
+ double aProgress = Abs (Min (aMaxDuration, aDuration));
+ aProgress *= aRunRatio;
+ aWalk[AIS_WalkTranslation_Side].Value = -aProgress;
+ aWalk[AIS_WalkTranslation_Side].Pressure = aPressure;
+ aWalk[AIS_WalkTranslation_Side].Duration = aDuration;
+ }
+ if (myKeys.HoldDuration (Aspect_VKey_NavSlideRight, aNewEventTime, aDuration, aPressure))
+ {
+ double aProgress = Abs (Min (aMaxDuration, aDuration));
+ aProgress *= aRunRatio;
+ aWalk[AIS_WalkTranslation_Side].Value = aProgress;
+ aWalk[AIS_WalkTranslation_Side].Pressure = aPressure;
+ aWalk[AIS_WalkTranslation_Side].Duration = aDuration;
+ }
+ if (myKeys.HoldDuration (Aspect_VKey_NavLookLeft, aNewEventTime, aDuration, aPressure))
+ {
+ double aProgress = Abs (Min (aMaxDuration, aDuration)) * aPressure;
+ aWalk[AIS_WalkRotation_Yaw].Value = aProgress;
+ aWalk[AIS_WalkRotation_Yaw].Pressure = aPressure;
+ aWalk[AIS_WalkRotation_Yaw].Duration = aDuration;
+ }
+ if (myKeys.HoldDuration (Aspect_VKey_NavLookRight, aNewEventTime, aDuration, aPressure))
+ {
+ double aProgress = Abs (Min (aMaxDuration, aDuration)) * aPressure;
+ aWalk[AIS_WalkRotation_Yaw].Value = -aProgress;
+ aWalk[AIS_WalkRotation_Yaw].Pressure = aPressure;
+ aWalk[AIS_WalkRotation_Yaw].Duration = aDuration;
+ }
+ if (myKeys.HoldDuration (Aspect_VKey_NavLookUp, aNewEventTime, aDuration, aPressure))
+ {
+ double aProgress = Abs (Min (aMaxDuration, aDuration)) * aPressure;
+ aWalk[AIS_WalkRotation_Pitch].Value = !myToInvertPitch ? -aProgress : aProgress;
+ aWalk[AIS_WalkRotation_Pitch].Pressure = aPressure;
+ aWalk[AIS_WalkRotation_Pitch].Duration = aDuration;
+ }
+ if (myKeys.HoldDuration (Aspect_VKey_NavLookDown, aNewEventTime, aDuration, aPressure))
+ {
+ double aProgress = Abs (Min (aMaxDuration, aDuration)) * aPressure;
+ aWalk[AIS_WalkRotation_Pitch].Value = !myToInvertPitch ? aProgress : -aProgress;
+ aWalk[AIS_WalkRotation_Pitch].Pressure = aPressure;
+ aWalk[AIS_WalkRotation_Pitch].Duration = aDuration;
+ }
+ if (myKeys.HoldDuration (Aspect_VKey_NavRollCCW, aNewEventTime, aDuration, aPressure))
+ {
+ double aProgress = Abs (Min (aMaxDuration, aDuration)) * aPressure;
+ aWalk[AIS_WalkRotation_Roll].Value = -aProgress;
+ aWalk[AIS_WalkRotation_Roll].Pressure = aPressure;
+ aWalk[AIS_WalkRotation_Roll].Duration = aDuration;
+ }
+ if (myKeys.HoldDuration (Aspect_VKey_NavRollCW, aNewEventTime, aDuration, aPressure))
+ {
+ double aProgress = Abs (Min (aMaxDuration, aDuration)) * aPressure;
+ aWalk[AIS_WalkRotation_Roll].Value = aProgress;
+ aWalk[AIS_WalkRotation_Roll].Pressure = aPressure;
+ aWalk[AIS_WalkRotation_Roll].Duration = aDuration;
+ }
+ if (myKeys.HoldDuration (Aspect_VKey_NavSlideUp, aNewEventTime, aDuration, aPressure))
+ {
+ double aProgress = Abs (Min (aMaxDuration, aDuration));
+ aWalk[AIS_WalkTranslation_Up].Value = aProgress;
+ aWalk[AIS_WalkTranslation_Up].Pressure = aPressure;
+ aWalk[AIS_WalkTranslation_Up].Duration = aDuration;
+ }
+ if (myKeys.HoldDuration (Aspect_VKey_NavSlideDown, aNewEventTime, aDuration, aPressure))
+ {
+ double aProgress = Abs (Min (aMaxDuration, aDuration));
+ aWalk[AIS_WalkTranslation_Up].Value = -aProgress;
+ aWalk[AIS_WalkTranslation_Up].Pressure = aPressure;
+ aWalk[AIS_WalkTranslation_Up].Duration = aDuration;
+ }
+ return aWalk;
+}
+
+// =======================================================================
+// function : handlePanning
+// purpose :
+// =======================================================================
+void AIS_ViewController::handlePanning (const Handle(V3d_View)& theView)
+{
+ if (!myGL.Panning.ToPan
+ || !myToAllowPanning)
+ {
+ return;
+ }
+
+ const Handle(Graphic3d_Camera)& aCam = theView->Camera();
+ if (aCam->IsOrthographic()
+ || !hasPanningAnchorPoint())
+ {
+ theView->Pan (myGL.Panning.Delta.x(), myGL.Panning.Delta.y());
+ theView->Invalidate();
+ return;
+ }
+
+ Graphic3d_Vec2i aWinSize;
+ theView->Window()->Size (aWinSize.x(), aWinSize.y());
+
+ const gp_Dir& aDir = aCam->Direction();
+ const gp_Ax3 aCameraCS (aCam->Center(), aDir.Reversed(), aDir ^ aCam->Up());
+ const gp_XYZ anEyeToPnt = myPanPnt3d.XYZ() - aCam->Eye().XYZ();
+ const gp_Pnt aViewDims = aCam->ViewDimensions (anEyeToPnt.Dot (aCam->Direction().XYZ())); // view dimensions at 3D point
+ const Graphic3d_Vec2d aDxy (-aViewDims.X() * myGL.Panning.Delta.x() / double(aWinSize.x()),
+ -aViewDims.X() * myGL.Panning.Delta.y() / double(aWinSize.x()));
+
+ //theView->Translate (aCam, aDxy.x(), aDxy.y());
+ gp_Trsf aPanTrsf;
+ const gp_Vec aCameraPan = gp_Vec (aCameraCS.XDirection()) * aDxy.x()
+ + gp_Vec (aCameraCS.YDirection()) * aDxy.y();
+ aPanTrsf.SetTranslation (aCameraPan);
+ aCam->Transform (aPanTrsf);
+ theView->Invalidate();
+}
+
+// =======================================================================
+// function : handleZRotate
+// purpose :
+// =======================================================================
+void AIS_ViewController::handleZRotate (const Handle(V3d_View)& theView)
+{
+ if (!myGL.ZRotate.ToRotate
+ || !myToAllowRotation)
+ {
+ return;
+ }
+
+ Graphic3d_Vec2i aViewPort;
+ theView->Window()->Size (aViewPort.x(), aViewPort.y());
+ Graphic3d_Vec2d aRotPnt (0.99 * aViewPort.x(),
+ 0.5 * aViewPort.y());
+ theView->StartRotation (int(aRotPnt.x()), int(aRotPnt.y()), 0.4);
+ aRotPnt.y() += myGL.ZRotate.Angle * aViewPort.y();
+ theView->Rotation (int(aRotPnt.x()), int(aRotPnt.y()));
+ theView->Invalidate();
+}
+
+// =======================================================================
+// function : handleZoom
+// purpose :
+// =======================================================================
+void AIS_ViewController::handleZoom (const Handle(V3d_View)& theView,
+ const Aspect_ScrollDelta& theParams,
+ const gp_Pnt* thePnt)
+{
+ if (!myToAllowZooming)
+ {
+ return;
+ }
+
+ const Handle(Graphic3d_Camera)& aCam = theView->Camera();
+ if (thePnt != NULL)
+ {
+ const double aViewDist = Max (myMinCamDistance, (thePnt->XYZ() - aCam->Eye().XYZ()).Modulus());
+ aCam->SetCenter (aCam->Eye().XYZ() + aCam->Direction().XYZ() * aViewDist);
+ }
+
+ if (!theParams.HasPoint())
+ {
+ Standard_Real aCoeff = Abs(theParams.Delta) / 100.0 + 1.0;
+ aCoeff = theParams.Delta > 0.0 ? aCoeff : 1.0 / aCoeff;
+ theView->SetZoom (aCoeff, true);
+ theView->Invalidate();
+ return;
+ }
+
+ // integer delta is too rough for small smooth increments
+ //theView->StartZoomAtPoint (theParams.Point.x(), theParams.Point.y());
+ //theView->ZoomAtPoint (0, 0, (int )theParams.Delta, (int )theParams.Delta);
+
+ double aDZoom = Abs (theParams.Delta) / 100.0 + 1.0;
+ aDZoom = (theParams.Delta > 0.0) ? aDZoom : 1.0 / aDZoom;
+ if (aDZoom <= 0.0)
+ {
+ return;
+ }
+
+ const Graphic3d_Vec2d aViewDims (aCam->ViewDimensions().X(), aCam->ViewDimensions().Y());
+
+ // ensure that zoom will not be too small or too big
+ double aCoef = aDZoom;
+ if (aViewDims.x() < aCoef * Precision::Confusion())
+ {
+ aCoef = aViewDims.x() / Precision::Confusion();
+ }
+ else if (aViewDims.x() > aCoef * 1e12)
+ {
+ aCoef = aViewDims.x() / 1e12;
+ }
+ if (aViewDims.y() < aCoef * Precision::Confusion())
+ {
+ aCoef = aViewDims.y() / Precision::Confusion();
+ }
+ else if (aViewDims.y() > aCoef * 1e12)
+ {
+ aCoef = aViewDims.y() / 1e12;
+ }
+
+ Graphic3d_Vec2d aZoomAtPointXYv (0.0, 0.0);
+ theView->Convert (theParams.Point.x(), theParams.Point.y(),
+ aZoomAtPointXYv.x(), aZoomAtPointXYv.y());
+ Graphic3d_Vec2d aDxy = aZoomAtPointXYv / aCoef;
+ aCam->SetScale (aCam->Scale() / aCoef);
+
+ const gp_Dir& aDir = aCam->Direction();
+ const gp_Ax3 aCameraCS (aCam->Center(), aDir.Reversed(), aDir ^ aCam->Up());
+
+ // pan back to the point
+ aDxy = aZoomAtPointXYv - aDxy;
+ if (thePnt != NULL)
+ {
+ // zoom at 3D point with perspective projection
+ const gp_XYZ anEyeToPnt = thePnt->XYZ() - aCam->Eye().XYZ();
+ aDxy.SetValues (anEyeToPnt.Dot (aCameraCS.XDirection().XYZ()),
+ anEyeToPnt.Dot (aCameraCS.YDirection().XYZ()));
+
+ // view dimensions at 3D point
+ const gp_Pnt aViewDims1 = aCam->ViewDimensions (anEyeToPnt.Dot (aCam->Direction().XYZ()));
+
+ Graphic3d_Vec2i aWinSize;
+ theView->Window()->Size (aWinSize.x(), aWinSize.y());
+ const Graphic3d_Vec2d aPanFromCenterPx (double(theParams.Point.x()) - 0.5 * double(aWinSize.x()),
+ double(theParams.Point.y()) - 0.5 * double(aWinSize.y()));
+ aDxy.x() += -aViewDims1.X() * aPanFromCenterPx.x() / double(aWinSize.x());
+ aDxy.y() += aViewDims1.X() * aPanFromCenterPx.y() / double(aWinSize.x());
+ }
+
+ //theView->Translate (aCam, aDxy.x(), aDxy.y());
+ gp_Trsf aPanTrsf;
+ const gp_Vec aCameraPan = gp_Vec (aCameraCS.XDirection()) * aDxy.x()
+ + gp_Vec (aCameraCS.YDirection()) * aDxy.y();
+ aPanTrsf.SetTranslation (aCameraPan);
+ aCam->Transform (aPanTrsf);
+ theView->Invalidate();
+}
+
+// =======================================================================
+// function : handleZFocusScroll
+// purpose :
+// =======================================================================
+void AIS_ViewController::handleZFocusScroll (const Handle(V3d_View)& theView,
+ const Aspect_ScrollDelta& theParams)
+{
+ if (!myToAllowZFocus
+ || !theView->Camera()->IsStereo())
+ {
+ return;
+ }
+
+ Standard_Real aFocus = theView->Camera()->ZFocus() + (theParams.Delta > 0.0 ? 0.05 : -0.05);
+ if (aFocus > 0.2
+ && aFocus < 2.0)
+ {
+ theView->Camera()->SetZFocus (theView->Camera()->ZFocusType(), aFocus);
+ theView->Redraw();
+ }
+}
+
+// =======================================================================
+// function : handleOrbitRotation
+// purpose :
+// =======================================================================
+void AIS_ViewController::handleOrbitRotation (const Handle(V3d_View)& theView,
+ const gp_Pnt& thePnt,
+ bool theToLockZUp)
+{
+ if (!myToAllowRotation)
+ {
+ return;
+ }
+
+ const Handle(Graphic3d_Camera)& aCam = theView->Camera();
+ if (myGL.OrbitRotation.ToStart)
+ {
+ // default alternatives
+ //if (myRotationMode == AIS_RotationMode_BndBoxActive) theView->StartRotation (myGL.RotateAtPoint.x(), myGL.RotateAtPoint.y());
+ //theView->Rotate (0.0, 0.0, 0.0, thePnt.X(), thePnt.Y(), thePnt.Z(), true);
+
+ myRotatePnt3d = thePnt;
+ myCamStartOpUp = aCam->Up();
+ myCamStartOpEye = aCam->Eye();
+ myCamStartOpCenter = aCam->Center();
+
+ gp_Trsf aTrsf;
+ aTrsf.SetTransformation (gp_Ax3 (myRotatePnt3d, aCam->OrthogonalizedUp(), aCam->Direction()),
+ gp_Ax3 (myRotatePnt3d, gp::DZ(), gp::DX()));
+ const gp_Quaternion aRot = aTrsf.GetRotation();
+ aRot.GetEulerAngles (gp_YawPitchRoll, myRotateStartYawPitchRoll[0], myRotateStartYawPitchRoll[1], myRotateStartYawPitchRoll[2]);
+
+ aTrsf.Invert();
+ myCamStartOpToEye = gp_Vec (myRotatePnt3d, aCam->Eye()).Transformed (aTrsf);
+ myCamStartOpToCenter = gp_Vec (myRotatePnt3d, aCam->Center()).Transformed (aTrsf);
+
+ theView->Invalidate();
+ }
+
+ if (!myGL.OrbitRotation.ToRotate)
+ {
+ return;
+ }
+
+ if (theToLockZUp)
+ {
+ // amend camera to exclude roll angle (put camera Up vector to plane containing global Z and view direction)
+ Graphic3d_Vec2i aWinXY;
+ theView->Window()->Size (aWinXY.x(), aWinXY.y());
+ double aYawAngleDelta = ((myGL.OrbitRotation.PointStart.x() - myGL.OrbitRotation.PointTo.x()) / double (aWinXY.x())) * (M_PI * 0.5);
+ double aPitchAngleDelta = -((myGL.OrbitRotation.PointStart.y() - myGL.OrbitRotation.PointTo.y()) / double (aWinXY.y())) * (M_PI * 0.5);
+ const double aPitchAngleNew = Max (Min (myRotateStartYawPitchRoll[1] + aPitchAngleDelta, M_PI * 0.5 - M_PI / 180.0), -M_PI * 0.5 + M_PI / 180.0);
+ const double aYawAngleNew = myRotateStartYawPitchRoll[0] + aYawAngleDelta;
+ const double aRoll = 0.0;
+
+ gp_Quaternion aRot;
+ aRot.SetEulerAngles (gp_YawPitchRoll, aYawAngleNew, aPitchAngleNew, aRoll);
+ gp_Trsf aTrsfRot;
+ aTrsfRot.SetRotation (aRot);
+
+ const gp_Dir aNewUp = gp::DZ().Transformed (aTrsfRot);
+ aCam->SetUp (aNewUp);
+ aCam->SetCenter(myRotatePnt3d.XYZ() + myCamStartOpToCenter.Transformed (aTrsfRot).XYZ());
+ aCam->SetEye (myRotatePnt3d.XYZ() + myCamStartOpToEye .Transformed (aTrsfRot).XYZ());
+ aCam->OrthogonalizeUp();
+ }
+ else
+ {
+ // default alternatives
+ //if (myRotationMode == AIS_RotationMode_BndBoxActive) theView->Rotation (myGL.RotateToPoint.x(), myGL.RotateToPoint.y());
+ //theView->Rotate (aDX, aDY, aDZ, myRotatePnt3d.X(), myRotatePnt3d.Y(), myRotatePnt3d.Z(), false);
+
+ // restore previous camera state
+ aCam->SetUp (myCamStartOpUp);
+ aCam->SetEye (myCamStartOpEye);
+ aCam->SetCenter (myCamStartOpCenter);
+
+ Graphic3d_Vec2d aWinXY;
+ theView->Size (aWinXY.x(), aWinXY.y());
+ const Standard_Real rx = (Standard_Real )theView->Convert (aWinXY.x());
+ const Standard_Real ry = (Standard_Real )theView->Convert (aWinXY.y());
+
+ const double THE_2PI = M_PI * 2.0;
+ double aDX = (myGL.OrbitRotation.PointTo.x() - myGL.OrbitRotation.PointStart.x()) * M_PI / rx;
+ double aDY = (myGL.OrbitRotation.PointStart.y() - myGL.OrbitRotation.PointTo.y()) * M_PI / ry;
+
+ if (aDX > 0.0) { while (aDX > THE_2PI) { aDX -= THE_2PI; } }
+ else if(aDX < 0.0) { while (aDX < -THE_2PI) { aDX += THE_2PI; } }
+ if (aDY > 0.0) { while (aDY > THE_2PI) { aDY -= THE_2PI; } }
+ else if(aDY < 0.0) { while (aDY < -THE_2PI) { aDY += THE_2PI; } }
+
+ // rotate camera around 3 initial axes
+ gp_Dir aCamDir (aCam->Direction().Reversed());
+ gp_Dir aCamUp (aCam->Up());
+ gp_Dir aCamSide(aCamUp.Crossed (aCamDir));
+
+ gp_Trsf aRot[2], aTrsf;
+ aRot[0].SetRotation (gp_Ax1 (myRotatePnt3d, aCamUp), -aDX);
+ aRot[1].SetRotation (gp_Ax1 (myRotatePnt3d, aCamSide), aDY);
+ aTrsf.Multiply (aRot[0]);
+ aTrsf.Multiply (aRot[1]);
+
+ aCam->Transform (aTrsf);
+ }
+
+ theView->Invalidate();
+}
+
+// =======================================================================
+// function : handleViewRotation
+// purpose :
+// =======================================================================
+void AIS_ViewController::handleViewRotation (const Handle(V3d_View)& theView,
+ double theYawExtra,
+ double thePitchExtra,
+ double theRoll,
+ bool theToRestartOnIncrement)
+{
+ if (!myToAllowRotation)
+ {
+ return;
+ }
+
+ const Handle(Graphic3d_Camera)& aCam = theView->Camera();
+ const bool toRotateAnyway = Abs (theYawExtra) > gp::Resolution()
+ || Abs (thePitchExtra) > gp::Resolution()
+ || Abs (theRoll - myRotateStartYawPitchRoll[2]) > gp::Resolution();
+ if (toRotateAnyway
+ && theToRestartOnIncrement)
+ {
+ myGL.ViewRotation.ToStart = true;
+ myGL.ViewRotation.PointTo = myGL.ViewRotation.PointStart;
+ }
+ if (myGL.ViewRotation.ToStart)
+ {
+ gp_Trsf aTrsf;
+ aTrsf.SetTransformation (gp_Ax3 (gp::Origin(), aCam->OrthogonalizedUp(), aCam->Direction()),
+ gp_Ax3 (gp::Origin(), gp::DZ(), gp::DX()));
+ const gp_Quaternion aRot = aTrsf.GetRotation();
+ double aRollDummy = 0.0;
+ aRot.GetEulerAngles (gp_YawPitchRoll, myRotateStartYawPitchRoll[0], myRotateStartYawPitchRoll[1], aRollDummy);
+ }
+ if (toRotateAnyway)
+ {
+ myRotateStartYawPitchRoll[0] += theYawExtra;
+ myRotateStartYawPitchRoll[1] += thePitchExtra;
+ myRotateStartYawPitchRoll[2] = theRoll;
+ myGL.ViewRotation.ToRotate = true;
+ }
+
+ if (!myGL.ViewRotation.ToRotate)
+ {
+ return;
+ }
+
+ Graphic3d_Vec2i aWinXY;
+ theView->Window()->Size (aWinXY.x(), aWinXY.y());
+ double aYawAngleDelta = ((myGL.ViewRotation.PointStart.x() - myGL.ViewRotation.PointTo.x()) / double (aWinXY.x())) * (M_PI * 0.5);
+ double aPitchAngleDelta = -((myGL.ViewRotation.PointStart.y() - myGL.ViewRotation.PointTo.y()) / double (aWinXY.y())) * (M_PI * 0.5);
+ const double aPitchAngleNew = Max (Min (myRotateStartYawPitchRoll[1] + aPitchAngleDelta, M_PI * 0.5 - M_PI / 180.0), -M_PI * 0.5 + M_PI / 180.0);
+ const double aYawAngleNew = myRotateStartYawPitchRoll[0] + aYawAngleDelta;
+ gp_Quaternion aRot;
+ aRot.SetEulerAngles (gp_YawPitchRoll, aYawAngleNew, aPitchAngleNew, theRoll);
+ gp_Trsf aTrsfRot;
+ aTrsfRot.SetRotation (aRot);
+
+ const double aDist = aCam->Distance();
+ const gp_Dir aNewUp = gp::DZ().Transformed (aTrsfRot);
+ const gp_Dir aNewDir = gp::DX().Transformed (aTrsfRot);
+ aCam->SetUp (aNewUp);
+ aCam->SetCenter (aCam->Eye().Translated (gp_Vec (aNewDir) * aDist));
+ aCam->OrthogonalizeUp();
+ theView->Invalidate();
+}
+
+// =======================================================================
+// function : PickPoint
+// purpose :
+// =======================================================================
+bool AIS_ViewController::PickPoint (gp_Pnt& thePnt,
+ const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView,
+ const Graphic3d_Vec2i& theCursor,
+ bool theToStickToPickRay)
+{
+ ResetPreviousMoveTo();
+
+ const Handle(StdSelect_ViewerSelector3d)& aSelector = theCtx->MainSelector();
+ aSelector->Pick (theCursor.x(), theCursor.y(), theView);
+ if (aSelector->NbPicked() < 1)
+ {
+ return false;
+ }
+
+ const SelectMgr_SortCriterion& aPicked = aSelector->PickedData (1);
+ if (theToStickToPickRay
+ && !Precision::IsInfinite (aPicked.Depth))
+ {
+ thePnt = aSelector->GetManager().DetectedPoint (aPicked.Depth);
+ }
+ else
+ {
+ thePnt = aSelector->PickedPoint (1);
+ }
+ return !Precision::IsInfinite (thePnt.X())
+ && !Precision::IsInfinite (thePnt.Y())
+ && !Precision::IsInfinite (thePnt.Z());
+}
+
+// =======================================================================
+// function : GravityPoint
+// purpose :
+// =======================================================================
+gp_Pnt AIS_ViewController::GravityPoint (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView)
+{
+ switch (myRotationMode)
+ {
+ case AIS_RotationMode_PickLast:
+ case AIS_RotationMode_PickCenter:
+ {
+ Graphic3d_Vec2i aCursor ((int )myGL.OrbitRotation.PointStart.x(), (int )myGL.OrbitRotation.PointStart.y());
+ if (myRotationMode == AIS_RotationMode_PickCenter)
+ {
+ Graphic3d_Vec2i aViewPort;
+ theView->Window()->Size (aViewPort.x(), aViewPort.y());
+ aCursor = aViewPort / 2;
+ }
+
+ gp_Pnt aPnt;
+ if (PickPoint (aPnt, theCtx, theView, aCursor, false))
+ {
+ return aPnt;
+ }
+ break;
+ }
+ case AIS_RotationMode_CameraAt:
+ {
+ const Handle(Graphic3d_Camera)& aCam = theView->Camera();
+ return aCam->Center();
+ }
+ case AIS_RotationMode_BndBoxScene:
+ {
+ Bnd_Box aBndBox = theView->View()->MinMaxValues (false);
+ if (!aBndBox.IsVoid())
+ {
+ return (aBndBox.CornerMin().XYZ() + aBndBox.CornerMax().XYZ()) * 0.5;
+ }
+ break;
+ }
+ case AIS_RotationMode_BndBoxActive:
+ break;
+ }
+
+ return theCtx ->GravityPoint (theView);
+}
+
+// =======================================================================
+// function : handleCameraActions
+// purpose :
+// =======================================================================
+void AIS_ViewController::handleCameraActions (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView,
+ const AIS_WalkDelta& theWalk)
+{
+ // apply view actions
+ if (myGL.Orientation.ToSetViewOrient)
+ {
+ theView->SetProj (myGL.Orientation.ViewOrient);
+ myGL.Orientation.ToFitAll = true;
+ }
+
+ // apply fit all
+ if (myGL.Orientation.ToFitAll)
+ {
+ const double aFitMargin = 0.01;
+ theView->FitAll (aFitMargin, false);
+ theView->Invalidate();
+ myGL.Orientation.ToFitAll = false;
+ }
+
+ if (myGL.IsNewGesture)
+ {
+ if (myAnchorPointPrs1->HasInteractiveContext())
+ {
+ theCtx->Remove (myAnchorPointPrs1, false);
+ if (!theView->Viewer()->ZLayerSettings (myAnchorPointPrs1->ZLayer()).IsImmediate())
+ {
+ theView->Invalidate();
+ }
+ else
+ {
+ theView->InvalidateImmediate();
+ }
+ }
+ if (myAnchorPointPrs2->HasInteractiveContext())
+ {
+ theCtx->Remove (myAnchorPointPrs2, false);
+ if (!theView->Viewer()->ZLayerSettings (myAnchorPointPrs2->ZLayer()).IsImmediate())
+ {
+ theView->Invalidate();
+ }
+ else
+ {
+ theView->InvalidateImmediate();
+ }
+ }
+
+ if (myHasHlrOnBeforeRotation)
+ {
+ myHasHlrOnBeforeRotation = false;
+ theView->SetComputedMode (true);
+ theView->Invalidate();
+ }
+ }
+
+ if (myNavigationMode != AIS_NavigationMode_FirstPersonWalk)
+ {
+ if (myGL.Panning.ToStart
+ && myToAllowPanning)
+ {
+ gp_Pnt aPanPnt (Precision::Infinite(), 0.0, 0.0);
+ if (!theView->Camera()->IsOrthographic())
+ {
+ bool toStickToRay = false;
+ if (myGL.Panning.PointStart.x() >= 0
+ && myGL.Panning.PointStart.y() >= 0)
+ {
+ PickPoint (aPanPnt, theCtx, theView, myGL.Panning.PointStart, toStickToRay);
+ }
+ if (Precision::IsInfinite (aPanPnt.X()))
+ {
+ Graphic3d_Vec2i aWinSize;
+ theView->Window()->Size (aWinSize.x(), aWinSize.y());
+ PickPoint (aPanPnt, theCtx, theView, aWinSize / 2, toStickToRay);
+ }
+ if (!Precision::IsInfinite (aPanPnt.X())
+ && myToShowPanAnchorPoint)
+ {
+ gp_Trsf aPntTrsf;
+ aPntTrsf.SetTranslation (gp_Vec (aPanPnt.XYZ()));
+ theCtx->SetLocation (myAnchorPointPrs2, aPntTrsf);
+ }
+ }
+ setPanningAnchorPoint (aPanPnt);
+ }
+
+ if (myToShowPanAnchorPoint
+ && hasPanningAnchorPoint()
+ && myGL.Panning.ToPan
+ && !myGL.IsNewGesture
+ && !myAnchorPointPrs2->HasInteractiveContext())
+ {
+ theCtx->Display (myAnchorPointPrs2, 0, -1, false, AIS_DS_Displayed);
+ }
+
+ handlePanning (theView);
+ handleZRotate (theView);
+ }
+
+ if ((myNavigationMode == AIS_NavigationMode_Orbit
+ || myGL.OrbitRotation.ToStart
+ || myGL.OrbitRotation.ToRotate)
+ && myToAllowRotation)
+ {
+ if (myGL.OrbitRotation.ToStart
+ && !myHasHlrOnBeforeRotation)
+ {
+ myHasHlrOnBeforeRotation = theView->ComputedMode();
+ if (myHasHlrOnBeforeRotation)
+ {
+ theView->SetComputedMode (false);
+ }
+ }
+
+ gp_Pnt aGravPnt;
+ if (myGL.OrbitRotation.ToStart)
+ {
+ aGravPnt = GravityPoint (theCtx, theView);
+ if (myToShowRotateCenter)
+ {
+ gp_Trsf aPntTrsf;
+ aPntTrsf.SetTranslation (gp_Vec (aGravPnt.XYZ()));
+ theCtx->SetLocation (myAnchorPointPrs1, aPntTrsf);
+ theCtx->SetLocation (myAnchorPointPrs2, aPntTrsf);
+ }
+ }
+
+ if (myToShowRotateCenter
+ && myGL.OrbitRotation.ToRotate
+ && !myGL.IsNewGesture
+ && !myAnchorPointPrs1->HasInteractiveContext())
+ {
+ theCtx->Display (myAnchorPointPrs1, 0, -1, false, AIS_DS_Displayed);
+ theCtx->Display (myAnchorPointPrs2, 0, -1, false, AIS_DS_Displayed);
+ }
+ handleOrbitRotation (theView, aGravPnt,
+ myToLockOrbitZUp || myNavigationMode != AIS_NavigationMode_Orbit);
+ }
+
+ if ((myNavigationMode != AIS_NavigationMode_Orbit
+ || myGL.ViewRotation.ToStart
+ || myGL.ViewRotation.ToRotate)
+ && myToAllowRotation)
+ {
+ if (myGL.ViewRotation.ToStart
+ && !myHasHlrOnBeforeRotation)
+ {
+ myHasHlrOnBeforeRotation = theView->ComputedMode();
+ if (myHasHlrOnBeforeRotation)
+ {
+ theView->SetComputedMode (false);
+ }
+ }
+
+ double aRoll = 0.0;
+ if (!theWalk[AIS_WalkRotation_Roll].IsEmpty()
+ && !myToLockOrbitZUp)
+ {
+ aRoll = (M_PI / 12.0) * theWalk[AIS_WalkRotation_Roll].Pressure;
+ aRoll *= Min (1000.0 * theWalk[AIS_WalkRotation_Roll].Duration, 100.0) / 100.0;
+ if (theWalk[AIS_WalkRotation_Roll].Value < 0.0)
+ {
+ aRoll = -aRoll;
+ }
+ }
+
+ handleViewRotation (theView, theWalk[AIS_WalkRotation_Yaw].Value, theWalk[AIS_WalkRotation_Pitch].Value, aRoll,
+ myNavigationMode == AIS_NavigationMode_FirstPersonFlight);
+ }
+
+ if (!myGL.ZoomActions.IsEmpty())
+ {
+ for (NCollection_Sequence<Aspect_ScrollDelta>::Iterator aZoomIter (myGL.ZoomActions); aZoomIter.More(); aZoomIter.Next())
+ {
+ Aspect_ScrollDelta aZoomParams = aZoomIter.Value();
+ if (myToAllowZFocus
+ && (aZoomParams.Flags & Aspect_VKeyFlags_CTRL) != 0
+ && theView->Camera()->IsStereo())
+ {
+ handleZFocusScroll (theView, aZoomParams);
+ continue;
+ }
+
+ if (!myToAllowZooming)
+ {
+ continue;
+ }
+
+ if (!theView->Camera()->IsOrthographic())
+ {
+ // what is more natural to user - point on ray or point exactly on geometry in corner cases?
+ const bool toStickToRay = false; // true;
+
+ gp_Pnt aPnt;
+ if (aZoomParams.HasPoint()
+ && PickPoint (aPnt, theCtx, theView, aZoomParams.Point, toStickToRay))
+ {
+ handleZoom (theView, aZoomParams, &aPnt);
+ continue;
+ }
+
+ Graphic3d_Vec2i aWinSize;
+ theView->Window()->Size (aWinSize.x(), aWinSize.y());
+ if (PickPoint (aPnt, theCtx, theView, aWinSize / 2, toStickToRay))
+ {
+ aZoomParams.ResetPoint(); // do not pretend to zoom at 'nothing'
+ handleZoom (theView, aZoomParams, &aPnt);
+ continue;
+ }
+ }
+ handleZoom (theView, aZoomParams, NULL);
+ }
+ myGL.ZoomActions.Clear();
+ }
+}
+
+// =======================================================================
+// function : OnSelectionChanged
+// purpose :
+// =======================================================================
+void AIS_ViewController::OnSelectionChanged (const Handle(AIS_InteractiveContext)& ,
+ const Handle(V3d_View)& )
+{
+ //
+}
+
+// =======================================================================
+// function : OnObjectDragged
+// purpose :
+// =======================================================================
+void AIS_ViewController::OnObjectDragged (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView,
+ AIS_DragAction theAction)
+{
+ switch (theAction)
+ {
+ case AIS_DragAction_Start:
+ {
+ myDragObject.Nullify();
+ if (!theCtx->HasDetected())
+ {
+ return;
+ }
+
+ Handle(AIS_InteractiveObject) aPrs = theCtx->DetectedInteractive();
+ if (Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (aPrs))
+ {
+ if (aManip->HasActiveMode())
+ {
+ myDragObject = aManip;
+ aManip->StartTransform (myGL.Dragging.PointStart.x(), myGL.Dragging.PointStart.y(), theView);
+ }
+ }
+ return;
+ }
+ case AIS_DragAction_Update:
+ {
+ if (myDragObject.IsNull())
+ {
+ return;
+ }
+
+ if (Handle(SelectMgr_EntityOwner) aGlobOwner = myDragObject->GlobalSelOwner())
+ {
+ theCtx->SetSelectedState (aGlobOwner, true);
+ }
+ if (Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (myDragObject))
+ {
+ aManip->Transform (myGL.Dragging.PointTo.x(), myGL.Dragging.PointTo.y(), theView);
+ }
+ theView->Invalidate();
+ return;
+ }
+ case AIS_DragAction_Abort:
+ {
+ if (myDragObject.IsNull())
+ {
+ return;
+ }
+
+ myGL.Dragging.PointTo = myGL.Dragging.PointStart;
+ OnObjectDragged (theCtx, theView, AIS_DragAction_Update);
+
+ if (Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (myDragObject))
+ {
+ aManip->StopTransform (false);
+ }
+ Standard_FALLTHROUGH
+ }
+ case AIS_DragAction_Stop:
+ {
+ if (myDragObject.IsNull())
+ {
+ return;
+ }
+
+ if (Handle(SelectMgr_EntityOwner) aGlobOwner = myDragObject->GlobalSelOwner())
+ {
+ theCtx->SetSelectedState (aGlobOwner, false);
+ }
+
+ theView->Invalidate();
+ myDragObject.Nullify();
+ return;
+ }
+ }
+}
+
+// =======================================================================
+// function : contextLazyMoveTo
+// purpose :
+// =======================================================================
+void AIS_ViewController::contextLazyMoveTo (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView,
+ const Graphic3d_Vec2i& thePnt)
+{
+ if (myPrevMoveTo == thePnt)
+ {
+ return;
+ }
+
+ myPrevMoveTo = thePnt;
+
+ Handle(SelectMgr_EntityOwner) aLastPicked = theCtx->DetectedOwner();
+ theCtx->MoveTo (thePnt.x(), thePnt.y(), theView, false);
+ Handle(SelectMgr_EntityOwner) aNewPicked = theCtx->DetectedOwner();
+
+ if (theView->Viewer()->Grid()->IsActive()
+ && theView->Viewer()->GridEcho())
+ {
+ if (aNewPicked.IsNull())
+ {
+ Graphic3d_Vec3d aPnt3d;
+ theView->ConvertToGrid (thePnt.x(), thePnt.y(), aPnt3d[0], aPnt3d[1], aPnt3d[2]);
+ theView->Viewer()->ShowGridEcho (theView, Graphic3d_Vertex (aPnt3d[0], aPnt3d[1], aPnt3d[2]));
+ theView->InvalidateImmediate();
+ }
+ else
+ {
+ theView->Viewer()->HideGridEcho (theView);
+ theView->InvalidateImmediate();
+ }
+ }
+
+ if (aLastPicked != aNewPicked
+ || (!aNewPicked.IsNull() && aNewPicked->IsForcedHilight()))
+ {
+ // dynamic highlight affects all Views
+ for (V3d_ListOfViewIterator aViewIter (theView->Viewer()->ActiveViewIterator()); aViewIter.More(); aViewIter.Next())
+ {
+ const Handle(V3d_View)& aView = aViewIter.Value();
+ aView->InvalidateImmediate();
+ }
+ }
+}
+
+// =======================================================================
+// function : handleSelectionPick
+// purpose :
+// =======================================================================
+void AIS_ViewController::handleSelectionPick (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView)
+{
+ if (myGL.Selection.Tool == AIS_ViewSelectionTool_Picking
+ && !myGL.Selection.Points.IsEmpty())
+ {
+ for (NCollection_Sequence<Graphic3d_Vec2i>::Iterator aPntIter (myGL.Selection.Points); aPntIter.More(); aPntIter.Next())
+ {
+ if (!myGL.Selection.IsXOR)
+ {
+ theCtx->ClearSelected (false);
+ }
+
+ const bool hadPrevMoveTo = HasPreviousMoveTo();
+ contextLazyMoveTo (theCtx, theView, aPntIter.Value());
+ if (!hadPrevMoveTo)
+ {
+ ResetPreviousMoveTo();
+ }
+
+ if (myGL.Selection.IsXOR)
+ {
+ theCtx->ShiftSelect (false);
+ }
+ else
+ {
+ theCtx->Select (false);
+ }
+
+ // selection affects all Views
+ theView->Viewer()->Invalidate();
+
+ OnSelectionChanged (theCtx, theView);
+ }
+
+ myGL.Selection.Points.Clear();
+ }
+}
+
+// =======================================================================
+// function : handleSelectionPoly
+// purpose :
+// =======================================================================
+void AIS_ViewController::handleSelectionPoly (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView)
+{
+ // rubber-band & window polygon selection
+ if (myGL.Selection.Tool == AIS_ViewSelectionTool_RubberBand
+ || myGL.Selection.Tool == AIS_ViewSelectionTool_Polygon)
+ {
+ if (!myGL.Selection.Points.IsEmpty())
+ {
+ myRubberBand->ClearPoints();
+ myRubberBand->SetToUpdate();
+
+ const bool anIsRubber = myGL.Selection.Tool == AIS_ViewSelectionTool_RubberBand;
+ if (anIsRubber)
+ {
+ myRubberBand->SetRectangle (myGL.Selection.Points.First().x(), -myGL.Selection.Points.First().y(),
+ myGL.Selection.Points.Last().x(), -myGL.Selection.Points.Last().y());
+ }
+ else
+ {
+ Graphic3d_Vec2i aPrev (IntegerLast(), IntegerLast());
+ for (NCollection_Sequence<Graphic3d_Vec2i>::Iterator aSelIter (myGL.Selection.Points); aSelIter.More(); aSelIter.Next())
+ {
+ Graphic3d_Vec2i aPntNew = Graphic3d_Vec2i (aSelIter.Value().x(), -aSelIter.Value().y());
+ if (aPntNew != aPrev)
+ {
+ aPrev = aPntNew;
+ myRubberBand->AddPoint (Graphic3d_Vec2i (aSelIter.Value().x(), -aSelIter.Value().y()));
+ }
+ }
+ }
+
+ myRubberBand->SetPolygonClosed (anIsRubber);
+ try
+ {
+ theCtx->Display (myRubberBand, 0, -1, false, AIS_DS_Displayed);
+ }
+ catch (const Standard_Failure& theEx)
+ {
+ Message::DefaultMessenger()->Send (TCollection_AsciiString ("Internal error while displaying rubber-band: ")
+ + theEx.DynamicType()->Name() + ", " + theEx.GetMessageString(), Message_Warning);
+ myRubberBand->ClearPoints();
+ }
+ if (!theView->Viewer()->ZLayerSettings (myRubberBand->ZLayer()).IsImmediate())
+ {
+ theView->Invalidate();
+ }
+ else
+ {
+ theView->InvalidateImmediate();
+ }
+ }
+ else if (!myRubberBand.IsNull()
+ && myRubberBand->HasInteractiveContext())
+ {
+ theCtx->Remove (myRubberBand, false);
+ myRubberBand->ClearPoints();
+ }
+ }
+
+ if (myGL.Selection.ToApplyTool)
+ {
+ myGL.Selection.ToApplyTool = false;
+ if (theCtx->IsDisplayed (myRubberBand))
+ {
+ theCtx->Remove (myRubberBand, false);
+ {
+ const NCollection_Sequence<Graphic3d_Vec2i>& aPoints = myRubberBand->Points();
+ if (aPoints.Size() == 4
+ && aPoints.Value (1).x() == aPoints.Value (2).x()
+ && aPoints.Value (3).x() == aPoints.Value (4).x()
+ && aPoints.Value (1).y() == aPoints.Value (4).y()
+ && aPoints.Value (2).y() == aPoints.Value (3).y())
+ {
+ const Graphic3d_Vec2i aPnt1 (aPoints.Value (1).x(), -aPoints.Value (1).y());
+ const Graphic3d_Vec2i aPnt2 (aPoints.Value (3).x(), -aPoints.Value (3).y());
+ theCtx->MainSelector()->AllowOverlapDetection (aPnt1.y() != Min (aPnt1.y(), aPnt2.y()));
+ if (myGL.Selection.IsXOR)
+ {
+ theCtx->ShiftSelect (Min (aPnt1.x(), aPnt2.x()), Min (aPnt1.y(), aPnt2.y()),
+ Max (aPnt1.x(), aPnt2.x()), Max (aPnt1.y(), aPnt2.y()),
+ theView, false);
+ }
+ else
+ {
+ theCtx->Select (Min (aPnt1.x(), aPnt2.x()), Min (aPnt1.y(), aPnt2.y()),
+ Max (aPnt1.x(), aPnt2.x()), Max (aPnt1.y(), aPnt2.y()),
+ theView, false);
+ }
+ theCtx->MainSelector()->AllowOverlapDetection (false);
+ }
+ else if (aPoints.Length() >= 3)
+ {
+ TColgp_Array1OfPnt2d aPolyline (1, aPoints.Length());
+ TColgp_Array1OfPnt2d::Iterator aPolyIter (aPolyline);
+ for (NCollection_Sequence<Graphic3d_Vec2i>::Iterator aSelIter (aPoints);
+ aSelIter.More(); aSelIter.Next(), aPolyIter.Next())
+ {
+ const Graphic3d_Vec2i& aNewPnt = aSelIter.Value();
+ aPolyIter.ChangeValue() = gp_Pnt2d (aNewPnt.x(), -aNewPnt.y());
+ }
+
+ theCtx->MainSelector()->AllowOverlapDetection (false);
+ if (myGL.Selection.IsXOR)
+ {
+ theCtx->ShiftSelect (aPolyline, theView, false);
+ }
+ else
+ {
+ theCtx->Select (aPolyline, theView, false);
+ }
+ }
+ }
+
+ // selection affects all Views
+ theView->Viewer()->Invalidate();
+
+ myRubberBand->ClearPoints();
+ OnSelectionChanged (theCtx, theView);
+ }
+ }
+}
+
+// =======================================================================
+// function : handleDynamicHighlight
+// purpose :
+// =======================================================================
+void AIS_ViewController::handleDynamicHighlight (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView)
+{
+ if ((myGL.MoveTo.ToHilight || myGL.Dragging.ToStart)
+ && myNavigationMode != AIS_NavigationMode_FirstPersonWalk)
+ {
+ const Graphic3d_Vec2i& aMoveToPnt = myGL.MoveTo.ToHilight ? myGL.MoveTo.Point : myGL.Dragging.PointStart;
+ if (myGL.Dragging.ToStart && (!myGL.MoveTo.ToHilight || !myToAllowHighlight)
+ && !HasPreviousMoveTo())
+ {
+ contextLazyMoveTo (theCtx, theView, aMoveToPnt);
+ ResetPreviousMoveTo();
+ OnObjectDragged (theCtx, theView, AIS_DragAction_Start);
+ theCtx->ClearDetected();
+ }
+ else if (myToAllowHighlight)
+ {
+ if (myPrevMoveTo != aMoveToPnt
+ || myGL.OrbitRotation.ToRotate
+ || myGL.ViewRotation.ToRotate
+ || theView->IsInvalidated())
+ {
+ ResetPreviousMoveTo();
+ contextLazyMoveTo (theCtx, theView, aMoveToPnt);
+ }
+ if (myGL.Dragging.ToStart)
+ {
+ OnObjectDragged (theCtx, theView, AIS_DragAction_Start);
+ }
+ }
+
+ myGL.MoveTo.ToHilight = false;
+ }
+
+ if (!myDragObject.IsNull())
+ {
+ if (myGL.Dragging.ToAbort)
+ {
+ OnObjectDragged (theCtx, theView, AIS_DragAction_Abort);
+ myGL.OrbitRotation.ToRotate = false;
+ myGL.ViewRotation .ToRotate = false;
+ }
+ else if (myGL.Dragging.ToStop)
+ {
+ OnObjectDragged (theCtx, theView, AIS_DragAction_Stop);
+ myGL.OrbitRotation.ToRotate = false;
+ myGL.ViewRotation .ToRotate = false;
+ }
+ else if (myGL.OrbitRotation.ToRotate
+ || myGL.ViewRotation.ToRotate)
+ {
+ OnObjectDragged (theCtx, theView, AIS_DragAction_Update);
+ myGL.OrbitRotation.ToRotate = false;
+ myGL.ViewRotation .ToRotate = false;
+ }
+ }
+}
+
+// =======================================================================
+// function : handleMoveTo
+// purpose :
+// =======================================================================
+void AIS_ViewController::handleMoveTo (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView)
+{
+ handleSelectionPick (theCtx, theView);
+ handleDynamicHighlight(theCtx, theView);
+ handleSelectionPoly (theCtx, theView);
+}
+
+// =======================================================================
+// function : handleViewRedraw
+// purpose :
+// =======================================================================
+void AIS_ViewController::handleViewRedraw (const Handle(AIS_InteractiveContext)& ,
+ const Handle(V3d_View)& theView)
+{
+ for (V3d_ListOfViewIterator aViewIter (theView->Viewer()->ActiveViewIterator()); aViewIter.More(); aViewIter.Next())
+ {
+ const Handle(V3d_View)& aView = aViewIter.Value();
+ if (aView->IsInvalidated()
+ || myToAskNextFrame)
+ {
+ if (aView->ComputedMode())
+ {
+ aView->Update();
+ }
+ else
+ {
+ aView->Redraw();
+ }
+ }
+ else if (aView->IsInvalidatedImmediate())
+ {
+ aView->RedrawImmediate();
+ }
+ }
+
+ if (myToAskNextFrame)
+ {
+ // ask more frames
+ theView->Window()->InvalidateContent (Handle(Aspect_DisplayConnection)());
+ }
+}
+
+// =======================================================================
+// function : HandleViewEvents
+// purpose :
+// =======================================================================
+void AIS_ViewController::HandleViewEvents (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView)
+{
+ handleMoveTo (theCtx, theView);
+
+ const AIS_WalkDelta aWalk = FetchNavigationKeys (1.0, 1.0);
+ handleCameraActions (theCtx, theView, aWalk);
+ handleViewRedraw (theCtx, theView);
+
+ // make sure to not process the same events twice
+ myGL.Reset();
+ myToAskNextFrame = false;
+}
--- /dev/null
+// Copyright (c) 2016-2019 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 _AIS_ViewController_HeaderFile
+#define _AIS_ViewController_HeaderFile
+
+#include <Aspect_VKeySet.hxx>
+#include <Aspect_TouchMap.hxx>
+#include <AIS_DragAction.hxx>
+#include <AIS_MouseGesture.hxx>
+#include <AIS_NavigationMode.hxx>
+#include <AIS_ViewInputBuffer.hxx>
+#include <AIS_RotationMode.hxx>
+#include <AIS_WalkDelta.hxx>
+
+#include <gp_Pnt.hxx>
+#include <Graphic3d_Vec3.hxx>
+#include <NCollection_Array1.hxx>
+#include <OSD_Timer.hxx>
+#include <Precision.hxx>
+#include <Standard_Mutex.hxx>
+
+class AIS_InteractiveObject;
+class AIS_InteractiveContext;
+class AIS_Point;
+class AIS_RubberBand;
+class V3d_View;
+
+//! Auxiliary structure for handling viewer events between GUI and Rendering threads.
+//!
+//! Class implements the following features:
+//! - Buffers storing the state of user input (mouse, touches and keyboard).
+//! - 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
+{
+public:
+
+ //! Empty constructor.
+ Standard_EXPORT AIS_ViewController();
+
+ //! Return input buffer.
+ const AIS_ViewInputBuffer& InputBuffer (AIS_ViewInputBufferType theType) const { return theType == AIS_ViewInputBufferType_UI ? myUI : myGL; }
+
+ //! Return input buffer.
+ AIS_ViewInputBuffer& ChangeInputBuffer (AIS_ViewInputBufferType theType) { return theType == AIS_ViewInputBufferType_UI ? myUI : myGL; }
+
+public: //! @name global parameters
+
+ //! Return camera rotation mode, AIS_RotationMode_BndBoxActive by default.
+ AIS_RotationMode RotationMode() const { return myRotationMode; }
+
+ //! Set camera rotation mode.
+ void SetRotationMode (AIS_RotationMode theMode) { myRotationMode = theMode; }
+
+ //! Return camera navigation mode; AIS_NavigationMode_Orbit by default.
+ AIS_NavigationMode NavigationMode() const { return myNavigationMode; }
+
+ //! Set camera navigation mode.
+ Standard_EXPORT void SetNavigationMode (AIS_NavigationMode theMode);
+
+ //! Return mouse input acceleration ratio in First Person mode; 1.0 by default.
+ float MouseAcceleration() const { return myMouseAccel; }
+
+ //! Set mouse input acceleration ratio.
+ void SetMouseAcceleration (float theRatio) { myMouseAccel = theRatio; }
+
+ //! Return orbit rotation acceleration ratio; 1.0 by default.
+ float OrbitAcceleration() const { return myOrbitAccel; }
+
+ //! Set orbit rotation acceleration ratio.
+ void SetOrbitAcceleration (float theRatio) { myOrbitAccel = theRatio; }
+
+ //! Return TRUE if panning anchor point within perspective projection should be displayed in 3D Viewer; TRUE by default.
+ bool ToShowPanAnchorPoint() const { return myToShowPanAnchorPoint; }
+
+ //! Set if panning anchor point within perspective projection should be displayed in 3D Viewer.
+ void SetShowPanAnchorPoint (bool theToShow) { myToShowPanAnchorPoint = theToShow; }
+
+ //! Return TRUE if rotation point should be displayed in 3D Viewer; TRUE by default.
+ bool ToShowRotateCenter() const { return myToShowRotateCenter; }
+
+ //! Set if rotation point should be displayed in 3D Viewer.
+ void SetShowRotateCenter (bool theToShow) { myToShowRotateCenter = theToShow; }
+
+ //! Return TRUE if camera up orientation within AIS_NavigationMode_Orbit rotation mode should be forced Z up; FALSE by default.
+ bool ToLockOrbitZUp() const { return myToLockOrbitZUp; }
+
+ //! Set if camera up orientation within AIS_NavigationMode_Orbit rotation mode should be forced Z up.
+ void SetLockOrbitZUp (bool theToForceUp) { myToLockOrbitZUp = theToForceUp; }
+
+ //! Return TRUE if z-rotation via two-touches gesture is enabled; FALSE by default.
+ bool ToAllowTouchZRotation() const { return myToAllowTouchZRotation; }
+
+ //! Set if z-rotation via two-touches gesture is enabled.
+ void SetAllowTouchZRotation (bool theToEnable) { myToAllowTouchZRotation = theToEnable; }
+
+ //! Return TRUE if camera rotation is allowed; TRUE by default.
+ bool ToAllowRotation() const { return myToAllowRotation; }
+
+ //! Set if camera rotation is allowed.
+ void SetAllowRotation (bool theToEnable) { myToAllowRotation = theToEnable; }
+
+ //! Return TRUE if panning is allowed; TRUE by default.
+ bool ToAllowPanning() const { return myToAllowPanning; }
+
+ //! Set if panning is allowed.
+ void SetAllowPanning (bool theToEnable) { myToAllowPanning = theToEnable; }
+
+ //! Return TRUE if zooming is allowed; TRUE by default.
+ bool ToAllowZooming() const { return myToAllowZooming; }
+
+ //! Set if zooming is allowed.
+ void SetAllowZooming (bool theToEnable) { myToAllowZooming = theToEnable; }
+
+ //! Return TRUE if ZFocus change is allowed; TRUE by default.
+ bool ToAllowZFocus() const { return myToAllowZFocus; }
+
+ //! Set if ZFocus change is allowed.
+ void SetAllowZFocus (bool theToEnable) { myToAllowZFocus = theToEnable; }
+
+ //! Return TRUE if dynamic highlight on mouse move is allowed; TRUE by default.
+ bool ToAllowHighlight() const { return myToAllowHighlight; }
+
+ //! Set if dragging object is allowed.
+ void SetAllowHighlight (bool theToEnable) { myToAllowHighlight = theToEnable; }
+
+ //! Return TRUE if dragging object is allowed; TRUE by default.
+ bool ToAllowDragging() const { return myToAllowDragging; }
+
+ //! Set if dynamic highlight on mouse move is allowed.
+ void SetAllowDragging (bool theToEnable) { myToAllowDragging = theToEnable; }
+
+ //! Return TRUE if pitch direction should be inverted while processing Aspect_VKey_NavLookUp/Aspect_VKey_NavLookDown; FALSE by default.
+ bool ToInvertPitch() const { return myToInvertPitch; }
+
+ //! Set flag inverting pitch direction.
+ void SetInvertPitch (bool theToInvert) { myToInvertPitch = theToInvert; }
+
+ //! Return normal walking speed, in m/s; 1.5 by default.
+ float WalkSpeedAbsolute() const { return myWalkSpeedAbsolute; }
+
+ //! Set normal walking speed, in m/s; 1.5 by default.
+ void SetWalkSpeedAbsolute (float theSpeed) { myWalkSpeedAbsolute = theSpeed; }
+
+ //! Return walking speed relative to scene bounding box; 0.1 by default.
+ float WalkSpeedRelative() const { return myWalkSpeedRelative; }
+
+ //! Set walking speed relative to scene bounding box.
+ void SetWalkSpeedRelative (float theFactor) { myWalkSpeedRelative = theFactor; }
+
+ //! Return active thrust value; 0.0f by default.
+ float ThrustSpeed() const { return myThrustSpeed; }
+
+ //! Set active thrust value.
+ void SetThrustSpeed (float theSpeed) { myThrustSpeed = theSpeed; }
+
+ //! Return TRUE if previous position of MoveTo has been defined.
+ bool HasPreviousMoveTo() const { return myPrevMoveTo != Graphic3d_Vec2i (-1); }
+
+ //! Return previous position of MoveTo event in 3D viewer.
+ const Graphic3d_Vec2i& PreviousMoveTo() const { return myPrevMoveTo; }
+
+ //! Reset previous position of MoveTo.
+ void ResetPreviousMoveTo() { myPrevMoveTo = Graphic3d_Vec2i (-1); }
+
+public: //! @name keyboard input
+
+ //! Return keyboard state.
+ const Aspect_VKeySet& Keys() const { return myKeys; }
+
+ //! Return keyboard state.
+ Aspect_VKeySet& ChangeKeys() { return myKeys; }
+
+ //! Press key.
+ //! @param theKey key pressed
+ //! @param theTime event timestamp
+ Standard_EXPORT virtual void KeyDown (Aspect_VKey theKey,
+ double theTime,
+ double thePressure = 1.0);
+
+ //! Release key.
+ //! @param theKey key pressed
+ //! @param theTime event timestamp
+ Standard_EXPORT virtual void KeyUp (Aspect_VKey theKey,
+ double theTime);
+
+ //! Simulate key up/down events from axis value.
+ Standard_EXPORT virtual void KeyFromAxis (Aspect_VKey theNegative,
+ Aspect_VKey thePositive,
+ double theTime,
+ double thePressure);
+
+ //! Fetch active navigation actions.
+ Standard_EXPORT AIS_WalkDelta FetchNavigationKeys (Standard_Real theCrouchRatio,
+ Standard_Real theRunRatio);
+
+public: //! @name mouse input
+
+ //! Return map defining mouse gestures.
+ const AIS_MouseGestureMap& MouseGestureMap() const { return myMouseGestureMap; }
+
+ //! Return map defining mouse gestures.
+ AIS_MouseGestureMap& ChangeMouseGestureMap() { return myMouseGestureMap; }
+
+ //! Return double click interval in seconds; 0.4 by default.
+ double MouseDoubleClickInterval() const { return myMouseDoubleClickInt; }
+
+ //! Set double click interval in seconds.
+ void SetMouseDoubleClickInterval (double theSeconds) { myMouseDoubleClickInt = theSeconds; }
+
+ //! Perform selection in 3D viewer.
+ //! This method is expected to be called from UI thread.
+ //! @param thePnt picking point
+ //! @param theIsXOR XOR selection flag
+ Standard_EXPORT virtual void SelectInViewer (const Graphic3d_Vec2i& thePnt,
+ const bool theIsXOR = false);
+
+ //! Perform selection in 3D viewer.
+ //! This method is expected to be called from UI thread.
+ //! @param thePnts picking point
+ //! @param theIsXOR XOR selection flag
+ Standard_EXPORT virtual void SelectInViewer (const NCollection_Sequence<Graphic3d_Vec2i>& thePnts,
+ const bool theIsXOR = false);
+
+ //! Update rectangle selection tool.
+ //! This method is expected to be called from UI thread.
+ //! @param thePntFrom rectangle first corner
+ //! @param thePntTo rectangle another corner
+ //! @param theIsXOR XOR selection flag
+ Standard_EXPORT virtual void UpdateRubberBand (const Graphic3d_Vec2i& thePntFrom,
+ const Graphic3d_Vec2i& thePntTo,
+ const bool theIsXOR = false);
+
+ //! Update polygonal selection tool.
+ //! This method is expected to be called from UI thread.
+ //! @param thePnt new point to add to polygon
+ //! @param theToAppend append new point or update the last point
+ Standard_EXPORT virtual void UpdatePolySelection (const Graphic3d_Vec2i& thePnt,
+ bool theToAppend);
+
+ //! Update zoom event (e.g. from mouse scroll).
+ //! This method is expected to be called from UI thread.
+ //! @param theDelta mouse cursor position to zoom at and zoom delta
+ //! @return TRUE if new zoom event has been created or FALSE if existing one has been updated
+ Standard_EXPORT virtual bool UpdateZoom (const Aspect_ScrollDelta& theDelta);
+
+ //! Update Z rotation event.
+ //! @param theAngle rotation angle, in radians.
+ //! @return TRUE if new zoom event has been created or FALSE if existing one has been updated
+ Standard_EXPORT virtual bool UpdateZRotation (double theAngle);
+
+ //! Update mouse scroll event; redirects to UpdateZoom by default.
+ //! 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);
+
+ //! 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 View should be redrawn
+ Standard_EXPORT virtual bool UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
+ Aspect_VKeyMouse theButtons,
+ Aspect_VKeyFlags theModifiers,
+ bool theIsEmulated);
+
+ //! Handle mouse cursor movement 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 View should be redrawn
+ 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);
+ }
+
+ //! 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.
+ //! Default implementation redirects to SelectInViewer().
+ //! This method is expected to be called from UI thread.
+ //! @param thePoint mouse cursor position
+ //! @param theButton clicked button
+ //! @param theModifiers key modifiers
+ //! @param theIsDoubleClick flag indicating double mouse click
+ //! @return TRUE if View should be redrawn
+ Standard_EXPORT virtual bool UpdateMouseClick (const Graphic3d_Vec2i& thePoint,
+ Aspect_VKeyMouse theButton,
+ Aspect_VKeyFlags theModifiers,
+ bool theIsDoubleClick);
+
+ //! 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 multi-touch input
+
+ //! Return scale factor for adjusting tolerances for starting multi-touch gestures; 1.0 by default
+ //! This scale factor is expected to be computed from touch screen resolution.
+ float TouchToleranceScale() const { return myTouchToleranceScale; }
+
+ //! Set scale factor for adjusting tolerances for starting multi-touch gestures.
+ void SetTouchToleranceScale (float theTolerance) { myTouchToleranceScale = theTolerance; }
+
+ //! Return TRUE if touches map is not empty.
+ bool HasTouchPoints() const { return !myTouchPoints.IsEmpty(); }
+
+ //! Add touch point with the given ID.
+ //! This method is expected to be called from UI thread.
+ //! @param theId touch unique identifier
+ //! @param thePnt touch coordinates
+ //! @param theClearBefore if TRUE previously registered touches will be removed
+ Standard_EXPORT virtual void AddTouchPoint (Standard_Size theId,
+ const Graphic3d_Vec2d& thePnt,
+ Standard_Boolean theClearBefore = false);
+
+ //! Remove touch point with the given ID.
+ //! This method is expected to be called from UI thread.
+ //! @param theId touch unique identifier
+ //! @param theClearSelectPnts if TRUE will initiate clearing of selection points
+ //! @return TRUE if point has been removed
+ Standard_EXPORT virtual bool RemoveTouchPoint (Standard_Size theId,
+ Standard_Boolean theClearSelectPnts = false);
+
+ //! Update touch point with the given ID.
+ //! If point with specified ID was not registered before, it will be added.
+ //! This method is expected to be called from UI thread.
+ //! @param theId touch unique identifier
+ //! @param thePnt touch coordinates
+ Standard_EXPORT virtual void UpdateTouchPoint (Standard_Size theId,
+ const Graphic3d_Vec2d& thePnt);
+
+public:
+
+ //! Return event time (e.g. current time).
+ double EventTime() const { return myEventTimer.ElapsedTime(); }
+
+ //! Reset input state (pressed keys, mouse buttons, etc.) e.g. on window focus loss.
+ //! This method is expected to be called from UI thread.
+ Standard_EXPORT virtual void ResetViewInput();
+
+ //! Reset view orientation.
+ //! This method is expected to be called from UI thread.
+ Standard_EXPORT virtual void UpdateViewOrientation (V3d_TypeOfOrientation theOrientation,
+ bool theToFitAll);
+
+ //! Update buffer for rendering thread.
+ //! This method is expected to be called within synchronization barrier between GUI
+ //! and Rendering threads (e.g. GUI thread should be locked beforehand to avoid data races).
+ //! @param theCtx interactive context
+ //! @param theView active view
+ //! @param theToHandle if TRUE, the HandleViewEvents() will be called
+ Standard_EXPORT virtual void FlushViewEvents (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView,
+ Standard_Boolean theToHandle = Standard_False);
+
+ //! Process events within rendering thread.
+ Standard_EXPORT virtual void HandleViewEvents (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView);
+
+public:
+
+ //! Callback called by handleMoveTo() on Selection in 3D Viewer.
+ //! This method is expected to be called from rendering thread.
+ Standard_EXPORT virtual void OnSelectionChanged (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView);
+
+ //! Callback called by handleMoveTo() on dragging object in 3D Viewer.
+ //! This method is expected to be called from rendering thread.
+ Standard_EXPORT virtual void OnObjectDragged (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView,
+ AIS_DragAction theAction);
+
+ //! Pick closest point under mouse cursor.
+ //! This method is expected to be called from rendering thread.
+ //! @param thePnt [out] result point
+ //! @param theCtx [in] interactive context
+ //! @param theView [in] active view
+ //! @param theCursor [in] mouse cursor
+ //! @param theToStickToPickRay [in] when TRUE, the result point will lie on picking ray
+ //! @return TRUE if result has been found
+ Standard_EXPORT virtual bool PickPoint (gp_Pnt& thePnt,
+ const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView,
+ const Graphic3d_Vec2i& theCursor,
+ bool theToStickToPickRay);
+
+ //! Compute rotation gravity center point depending on rotation mode.
+ //! This method is expected to be called from rendering thread.
+ Standard_EXPORT virtual gp_Pnt GravityPoint (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView);
+
+public:
+
+ //! Perform camera actions.
+ //! This method is expected to be called from rendering thread.
+ Standard_EXPORT virtual void handleCameraActions (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView,
+ const AIS_WalkDelta& theWalk);
+
+ //! Perform moveto/selection/dragging.
+ //! This method is expected to be called from rendering thread.
+ Standard_EXPORT virtual void handleMoveTo (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView);
+
+ //! Return TRUE if another frame should be drawn right after this one.
+ bool toAskNextFrame() const { return myToAskNextFrame; }
+
+ //! Set if another frame should be drawn right after this one.
+ void setAskNextFrame (bool theToDraw = true) { myToAskNextFrame = theToDraw; }
+
+ //! Return if panning anchor point has been defined.
+ bool hasPanningAnchorPoint() const { return !Precision::IsInfinite (myPanPnt3d.X()); }
+
+ //! Return active panning anchor point.
+ const gp_Pnt& panningAnchorPoint() const { return myPanPnt3d; }
+
+ //! Set active panning anchor point.
+ void setPanningAnchorPoint (const gp_Pnt& thePnt) { myPanPnt3d = thePnt; }
+
+ //! Handle panning event myGL.Panning.
+ Standard_EXPORT virtual void handlePanning (const Handle(V3d_View)& theView);
+
+ //! Handle Z rotation event myGL.ZRotate.
+ Standard_EXPORT virtual void handleZRotate (const Handle(V3d_View)& theView);
+
+ //! Return minimal camera distance for zoom operation.
+ double MinZoomDistance() const { return myMinCamDistance; }
+
+ //! Set minimal camera distance for zoom operation.
+ void SetMinZoomDistance (double theDist) { myMinCamDistance = theDist; }
+
+ //! Handle zoom event myGL.ZoomActions.
+ //! This method is expected to be called from rendering thread.
+ Standard_EXPORT virtual void handleZoom (const Handle(V3d_View)& theView,
+ const Aspect_ScrollDelta& theParams,
+ const gp_Pnt* thePnt);
+
+ //! Handle ZScroll event myGL.ZoomActions.
+ //! This method is expected to be called from rendering thread.
+ Standard_EXPORT virtual void handleZFocusScroll (const Handle(V3d_View)& theView,
+ const Aspect_ScrollDelta& theParams);
+
+ //! Handle orbital rotation events myGL.OrbitRotation.
+ //! @param theView view to modify
+ //! @param thePnt 3D point to rotate around
+ //! @param theToLockZUp amend camera to exclude roll angle (put camera Up vector to plane containing global Z and view direction)
+ Standard_EXPORT virtual void handleOrbitRotation (const Handle(V3d_View)& theView,
+ const gp_Pnt& thePnt,
+ bool theToLockZUp);
+
+ //! Handle view direction rotation events myGL.ViewRotation.
+ //! This method is expected to be called from rendering thread.
+ //! @param theView camera to modify
+ //! @param theYawExtra extra yaw increment
+ //! @param thePitchExtra extra pitch increment
+ //! @param theRoll roll value
+ //! @param theToRestartOnIncrement flag indicating flight mode
+ Standard_EXPORT virtual void handleViewRotation (const Handle(V3d_View)& theView,
+ double theYawExtra,
+ double thePitchExtra,
+ double theRoll,
+ bool theToRestartOnIncrement);
+
+ //! Handle view redraw.
+ //! This method is expected to be called from rendering thread.
+ Standard_EXPORT virtual void handleViewRedraw (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView);
+
+protected:
+
+ //! Flush buffers.
+ Standard_EXPORT virtual void flushBuffers (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView);
+
+ //! Flush touch gestures.
+ Standard_EXPORT virtual void flushGestures (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView);
+
+ //! Return current and previously fetched event times.
+ //! This callback is intended to compute delta between sequentially processed events.
+ //! @param thePrevTime [out] events time fetched previous time by this method
+ //! @param theCurrTime [out] actual events time
+ void updateEventsTime (double& thePrevTime,
+ double& theCurrTime)
+ {
+ thePrevTime = myLastEventsTime;
+ myLastEventsTime = EventTime();
+ theCurrTime = myLastEventsTime;
+ }
+
+ //! Perform selection via mouse click.
+ //! This method is expected to be called from rendering thread.
+ Standard_EXPORT virtual void handleSelectionPick (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView);
+
+ //! Perform dynamic highlight on mouse move.
+ //! This method is expected to be called from rendering thread.
+ Standard_EXPORT virtual void handleDynamicHighlight (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView);
+
+ //! Perform rubber-band selection.
+ //! This method is expected to be called from rendering thread.
+ Standard_EXPORT virtual void handleSelectionPoly (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView);
+
+ //! Lazy AIS_InteractiveContext::MoveTo() with myPrevMoveTo check.
+ Standard_EXPORT virtual void contextLazyMoveTo (const Handle(AIS_InteractiveContext)& theCtx,
+ const Handle(V3d_View)& theView,
+ const Graphic3d_Vec2i& thePnt);
+
+protected:
+
+ 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_Real myMinCamDistance; //!< minimal camera distance for zoom operation
+ AIS_RotationMode myRotationMode; //!< rotation mode
+ AIS_NavigationMode myNavigationMode; //!< navigation mode (orbit rotation / first person)
+ Standard_ShortReal myMouseAccel; //!< mouse input acceleration ratio in First Person mode
+ Standard_ShortReal myOrbitAccel; //!< Orbit rotation acceleration ratio
+ Standard_Boolean myToShowPanAnchorPoint; //!< option displaying panning anchor point
+ Standard_Boolean myToShowRotateCenter; //!< option displaying rotation center point
+ Standard_Boolean myToLockOrbitZUp; //!< force camera up orientation within AIS_NavigationMode_Orbit rotation mode
+ Standard_Boolean myToInvertPitch; //!< flag inverting pitch direction while processing Aspect_VKey_NavLookUp/Aspect_VKey_NavLookDown
+ Standard_Boolean myToAllowTouchZRotation; //!< enable z-rotation two-touches gesture; FALSE by default
+ Standard_Boolean myToAllowRotation; //!< enable rotation; TRUE by default
+ Standard_Boolean myToAllowPanning; //!< enable panning; TRUE by default
+ Standard_Boolean myToAllowZooming; //!< enable zooming; TRUE by default
+ Standard_Boolean myToAllowZFocus; //!< enable ZFocus change; TRUE by default
+ Standard_Boolean myToAllowHighlight; //!< enable dynamic highlight on mouse move; TRUE by default
+ Standard_Boolean myToAllowDragging; //!< enable dragging object; TRUE by default
+
+ Standard_ShortReal myWalkSpeedAbsolute; //!< normal walking speed, in m/s; 1.5 by default
+ Standard_ShortReal myWalkSpeedRelative; //!< walking speed relative to scene bounding box; 0.1 by default
+ Standard_ShortReal myThrustSpeed; //!< active thrust value
+ Standard_Boolean myHasThrust; //!< flag indicating active thrust
+
+ Handle(AIS_RubberBand) myRubberBand; //!< Rubber-band presentation
+ Handle(AIS_InteractiveObject) myDragObject; //!< currently dragged object
+ Graphic3d_Vec2i myPrevMoveTo; //!< previous position of MoveTo event in 3D viewer
+ Standard_Boolean myHasHlrOnBeforeRotation; //!< flag for restoring Computed mode after rotation
+
+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
+ Standard_Real myMouseDoubleClickInt; //!< double click interval in seconds; 0.4 by default
+ Standard_ShortReal myScrollZoomRatio; //!< distance ratio for mapping mouse scroll event to zoom; 15.0 by default
+
+ AIS_MouseGestureMap myMouseGestureMap; //!< map defining mouse gestures
+ AIS_MouseGesture myMouseActiveGesture; //!< initiated mouse gesture (by pressing mouse button)
+ 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)
+
+protected: //! @name multi-touch input variables
+
+ Standard_ShortReal myTouchToleranceScale; //!< tolerance scale factor; 1.0 by default
+ Standard_ShortReal myTouchRotationThresholdPx; //!< threshold for starting one-touch rotation gesture in pixels; 6 by default
+ Standard_ShortReal myTouchZRotationThreshold; //!< threshold for starting two-touch Z-rotation gesture in radians; 2 degrees by default
+ Standard_ShortReal myTouchPanThresholdPx; //!< threshold for starting two-touch panning gesture in pixels; 4 by default
+ Standard_ShortReal myTouchZoomThresholdPx; //!< threshold for starting two-touch zoom (pitch) gesture in pixels; 6 by default
+ Standard_ShortReal myTouchZoomRatio; //!< distance ratio for mapping two-touch zoom (pitch) gesture from pixels to zoom; 0.13 by default
+
+ Aspect_TouchMap myTouchPoints; //!< map of active touches
+ Graphic3d_Vec2d myStartPanCoord; //!< touch coordinates at the moment of starting panning gesture
+ Graphic3d_Vec2d myStartRotCoord; //!< touch coordinates at the moment of starting rotating gesture
+ Standard_Integer myNbTouchesLast; //!< number of touches within previous gesture flush to track gesture changes
+ Standard_Boolean myUpdateStartPointPan; //!< flag indicating that new anchor point should be picked for starting panning 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
+
+protected: //! @name rotation/panning transient state variables
+
+ Handle(AIS_Point) myAnchorPointPrs1; //!< anchor point presentation (Graphic3d_ZLayerId_Top)
+ Handle(AIS_Point) myAnchorPointPrs2; //!< anchor point presentation (Graphic3d_ZLayerId_Topmost)
+ gp_Pnt myPanPnt3d; //!< active panning anchor point
+ gp_Pnt myRotatePnt3d; //!< active rotation center of gravity
+ gp_Dir myCamStartOpUp; //!< camera Up direction at the beginning of rotation
+ gp_Pnt myCamStartOpEye; //!< camera Eye position at the beginning of rotation
+ gp_Pnt myCamStartOpCenter; //!< camera Center position at the beginning of rotation
+ gp_Vec myCamStartOpToCenter; //!< vector from rotation gravity point to camera Center at the beginning of rotation
+ gp_Vec myCamStartOpToEye; //!< vector from rotation gravity point to camera Eye at the beginning of rotation
+ Graphic3d_Vec3d myRotateStartYawPitchRoll; //!< camera yaw pitch roll at the beginning of rotation
+
+};
+
+#endif // _AIS_ViewController_HeaderFile
--- /dev/null
+// Copyright (c) 2016-2019 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 _AIS_ViewInputBuffer_HeaderFile
+#define _AIS_ViewInputBuffer_HeaderFile
+
+#include <Aspect_ScrollDelta.hxx>
+
+#include <Graphic3d_Vec2.hxx>
+#include <NCollection_Sequence.hxx>
+#include <V3d_TypeOfOrientation.hxx>
+
+//! Selection mode
+enum AIS_ViewSelectionTool
+{
+ AIS_ViewSelectionTool_Picking, //!< pick to select
+ AIS_ViewSelectionTool_RubberBand, //!< rubber-band to select
+ AIS_ViewSelectionTool_Polygon //!< polyline to select
+};
+
+//! Input buffer type.
+enum AIS_ViewInputBufferType
+{
+ AIS_ViewInputBufferType_UI, //!< input buffer for filling from UI thread
+ AIS_ViewInputBufferType_GL, //!< input buffer accessible from GL thread
+};
+
+//! Auxiliary structure defining viewer events
+class AIS_ViewInputBuffer
+{
+public:
+
+ bool IsNewGesture; //!< transition from one action to another
+
+ NCollection_Sequence<Aspect_ScrollDelta> ZoomActions; //!< the queue with zoom actions
+
+ struct _orientation
+ {
+ bool ToFitAll; //!< perform FitAll operation
+ bool ToSetViewOrient; //!< set new view orientation
+ V3d_TypeOfOrientation ViewOrient; //!< new view orientation
+
+ _orientation() : ToFitAll (false), ToSetViewOrient (false), ViewOrient (V3d_Xpos) {}
+ } Orientation;
+
+ struct _highlighting
+ {
+ bool ToHilight; //!< perform dynamic highlighting at specified point
+ Graphic3d_Vec2i Point; //!< the new point for dynamic highlighting
+
+ _highlighting() : ToHilight (false) {}
+ } MoveTo;
+
+ struct _selection
+ {
+ AIS_ViewSelectionTool Tool; //!< perform selection
+ bool IsXOR; //!< perform shift selection
+ NCollection_Sequence<Graphic3d_Vec2i>
+ Points; //!< the points for selection
+ bool ToApplyTool; //!< apply rubber-band selection tool
+
+ _selection() : Tool (AIS_ViewSelectionTool_Picking), IsXOR (false), ToApplyTool (false) {}
+ } Selection;
+
+ struct _panningParams
+ {
+ bool ToStart; //!< start panning
+ Graphic3d_Vec2i PointStart; //!< panning start point
+ bool ToPan; //!< perform panning
+ Graphic3d_Vec2i Delta; //!< panning delta
+
+ _panningParams() : ToStart (false), ToPan (false) {}
+ } Panning;
+
+ struct _draggingParams
+ {
+ bool ToStart; //!< start dragging
+ bool ToStop; //!< stop dragging
+ bool ToAbort; //!< abort dragging (restore previous position)
+ Graphic3d_Vec2i PointStart; //!< drag start point
+ Graphic3d_Vec2i PointTo; //!< drag end point
+
+ _draggingParams() : ToStart (false), ToStop (false), ToAbort (false) {}
+ } Dragging;
+
+ struct _orbitRotation
+ {
+ bool ToStart; //!< start orbit rotation
+ Graphic3d_Vec2d PointStart; //!< orbit rotation start point
+ bool ToRotate; //!< perform orbit rotation
+ Graphic3d_Vec2d PointTo; //!< orbit rotation end point
+
+ _orbitRotation() : ToStart (false), ToRotate (false) {}
+ } OrbitRotation;
+
+ struct _viewRotation
+ {
+ bool ToStart; //!< start view rotation
+ Graphic3d_Vec2d PointStart; //!< view rotation start point
+ bool ToRotate; //!< perform view rotation
+ Graphic3d_Vec2d PointTo; //!< view rotation end point
+
+ _viewRotation() : ToStart (false), ToRotate (false) {}
+ } ViewRotation;
+
+ struct _zrotateParams
+ {
+ Graphic3d_Vec2i Point; //!< Z rotation start point
+ double Angle; //!< Z rotation angle
+ bool ToRotate; //!< start Z rotation
+
+ _zrotateParams() : Angle (0.0), ToRotate (false) {}
+ } ZRotate;
+
+public:
+
+ AIS_ViewInputBuffer()
+ : IsNewGesture (false) {}
+
+ //! Reset events buffer.
+ void Reset()
+ {
+ Orientation.ToFitAll = false;
+ Orientation.ToSetViewOrient = false;
+ MoveTo.ToHilight = false;
+ Selection.ToApplyTool = false;
+ IsNewGesture = false;
+ ZoomActions.Clear();
+ Panning.ToStart = false;
+ Panning.ToPan = false;
+ Dragging.ToStart = false;
+ Dragging.ToStop = false;
+ Dragging.ToAbort = false;
+ OrbitRotation.ToStart = false;
+ OrbitRotation.ToRotate = false;
+ ViewRotation.ToStart = false;
+ ViewRotation.ToRotate = false;
+ ZRotate.ToRotate = false;
+ }
+
+};
+
+#endif // _AIS_ViewInputBuffer_HeaderFile
--- /dev/null
+// Copyright (c) 2019 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 _AIS_WalkDelta_HeaderFile
+#define _AIS_WalkDelta_HeaderFile
+
+#include <Standard_Real.hxx>
+
+//! Walking translation components.
+enum AIS_WalkTranslation
+{
+ AIS_WalkTranslation_Forward = 0, //!< translation delta, Forward walk
+ AIS_WalkTranslation_Side, //!< translation delta, Side walk
+ AIS_WalkTranslation_Up, //!< translation delta, Up walk
+};
+
+//! Walking rotation components.
+enum AIS_WalkRotation
+{
+ AIS_WalkRotation_Yaw = 0, //!< yaw rotation angle
+ AIS_WalkRotation_Pitch, //!< pitch rotation angle
+ AIS_WalkRotation_Roll, //!< roll rotation angle
+};
+
+//! Walking value.
+struct AIS_WalkPart
+{
+ Standard_Real Value; //!< value
+ Standard_Real Pressure; //!< key pressure
+ Standard_Real Duration; //!< duration
+
+ //! Return TRUE if delta is empty.
+ bool IsEmpty() const { return Abs (Value) <= RealSmall(); }
+
+ //! Empty constructor.
+ AIS_WalkPart() : Value (0.0), Pressure (1.0), Duration (0.0) {}
+};
+
+//! Walking values.
+struct AIS_WalkDelta
+{
+ //! Empty constructor.
+ AIS_WalkDelta()
+ : myIsJumping (false), myIsCrouching (false), myIsRunning (false) {}
+
+ //! Return translation component.
+ const AIS_WalkPart& operator[] (AIS_WalkTranslation thePart) const { return myTranslation[thePart]; }
+
+ //! Return translation component.
+ AIS_WalkPart& operator[] (AIS_WalkTranslation thePart) { return myTranslation[thePart]; }
+
+ //! Return rotation component.
+ const AIS_WalkPart& operator[] (AIS_WalkRotation thePart) const { return myRotation[thePart]; }
+
+ //! Return rotation component.
+ AIS_WalkPart& operator[] (AIS_WalkRotation thePart) { return myRotation[thePart]; }
+
+ //! Return jumping state.
+ bool IsJumping() const { return myIsJumping; }
+
+ //! Set jumping state.
+ void SetJumping (bool theIsJumping) { myIsJumping = theIsJumping; }
+
+ //! Return crouching state.
+ bool IsCrouching() const { return myIsCrouching; }
+
+ //! Set crouching state.
+ void SetCrouching (bool theIsCrouching) { myIsCrouching = theIsCrouching; }
+
+ //! Return running state.
+ bool IsRunning() const { return myIsRunning; }
+
+ //! Set running state.
+ void SetRunning (bool theIsRunning) { myIsRunning = theIsRunning; }
+
+ //! Return TRUE when both Rotation and Translation deltas are empty.
+ bool IsEmpty() const { return !ToMove() && !ToRotate(); }
+
+ //! Return TRUE if translation delta is defined.
+ bool ToMove() const
+ {
+ return !myTranslation[AIS_WalkTranslation_Forward].IsEmpty()
+ || !myTranslation[AIS_WalkTranslation_Side].IsEmpty()
+ || !myTranslation[AIS_WalkTranslation_Up].IsEmpty();
+ }
+
+ //! Return TRUE if rotation delta is defined.
+ bool ToRotate() const
+ {
+ return !myRotation[AIS_WalkRotation_Yaw].IsEmpty()
+ || !myRotation[AIS_WalkRotation_Pitch].IsEmpty()
+ || !myRotation[AIS_WalkRotation_Roll].IsEmpty();
+ }
+
+private:
+
+ AIS_WalkPart myTranslation[3];
+ AIS_WalkPart myRotation[3];
+ bool myIsJumping;
+ bool myIsCrouching;
+ bool myIsRunning;
+
+};
+
+#endif // _AIS_WalkDelta_HeaderFile
AIS_DisplayMode.hxx
AIS_DisplaySpecialSymbol.hxx
AIS_DisplayStatus.hxx
+AIS_DragAction.hxx
AIS_EllipseRadiusDimension.cxx
AIS_EllipseRadiusDimension.hxx
AIS_EqualDistanceRelation.cxx
AIS_MaxRadiusDimension.hxx
AIS_MediaPlayer.cxx
AIS_MediaPlayer.hxx
+AIS_MouseGesture.hxx
AIS_MidPointRelation.cxx
AIS_MidPointRelation.hxx
AIS_MidPointRelation.lxx
AIS_MultipleConnectedInteractive.cxx
AIS_MultipleConnectedInteractive.hxx
AIS_MultipleConnectedInteractive.lxx
+AIS_NavigationMode.hxx
AIS_NListOfEntityOwner.hxx
AIS_OffsetDimension.cxx
AIS_OffsetDimension.hxx
AIS_RadiusDimension.hxx
AIS_Relation.cxx
AIS_Relation.hxx
+AIS_RotationMode.hxx
AIS_RubberBand.hxx
AIS_RubberBand.cxx
AIS_Selection.cxx
AIS_TypeOfDist.hxx
AIS_TypeOfIso.hxx
AIS_TypeOfPlane.hxx
+AIS_ViewController.cxx
+AIS_ViewController.hxx
+AIS_ViewInputBuffer.hxx
+AIS_WalkDelta.hxx
--- /dev/null
+// Copyright (c) 2019 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_ScrollDelta_HeaderFile
+#define _Aspect_ScrollDelta_HeaderFile
+
+#include <Aspect_VKeyFlags.hxx>
+#include <NCollection_Vec2.hxx>
+#include <Standard_Real.hxx>
+
+//! Parameters for mouse scroll action.
+struct Aspect_ScrollDelta
+{
+
+ NCollection_Vec2<int> Point; //!< scale position
+ Standard_Real Delta; //!< delta in pixels
+ Aspect_VKeyFlags Flags; //!< key flags
+
+ //! Return true if action has point defined.
+ bool HasPoint() const
+ {
+ return Point.x() >= 0
+ && Point.y() >= 0;
+ }
+
+ //! Reset at point.
+ void ResetPoint()
+ {
+ Point.SetValues (-1, -1);
+ }
+
+ //! Empty constructor.
+ Aspect_ScrollDelta()
+ : Point (-1, -1), Delta (0.0), Flags (Aspect_VKeyFlags_NONE) {}
+
+ //! Constructor.
+ Aspect_ScrollDelta (const NCollection_Vec2<int>& thePnt,
+ Standard_Real theValue,
+ Aspect_VKeyFlags theFlags = Aspect_VKeyFlags_NONE)
+ : Point (thePnt), Delta (theValue), Flags (theFlags) {}
+
+ //! Constructor with undefined point.
+ Aspect_ScrollDelta (Standard_Real theValue,
+ Aspect_VKeyFlags theFlags = Aspect_VKeyFlags_NONE)
+ : Point (-1, -1), Delta (theValue), Flags (theFlags) {}
+
+};
+
+#endif // _Aspect_ScrollDelta_HeaderFile
--- /dev/null
+// Copyright (c) 2016-2019 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_Touch_HeaderFile
+#define _Aspect_Touch_HeaderFile
+
+#include <NCollection_Vec2.hxx>
+#include <Standard_Boolean.hxx>
+#include <Standard_Real.hxx>
+
+//! Structure holding touch position - original and current location.
+class Aspect_Touch
+{
+public:
+
+ NCollection_Vec2<Standard_Real> From; //!< original touch position
+ NCollection_Vec2<Standard_Real> To; //!< current touch position
+ Standard_Boolean IsPreciseDevice; //!< precise device input (e.g. mouse cursor, NOT emulated from touch screen)
+
+ //! Return values delta.
+ NCollection_Vec2<Standard_Real> Delta() const { return To - From; }
+
+ //! Empty constructor
+ Aspect_Touch()
+ : From (0.0, 0.0), To (0.0, 0.0), IsPreciseDevice (false) {}
+
+ //! Constructor with initialization.
+ Aspect_Touch (const NCollection_Vec2<Standard_Real>& thePnt,
+ Standard_Boolean theIsPreciseDevice)
+ : From (thePnt), To (thePnt), IsPreciseDevice (theIsPreciseDevice) {}
+
+ //! Constructor with initialization.
+ Aspect_Touch (Standard_Real theX, Standard_Real theY,
+ Standard_Boolean theIsPreciseDevice)
+ : From (theX, theY), To (theX, theY), IsPreciseDevice (theIsPreciseDevice) {}
+
+};
+
+#endif // _Aspect_Touch_HeaderFile
--- /dev/null
+// Copyright (c) 2016-2019 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_TouchMap_HeaderFile
+#define _Aspect_TouchMap_HeaderFile
+
+#include <Aspect_Touch.hxx>
+
+#include <NCollection_IndexedDataMap.hxx>
+
+typedef NCollection_IndexedDataMap<Standard_Size, Aspect_Touch> Aspect_TouchMap;
+
+#endif // _Aspect_TouchMap_HeaderFile
--- /dev/null
+// Copyright (c) 2016-2019 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_VKey_HeaderFile
+#define _Aspect_VKey_HeaderFile
+
+#include <Aspect_VKeyFlags.hxx>
+
+//! Define virtual key as integer number to allow extensions.
+typedef unsigned int Aspect_VKey;
+
+//! Enumeration defining virtual keys irrelevant to current keyboard layout for simplified hot-keys management logic.
+enum Aspect_VKeyBasic
+{
+ Aspect_VKey_UNKNOWN = 0,
+
+ // main latin alphabet keys
+ Aspect_VKey_A = 1,
+ Aspect_VKey_B,
+ Aspect_VKey_C,
+ Aspect_VKey_D,
+ Aspect_VKey_E,
+ Aspect_VKey_F,
+ Aspect_VKey_G,
+ Aspect_VKey_H,
+ Aspect_VKey_I,
+ Aspect_VKey_J,
+ Aspect_VKey_K,
+ Aspect_VKey_L,
+ Aspect_VKey_M,
+ Aspect_VKey_N,
+ Aspect_VKey_O,
+ Aspect_VKey_P,
+ Aspect_VKey_Q,
+ Aspect_VKey_R,
+ Aspect_VKey_S,
+ Aspect_VKey_T,
+ Aspect_VKey_U,
+ Aspect_VKey_V,
+ Aspect_VKey_W,
+ Aspect_VKey_X,
+ Aspect_VKey_Y,
+ Aspect_VKey_Z,
+
+ Aspect_VKey_0,
+ Aspect_VKey_1,
+ Aspect_VKey_2,
+ Aspect_VKey_3,
+ Aspect_VKey_4,
+ Aspect_VKey_5,
+ Aspect_VKey_6,
+ Aspect_VKey_7,
+ Aspect_VKey_8,
+ Aspect_VKey_9,
+
+ Aspect_VKey_F1,
+ Aspect_VKey_F2,
+ Aspect_VKey_F3,
+ Aspect_VKey_F4,
+ Aspect_VKey_F5,
+ Aspect_VKey_F6,
+ Aspect_VKey_F7,
+ Aspect_VKey_F8,
+ Aspect_VKey_F9,
+ Aspect_VKey_F10,
+ Aspect_VKey_F11,
+ Aspect_VKey_F12,
+
+ // standard keys
+ Aspect_VKey_Up,
+ Aspect_VKey_Down,
+ Aspect_VKey_Left,
+ Aspect_VKey_Right,
+ Aspect_VKey_Plus, //!< '+'
+ Aspect_VKey_Minus, //!< '-'
+ Aspect_VKey_Equal, //!< '=+'
+ Aspect_VKey_PageUp,
+ Aspect_VKey_PageDown,
+ Aspect_VKey_Home,
+ Aspect_VKey_End,
+ Aspect_VKey_Escape,
+ Aspect_VKey_Back,
+ Aspect_VKey_Enter,
+ Aspect_VKey_Backspace,
+ Aspect_VKey_Space,
+ Aspect_VKey_Delete,
+ Aspect_VKey_Tilde,
+ Aspect_VKey_Tab,
+ Aspect_VKey_Comma, //!< ','
+ Aspect_VKey_Period, //!< '.'
+ Aspect_VKey_Semicolon, //!< ';:'
+ Aspect_VKey_Slash, //!< '/?'
+ Aspect_VKey_BracketLeft, //!< '[{'
+ Aspect_VKey_Backslash, //!< '\|'
+ Aspect_VKey_BracketRight, //!< ']}'
+ Aspect_VKey_Apostrophe, //!< ''"'
+ Aspect_VKey_Numlock, //!< Num Lock key
+ Aspect_VKey_Scroll, //!< Scroll Lock key
+
+ // numpad keys
+ Aspect_VKey_Numpad0,
+ Aspect_VKey_Numpad1,
+ Aspect_VKey_Numpad2,
+ Aspect_VKey_Numpad3,
+ Aspect_VKey_Numpad4,
+ Aspect_VKey_Numpad5,
+ Aspect_VKey_Numpad6,
+ Aspect_VKey_Numpad7,
+ Aspect_VKey_Numpad8,
+ Aspect_VKey_Numpad9,
+ Aspect_VKey_NumpadMultiply, //!< numpad '*'
+ Aspect_VKey_NumpadAdd, //!< numpad '+'
+ Aspect_VKey_NumpadSubtract, //!< numpad '-'
+ Aspect_VKey_NumpadDivide, //!< numpad '/'
+
+ // Multimedia keys
+ Aspect_VKey_MediaNextTrack,
+ Aspect_VKey_MediaPreviousTrack,
+ Aspect_VKey_MediaStop,
+ Aspect_VKey_MediaPlayPause,
+ Aspect_VKey_VolumeMute,
+ Aspect_VKey_VolumeDown,
+ Aspect_VKey_VolumeUp,
+ Aspect_VKey_BrowserBack,
+ Aspect_VKey_BrowserForward,
+ Aspect_VKey_BrowserRefresh,
+ Aspect_VKey_BrowserStop,
+ Aspect_VKey_BrowserSearch,
+ Aspect_VKey_BrowserFavorites,
+ Aspect_VKey_BrowserHome,
+
+ // modifier keys, @sa Aspect_VKey_ModifiersLower and Aspect_VKey_ModifiersUpper below
+ Aspect_VKey_Shift,
+ Aspect_VKey_Control,
+ Aspect_VKey_Alt,
+ Aspect_VKey_Menu,
+ Aspect_VKey_Meta,
+
+ // virtual navigation keys, @sa Aspect_VKey_NavigationKeysLower and Aspect_VKey_NavigationKeysUpper below
+ Aspect_VKey_NavInteract, //!< interact
+ Aspect_VKey_NavForward, //!< go forward
+ Aspect_VKey_NavBackward, //!< go backward
+ Aspect_VKey_NavSlideLeft, //!< sidewalk, left
+ Aspect_VKey_NavSlideRight, //!< sidewalk, right
+ Aspect_VKey_NavSlideUp, //!< lift up
+ Aspect_VKey_NavSlideDown, //!< fall down
+ Aspect_VKey_NavRollCCW, //!< bank left (roll counter-clockwise)
+ Aspect_VKey_NavRollCW, //!< bank right (roll clockwise)
+ Aspect_VKey_NavLookLeft, //!< look left (yaw counter-clockwise)
+ Aspect_VKey_NavLookRight, //!< look right (yaw clockwise)
+ Aspect_VKey_NavLookUp, //!< look up (pitch clockwise)
+ Aspect_VKey_NavLookDown, //!< look down (pitch counter-clockwise)
+ Aspect_VKey_NavCrouch, //!< crouch walking
+ Aspect_VKey_NavJump, //!< jump
+ Aspect_VKey_NavThrustForward, //!< increase continuous velocity in forward direction
+ Aspect_VKey_NavThrustBackward, //!< increase continuous velocity in reversed direction
+ Aspect_VKey_NavThrustStop, //!< reset continuous velocity
+ Aspect_VKey_NavSpeedIncrease, //!< increase navigation speed
+ Aspect_VKey_NavSpeedDecrease, //!< decrease navigation speed
+};
+
+//! Auxiliary ranges.
+enum
+{
+ Aspect_VKey_Lower = 0,
+ Aspect_VKey_ModifiersLower = Aspect_VKey_Shift,
+ Aspect_VKey_ModifiersUpper = Aspect_VKey_Meta,
+ Aspect_VKey_NavigationKeysLower = Aspect_VKey_NavInteract,
+ Aspect_VKey_NavigationKeysUpper = Aspect_VKey_NavSpeedDecrease,
+ Aspect_VKey_Upper = Aspect_VKey_NavSpeedDecrease,
+ Aspect_VKey_NB = Aspect_VKey_Upper - Aspect_VKey_Lower + 1,
+ Aspect_VKey_MAX = 255
+};
+
+//! Return modifier flags for specified modifier key.
+inline Aspect_VKeyFlags Aspect_VKey2Modifier (Aspect_VKey theKey)
+{
+ switch (theKey)
+ {
+ case Aspect_VKey_Shift: return Aspect_VKeyFlags_SHIFT;
+ case Aspect_VKey_Control: return Aspect_VKeyFlags_CTRL;
+ case Aspect_VKey_Alt: return Aspect_VKeyFlags_ALT;
+ case Aspect_VKey_Menu: return Aspect_VKeyFlags_MENU;
+ case Aspect_VKey_Meta: return Aspect_VKeyFlags_META;
+ default: return 0;
+ }
+}
+
+#endif // _Aspect_VKey_HeaderFile
--- /dev/null
+// Copyright (c) 2016-2019 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_VKeyFlags_HeaderFile
+#define _Aspect_VKeyFlags_HeaderFile
+
+//! Key modifier, for combining with general key from Aspect_VKey.
+typedef unsigned int Aspect_VKeyFlags;
+
+//! Key modifier, for combining with general key from Aspect_VKey.
+enum
+{
+ Aspect_VKeyFlags_NONE = 0,
+ // reserve first 8 bits to combine value with Aspect_VKey
+ Aspect_VKeyFlags_SHIFT = 1 << 8, //!< Aspect_VKey_Shift
+ Aspect_VKeyFlags_CTRL = 1 << 9, //!< Aspect_VKey_Control
+ Aspect_VKeyFlags_ALT = 1 << 10, //!< Aspect_VKey_Alt
+ Aspect_VKeyFlags_MENU = 1 << 11, //!< Aspect_VKey_Menu
+ Aspect_VKeyFlags_META = 1 << 12, //!< Aspect_VKey_Meta
+
+ Aspect_VKeyFlags_ALL = Aspect_VKeyFlags_SHIFT | Aspect_VKeyFlags_CTRL | Aspect_VKeyFlags_ALT | Aspect_VKeyFlags_MENU | Aspect_VKeyFlags_META
+};
+
+//! Mouse buttons, for combining with Aspect_VKey and Aspect_VKeyFlags.
+typedef unsigned int Aspect_VKeyMouse;
+
+//! Mouse button bitmask
+enum
+{
+ Aspect_VKeyMouse_NONE = 0, //!< no buttons
+
+ Aspect_VKeyMouse_LeftButton = 1 << 13, //!< mouse left button
+ Aspect_VKeyMouse_MiddleButton = 1 << 14, //!< mouse middle button (scroll)
+ Aspect_VKeyMouse_RightButton = 1 << 15, //!< mouse right button
+
+ Aspect_VKeyMouse_MainButtons = Aspect_VKeyMouse_LeftButton | Aspect_VKeyMouse_MiddleButton | Aspect_VKeyMouse_RightButton
+};
+
+#endif // _Aspect_VKeyFlags_HeaderFile
--- /dev/null
+// Copyright (c) 2016-2019 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_VKeySet.hxx"
+
+IMPLEMENT_STANDARD_RTTIEXT(Aspect_VKeySet, Standard_Transient)
+
+// ================================================================
+// Function : As1pect_VKeySet
+// Purpose :
+// ================================================================
+Aspect_VKeySet::Aspect_VKeySet()
+: myKeys (0, Aspect_VKey_MAX),
+ myModifiers (Aspect_VKeyFlags_NONE)
+{
+ //
+}
+
+// ================================================================
+// Function : Reset
+// Purpose :
+// ================================================================
+void Aspect_VKeySet::Reset()
+{
+ Standard_Mutex::Sentry aLock (myLock);
+ myModifiers = 0;
+ for (NCollection_Array1<KeyState>::Iterator aKeyIter (myKeys); aKeyIter.More(); aKeyIter.Next())
+ {
+ aKeyIter.ChangeValue().Reset();
+ }
+}
+
+// ================================================================
+// Function : KeyDown
+// Purpose :
+// ================================================================
+void Aspect_VKeySet::KeyDown (Aspect_VKey theKey,
+ double theTime,
+ double thePressure)
+{
+ Standard_Mutex::Sentry aLock (myLock);
+ if (myKeys[theKey].Status != KeyStatus_Pressed)
+ {
+ myKeys[theKey].Status = KeyStatus_Pressed;
+ myKeys[theKey].TimeDown = theTime;
+ }
+ myKeys[theKey].Pressure = thePressure;
+
+ const unsigned int aModif = Aspect_VKey2Modifier (theKey);
+ myModifiers = myModifiers | aModif;
+}
+
+// ================================================================
+// Function : KeyUp
+// Purpose :
+// ================================================================
+void Aspect_VKeySet::KeyUp (Aspect_VKey theKey,
+ double theTime)
+{
+ Standard_Mutex::Sentry aLock (myLock);
+ if (myKeys[theKey].Status == KeyStatus_Pressed)
+ {
+ myKeys[theKey].Status = KeyStatus_Released;
+ myKeys[theKey].TimeUp = theTime;
+ }
+
+ const unsigned int aModif = Aspect_VKey2Modifier (theKey);
+ if (aModif != 0)
+ {
+ myModifiers = myModifiers & ~aModif;
+ }
+}
+
+// ================================================================
+// Function : KeyFromAxis
+// Purpose :
+// ================================================================
+void Aspect_VKeySet::KeyFromAxis (Aspect_VKey theNegative,
+ Aspect_VKey thePositive,
+ double theTime,
+ double thePressure)
+{
+ Standard_Mutex::Sentry aLock (myLock);
+ if (thePressure != 0)
+ {
+ const Aspect_VKey aKeyDown = thePressure > 0 ? thePositive : theNegative;
+ const Aspect_VKey aKeyUp = thePressure < 0 ? thePositive : theNegative;
+
+ KeyDown (aKeyDown, theTime, Abs (thePressure));
+ if (myKeys[aKeyUp].Status == KeyStatus_Pressed)
+ {
+ KeyUp (aKeyUp, theTime);
+ }
+ }
+ else
+ {
+ if (myKeys[theNegative].Status == KeyStatus_Pressed)
+ {
+ KeyUp (theNegative, theTime);
+ }
+ if (myKeys[thePositive].Status == KeyStatus_Pressed)
+ {
+ KeyUp (thePositive, theTime);
+ }
+ }
+}
+
+// ================================================================
+// Function : HoldDuration
+// Purpose :
+// ================================================================
+bool Aspect_VKeySet::HoldDuration (Aspect_VKey theKey,
+ double theTime,
+ double& theDuration,
+ double& thePressure)
+{
+ Standard_Mutex::Sentry aLock (myLock);
+ switch (myKeys[theKey].Status)
+ {
+ case KeyStatus_Free:
+ {
+ theDuration = 0.0;
+ return false;
+ }
+ case KeyStatus_Released:
+ {
+ myKeys[theKey].Status = KeyStatus_Free;
+ theDuration = myKeys[theKey].TimeUp - myKeys[theKey].TimeDown;
+ thePressure = myKeys[theKey].Pressure;
+ return true;
+ }
+ case KeyStatus_Pressed:
+ {
+ theDuration = theTime - myKeys[theKey].TimeDown;
+ thePressure = myKeys[theKey].Pressure;
+ return true;
+ }
+ }
+ return false;
+}
--- /dev/null
+// Copyright (c) 2016-2019 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_VKeySet_HeaderFile
+#define _Aspect_VKeySet_HeaderFile
+
+#include <Aspect_VKey.hxx>
+
+#include <NCollection_Array1.hxx>
+#include <OSD_Timer.hxx>
+#include <Standard_Mutex.hxx>
+#include <Standard_Transient.hxx>
+
+//! Structure defining key state.
+class Aspect_VKeySet : public Standard_Transient
+{
+ DEFINE_STANDARD_RTTIEXT(Aspect_VKeySet, Standard_Transient)
+public:
+
+ //! Main constructor.
+ Standard_EXPORT Aspect_VKeySet();
+
+ //! Return active modifiers.
+ Aspect_VKeyFlags Modifiers() const
+ {
+ Standard_Mutex::Sentry aLock (myLock);
+ return myModifiers;
+ }
+
+ //! Return timestamp of press event.
+ double DownTime (Aspect_VKey theKey) const
+ {
+ Standard_Mutex::Sentry aLock (myLock);
+ return myKeys[theKey].TimeDown;
+ }
+
+ //! Return timestamp of release event.
+ double TimeUp (Aspect_VKey theKey) const
+ {
+ Standard_Mutex::Sentry aLock (myLock);
+ return myKeys[theKey].TimeUp;
+ }
+
+ //! Return TRUE if key is in Free state.
+ bool IsFreeKey (Aspect_VKey theKey) const
+ {
+ Standard_Mutex::Sentry aLock (myLock);
+ return myKeys[theKey].Status == KeyStatus_Free;
+ }
+
+ //! Return TRUE if key is in Pressed state.
+ bool IsKeyDown (Aspect_VKey theKey) const
+ {
+ Standard_Mutex::Sentry aLock (myLock);
+ return myKeys[theKey].Status == KeyStatus_Pressed;
+ }
+
+public:
+
+ //! Reset the key state into unpressed state.
+ Standard_EXPORT void Reset();
+
+ //! Press key.
+ //! @param theKey key pressed
+ //! @param theTime event timestamp
+ Standard_EXPORT void KeyDown (Aspect_VKey theKey,
+ double theTime,
+ double thePressure = 1.0);
+
+ //! Release key.
+ //! @param theKey key pressed
+ //! @param theTime event timestamp
+ Standard_EXPORT void KeyUp (Aspect_VKey theKey,
+ double theTime);
+
+ //! Simulate key up/down events from axis value.
+ Standard_EXPORT void KeyFromAxis (Aspect_VKey theNegative,
+ Aspect_VKey thePositive,
+ double theTime,
+ double thePressure);
+
+ //! Return duration of the button in pressed state.
+ //! @param theKey key to check
+ //! @param theTime current time (for computing duration from key down time)
+ //! @param theDuration key press duration
+ //! @return TRUE if key was in pressed state
+ bool HoldDuration (Aspect_VKey theKey,
+ double theTime,
+ double& theDuration)
+ {
+ double aPressure = -1.0;
+ return HoldDuration (theKey, theTime, theDuration, aPressure);
+ }
+
+ //! Return duration of the button in pressed state.
+ //! @param theKey key to check
+ //! @param theTime current time (for computing duration from key down time)
+ //! @param theDuration key press duration
+ //! @param thePressure key pressure
+ //! @return TRUE if key was in pressed state
+ Standard_EXPORT bool HoldDuration (Aspect_VKey theKey,
+ double theTime,
+ double& theDuration,
+ double& thePressure);
+
+private:
+
+ //! Key state.
+ enum KeyStatus
+ {
+ KeyStatus_Free, //!< free status
+ KeyStatus_Pressed, //!< key is in pressed state
+ KeyStatus_Released, //!< key has been just released (transient state before KeyStatus_Free)
+ };
+
+ //! Structure defining key state.
+ struct KeyState
+ {
+ KeyState() : TimeDown (0.0), TimeUp (0.0), Pressure (1.0), Status (KeyStatus_Free) {}
+ void Reset()
+ {
+ Status = KeyStatus_Free;
+ TimeDown = 0.0;
+ TimeUp = 0.0;
+ Pressure = 1.0;
+ }
+
+ double TimeDown; //!< time of key press event
+ double TimeUp; //!< time of key release event
+ double Pressure; //!< key pressure
+ KeyStatus Status; //!< key status
+ };
+
+private:
+
+ NCollection_Array1<KeyState> myKeys; //!< keys state
+ mutable Standard_Mutex myLock; //!< mutex for thread-safe updates
+ Aspect_VKeyFlags myModifiers; //!< active modifiers
+
+};
+
+#endif // _Aspect_VKeySet_HeaderFile
#ifndef _Aspect_Window_HeaderFile
#define _Aspect_Window_HeaderFile
-#include <Standard.hxx>
-#include <Standard_Type.hxx>
-
#include <Aspect_Background.hxx>
#include <Aspect_GradientBackground.hxx>
#include <Aspect_FBConfig.hxx>
#include <Aspect_FillMethod.hxx>
-#include <Standard_Boolean.hxx>
-#include <Standard_Transient.hxx>
#include <Quantity_Color.hxx>
#include <Aspect_GradientFillMethod.hxx>
#include <Aspect_TypeOfResize.hxx>
-#include <Standard_Integer.hxx>
#include <Aspect_Drawable.hxx>
+#include <Standard.hxx>
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+#include <TCollection_AsciiString.hxx>
class Aspect_DisplayConnection;
-class Aspect_WindowDefinitionError;
-class Aspect_WindowError;
-class Aspect_Background;
-class Aspect_GradientBackground;
-class Aspect_Window;
DEFINE_STANDARD_HANDLE(Aspect_Window, Standard_Transient)
//! Defines a window.
//! Returns native Window FB config (GLXFBConfig on Xlib)
Standard_EXPORT virtual Aspect_FBConfig NativeFBConfig() const = 0;
+ //! Sets window title.
+ virtual void SetTitle (const TCollection_AsciiString& theTitle) { (void )theTitle; }
+
//! Invalidate entire window content.
//!
//! Implementation is expected to allow calling this method from non-GUI thread,
Aspect_RectangularGrid.hxx
Aspect_RenderingContext.hxx
Aspect_SequenceOfColor.hxx
+Aspect_ScrollDelta.hxx
+Aspect_Touch.hxx
+Aspect_TouchMap.hxx
Aspect_TypeOfColorScaleData.hxx
Aspect_TypeOfColorScaleOrientation.hxx
Aspect_TypeOfColorScalePosition.hxx
Aspect_TypeOfStyleText.hxx
Aspect_TypeOfTriedronPosition.hxx
Aspect_Units.hxx
+Aspect_VKey.hxx
+Aspect_VKeyFlags.hxx
+Aspect_VKeySet.cxx
+Aspect_VKeySet.hxx
Aspect_WidthOfLine.hxx
Aspect_Window.cxx
Aspect_Window.hxx
#include <Aspect_GradientFillMethod.hxx>
#include <Aspect_Handle.hxx>
#include <Aspect_TypeOfResize.hxx>
+#include <Aspect_VKey.hxx>
#include <Quantity_NameOfColor.hxx>
class Aspect_WindowDefinitionError;
//! This class defines Cocoa window
class Cocoa_Window : public Aspect_Window
{
+public:
+
+ //! Convert Carbon virtual key into Aspect_VKey.
+ Standard_EXPORT static Aspect_VKey VirtualKeyFromNative (Standard_Integer theKey);
public:
//! Returns nothing on OS X
virtual Aspect_FBConfig NativeFBConfig() const Standard_OVERRIDE { return NULL; }
+ //! Sets window title.
+ Standard_EXPORT virtual void SetTitle (const TCollection_AsciiString& theTitle) Standard_OVERRIDE;
+
//! Invalidate entire window content by setting NSView::setNeedsDisplay property.
//! Call will be implicitly redirected to the main thread when called from non-GUI thread.
Standard_EXPORT virtual void InvalidateContent (const Handle(Aspect_DisplayConnection)& theDisp = NULL) Standard_OVERRIDE;
theHeight = (Standard_Integer )aBounds.size.height;
}
+// =======================================================================
+// function : SetTitle
+// purpose :
+// =======================================================================
+void Cocoa_Window::SetTitle (const TCollection_AsciiString& theTitle)
+{
+ if (myHView == NULL)
+ {
+ return;
+ }
+
+#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+ (void )theTitle;
+#else
+ NSWindow* aWindow = [myHView window];
+ NSString* aTitleNS = [[NSString alloc] initWithUTF8String: theTitle.ToCString()];
+ [aWindow setTitle: aTitleNS];
+ [aTitleNS release];
+#endif
+}
+
// =======================================================================
// function : InvalidateContent
// purpose :
waitUntilDone: NO];
}
}
+
+// =======================================================================
+// function : VirtualKeyFromNative
+// purpose :
+// =======================================================================
+Aspect_VKey Cocoa_Window::VirtualKeyFromNative (Standard_Integer theKey)
+{
+ switch (theKey)
+ {
+ case 0x00: return Aspect_VKey_A;
+ case 0x01: return Aspect_VKey_S;
+ case 0x02: return Aspect_VKey_D;
+ case 0x03: return Aspect_VKey_F;
+ case 0x04: return Aspect_VKey_H;
+ case 0x05: return Aspect_VKey_G;
+ case 0x06: return Aspect_VKey_Z;
+ case 0x07: return Aspect_VKey_X;
+ case 0x08: return Aspect_VKey_C;
+ case 0x09: return Aspect_VKey_V;
+ case 0x0A: return Aspect_VKey_UNKNOWN;
+ case 0x0B: return Aspect_VKey_B;
+ case 0x0C: return Aspect_VKey_Q;
+ case 0x0D: return Aspect_VKey_W;
+ case 0x0E: return Aspect_VKey_E;
+ case 0x0F: return Aspect_VKey_R;
+ case 0x10: return Aspect_VKey_Y;
+ case 0x11: return Aspect_VKey_T;
+ case 0x12: return Aspect_VKey_1;
+ case 0x13: return Aspect_VKey_2;
+ case 0x14: return Aspect_VKey_3;
+ case 0x15: return Aspect_VKey_4;
+ case 0x16: return Aspect_VKey_6;
+ case 0x17: return Aspect_VKey_5;
+ case 0x18: return Aspect_VKey_Plus;
+ case 0x19: return Aspect_VKey_9;
+ case 0x1A: return Aspect_VKey_7;
+ case 0x1B: return Aspect_VKey_Minus;
+ case 0x1C: return Aspect_VKey_8;
+ case 0x1D: return Aspect_VKey_0;
+ case 0x1E: return Aspect_VKey_BracketRight;
+ case 0x1F: return Aspect_VKey_O;
+ case 0x20: return Aspect_VKey_U;
+ case 0x21: return Aspect_VKey_BracketLeft;
+ case 0x22: return Aspect_VKey_I;
+ case 0x23: return Aspect_VKey_P;
+ case 0x24: return Aspect_VKey_Enter;
+ case 0x25: return Aspect_VKey_L;
+ case 0x26: return Aspect_VKey_J;
+ case 0x27: return Aspect_VKey_Apostrophe;
+ case 0x28: return Aspect_VKey_K;
+ case 0x29: return Aspect_VKey_Semicolon;
+ case 0x2A: return Aspect_VKey_Backslash;
+ case 0x2B: return Aspect_VKey_Comma; // 43, ',<'
+ case 0x2C: return Aspect_VKey_Slash; //ST_VK_OEM_2, // 44, '?/'
+ case 0x2D: return Aspect_VKey_N;
+ case 0x2E: return Aspect_VKey_M;
+ case 0x2F: return Aspect_VKey_Period; // 47, '.>'
+ case 0x30: return Aspect_VKey_Tab;
+ case 0x31: return Aspect_VKey_Space;
+ case 0x32: return Aspect_VKey_Tilde; // '~`'
+ case 0x33: return Aspect_VKey_Backspace;
+ case 0x34: return Aspect_VKey_UNKNOWN;
+ case 0x35: return Aspect_VKey_Escape;
+ case 0x36: return Aspect_VKey_UNKNOWN; // Aspect_VKey_Cmd, right Command
+ case 0x37: return Aspect_VKey_UNKNOWN; // Aspect_VKey_Cmd, left Command
+ case 0x38: return Aspect_VKey_Shift; // left shift
+ case 0x39: return Aspect_VKey_UNKNOWN;
+ case 0x3A: return Aspect_VKey_Alt; // left alt/option
+ case 0x3B: return Aspect_VKey_Control;
+ case 0x3C: return Aspect_VKey_Shift; // right shift
+ case 0x3D: return Aspect_VKey_Alt; // right alt/option
+ case 0x3E: return Aspect_VKey_UNKNOWN;
+ case 0x3F: return Aspect_VKey_UNKNOWN; // Aspect_VKey_Func, fn
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4A:
+ case 0x4B: return Aspect_VKey_UNKNOWN;
+ case 0x4C: return Aspect_VKey_Enter; // fn + return
+ case 0x4D:
+ case 0x4E:
+ case 0x4F:
+ case 0x50:
+ case 0x51:
+ case 0x52:
+ case 0x53:
+ case 0x54:
+ case 0x55:
+ case 0x56:
+ case 0x57:
+ case 0x58:
+ case 0x59:
+ case 0x5A:
+ case 0x5B:
+ case 0x5C:
+ case 0x5D:
+ case 0x5E:
+ case 0x5F: return Aspect_VKey_UNKNOWN;
+ case 0x60: return Aspect_VKey_F5;
+ case 0x61: return Aspect_VKey_F6;
+ case 0x62: return Aspect_VKey_F7;
+ case 0x63: return Aspect_VKey_F3;
+ case 0x64: return Aspect_VKey_F8;
+ case 0x65: return Aspect_VKey_F9;
+ //case 0x66: return Aspect_VKey_UNKNOWN;
+ case 0x67: return Aspect_VKey_F11;
+ //case 0x68: return Aspect_VKey_UNKNOWN;
+ //case 0x69: return Aspect_VKey_UNKNOWN;
+ //case 0x6A: return Aspect_VKey_UNKNOWN;
+ //case 0x6B: return Aspect_VKey_UNKNOWN;
+ //case 0x6C: return Aspect_VKey_UNKNOWN;
+ case 0x6D: return Aspect_VKey_F10;
+ //case 0x6E: return Aspect_VKey_UNKNOWN;
+ case 0x6F: return Aspect_VKey_F12;
+ //case 0x70: return Aspect_VKey_UNKNOWN;
+ //case 0x71: return Aspect_VKey_UNKNOWN;
+ //case 0x72: return Aspect_VKey_UNKNOWN;
+ case 0x73: return Aspect_VKey_Home;
+ case 0x74: return Aspect_VKey_PageUp;
+ case 0x75: return Aspect_VKey_Delete;
+ case 0x76: return Aspect_VKey_F4;
+ case 0x77: return Aspect_VKey_End;
+ case 0x78: return Aspect_VKey_F2;
+ case 0x79: return Aspect_VKey_PageDown;
+ case 0x7A: return Aspect_VKey_F1;
+ case 0x7B: return Aspect_VKey_Left;
+ case 0x7C: return Aspect_VKey_Right;
+ case 0x7D: return Aspect_VKey_Down;
+ case 0x7E: return Aspect_VKey_Up;
+ case 0x7F: return Aspect_VKey_UNKNOWN;
+ }
+ return Aspect_VKey_UNKNOWN;
+}
Standard_EXPORT ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
#endif
-static TColStd_MapOfInteger theactivatedmodes(8);
-
#include <AIS_PlaneTrihedron.hxx>
#include <TopoDS_Face.hxx>
#include <TopExp_Explorer.hxx>
//purpose :
//=============================================================================
V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView theType)
-: MyViewer (theViewer.operator->()),
+: myIsInvalidatedImmediate (Standard_True),
+ MyViewer (theViewer.operator->()),
SwitchSetFront (Standard_False),
myZRotation (Standard_False),
myTrihedron (new V3d_Trihedron()),
//purpose :
//=============================================================================
V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const Handle(V3d_View)& theView)
-: MyViewer (theViewer.operator->()),
+: myIsInvalidatedImmediate (Standard_True),
+ MyViewer (theViewer.operator->()),
SwitchSetFront(Standard_False),
myZRotation (Standard_False),
MyTrsf (1, 4, 1, 4)
return;
}
+ myIsInvalidatedImmediate = Standard_False;
myView->Update();
myView->Compute();
myView->Redraw();
return;
}
+ myIsInvalidatedImmediate = Standard_False;
Handle(Graphic3d_StructureManager) aStructureMgr = MyViewer->StructureManager();
for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
{
return;
}
+ myIsInvalidatedImmediate = Standard_False;
myView->RedrawImmediate();
}
}
//=======================================================================
-//function : Gravity
+//function : GravityPoint
//purpose :
//=======================================================================
-void V3d_View::Gravity (Standard_Real& theX,
- Standard_Real& theY,
- Standard_Real& theZ) const
+gp_Pnt V3d_View::GravityPoint() const
{
Graphic3d_MapOfStructure aSetOfStructures;
myView->DisplayedStructures (aSetOfStructures);
{
aResult /= aNbPoints;
}
- theX = aResult.X();
- theY = aResult.Y();
- theZ = aResult.Z();
+
+ return aResult;
}
//=======================================================================
Size(x,y);
rx = Standard_Real(Convert(x));
ry = Standard_Real(Convert(y));
- Gravity(gx,gy,gz);
- Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
+ myRotateGravity = GravityPoint();
+ Rotate (0.0, 0.0, 0.0,
+ myRotateGravity.X(), myRotateGravity.Y(), myRotateGravity.Z(),
+ Standard_True);
myZRotation = Standard_False;
if( zRotationThreshold > 0. ) {
Standard_Real dx = Abs(sx - rx/2.);
dy = (sy - Standard_Real(Y)) * M_PI / ry;
}
- Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
+ Rotate (dx, dy, dz,
+ myRotateGravity.X(), myRotateGravity.Y(), myRotateGravity.Z(),
+ Standard_False);
}
//=============================================================================
//! Returns true if cached view content has been invalidated.
Standard_EXPORT Standard_Boolean IsInvalidated() const;
+ //! Returns true if immediate layer content has been invalidated.
+ Standard_Boolean IsInvalidatedImmediate() const { return myIsInvalidatedImmediate; }
+
+ //! Invalidates view content within immediate layer but does not redraw it.
+ void InvalidateImmediate() { myIsInvalidatedImmediate = Standard_True; }
+
//! Must be called when the window supporting the
//! view changes size.
//! if the view is not mapped on a window.
//! Fills in the dictionary with statistic performance info.
Standard_EXPORT void StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const;
+ //! Returns the Objects number and the gravity center of ALL viewable points in the view
+ Standard_EXPORT gp_Pnt GravityPoint() const;
+
DEFINE_STANDARD_RTTIEXT(V3d_View,Standard_Transient)
protected:
//! the objects contained in the view
Standard_EXPORT Standard_Integer MinMax (Standard_Real& Xmin, Standard_Real& Ymin, Standard_Real& Zmin, Standard_Real& Xmax, Standard_Real& Ymax, Standard_Real& Zmax) const;
- //! Returns the Objects number and the gravity center
- //! of ALL viewable points in the view
- Standard_EXPORT void Gravity (Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const;
-
Standard_EXPORT void Init();
//! Returns a new vertex when the grid is activated.
Handle(Graphic3d_Camera) myDefaultCamera;
Handle(Graphic3d_CView) myView;
Standard_Boolean myImmediateUpdate;
+ mutable Standard_Boolean myIsInvalidatedImmediate;
private:
Standard_Integer sy;
Standard_Real rx;
Standard_Real ry;
- Standard_Real gx;
- Standard_Real gy;
- Standard_Real gz;
+ gp_Pnt myRotateGravity;
Standard_Boolean myComputedMode;
Standard_Boolean SwitchSetFront;
Standard_Boolean myZRotation;
ViewerTest_DoubleMapOfInteractiveAndName.hxx
ViewerTest_EventManager.cxx
ViewerTest_EventManager.hxx
-ViewerTest_EventManager.lxx
ViewerTest_FilletCommands.cxx
ViewerTest_ObjectCommands.cxx
ViewerTest_OpenGlCommands.cxx
ViewerTest_RelationCommands.cxx
ViewerTest_ViewerCommands.cxx
ViewerTest_ViewerCommands_1.mm
+ViewerTest_V3dView.cxx
+ViewerTest_V3dView.hxx
return ViewerTest::Display (theName, theObject, Standard_True, theReplaceIfExists);
}
-static TColStd_MapOfInteger theactivatedmodes(8);
-static TColStd_ListOfTransient theEventMgrs;
-
-static void VwrTst_InitEventMgr(const Handle(V3d_View)& aView,
- const Handle(AIS_InteractiveContext)& Ctx)
-{
- theEventMgrs.Clear();
- theEventMgrs.Prepend(new ViewerTest_EventManager(aView, Ctx));
-}
+static NCollection_List<Handle(ViewerTest_EventManager)> theEventMgrs;
static Handle(V3d_View)& a3DView()
{
void ViewerTest::ResetEventManager()
{
- const Handle(V3d_View) aView = ViewerTest::CurrentView();
- VwrTst_InitEventMgr(aView, ViewerTest::GetAISContext());
+ theEventMgrs.Clear();
+ theEventMgrs.Prepend (new ViewerTest_EventManager (ViewerTest::CurrentView(), ViewerTest::GetAISContext()));
}
Handle(ViewerTest_EventManager) ViewerTest::CurrentEventManager()
{
- Handle(ViewerTest_EventManager) EM;
- if(theEventMgrs.IsEmpty()) return EM;
- Handle(Standard_Transient) Tr = theEventMgrs.First();
- EM = Handle(ViewerTest_EventManager)::DownCast (Tr);
- return EM;
+ return !theEventMgrs.IsEmpty()
+ ? theEventMgrs.First()
+ : Handle(ViewerTest_EventManager)();
}
//=======================================================================
#include <ViewerTest_EventManager.hxx>
#include <AIS_InteractiveContext.hxx>
+#include <AIS_Shape.hxx>
#include <Aspect_Grid.hxx>
-#include <Standard_Type.hxx>
-#include <V3d_View.hxx>
+#include <Draw.hxx>
+#include <ViewerTest_V3dView.hxx>
+
+Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
IMPLEMENT_STANDARD_RTTIEXT(ViewerTest_EventManager,Standard_Transient)
const Handle(AIS_InteractiveContext)& theCtx)
: myCtx (theCtx),
myView (theView),
- myX (-1),
- myY (-1)
+ myToPickPnt (Standard_False)
{}
//=======================================================================
-//function : MoveTo
+//function : UpdateMouseButtons
//purpose :
//=======================================================================
-
-void ViewerTest_EventManager::MoveTo (const Standard_Integer theXPix,
- const Standard_Integer theYPix)
+bool ViewerTest_EventManager::UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
+ Aspect_VKeyMouse theButtons,
+ Aspect_VKeyFlags theModifiers,
+ bool theIsEmulated)
{
- Standard_Real aPnt3d[3] = {0.0, 0.0, 0.0};
- if (!myCtx.IsNull()
- && !myView.IsNull())
+ SetAllowRotation (!ViewerTest_V3dView::IsCurrentViewIn2DMode());
+
+ if (theButtons == Aspect_VKeyMouse_LeftButton)
{
- const Standard_Boolean toEchoGrid = myView->Viewer()->Grid()->IsActive()
- && myView->Viewer()->GridEcho();
- switch (myCtx->MoveTo (theXPix, theYPix, myView, !toEchoGrid))
+ if (myToPickPnt && (theModifiers & Aspect_VKeyFlags_CTRL) != 0)
{
- case AIS_SOD_Nothing:
- {
- if (toEchoGrid)
- {
- myView->ConvertToGrid (theXPix, theYPix, aPnt3d[0], aPnt3d[1], aPnt3d[2]);
- myView->Viewer()->ShowGridEcho (myView, Graphic3d_Vertex (aPnt3d[0], aPnt3d[1], aPnt3d[2]));
- myView->RedrawImmediate();
- }
- break;
- }
- default:
- {
- if (toEchoGrid)
- {
- myView->Viewer()->HideGridEcho (myView);
- myView->RedrawImmediate();
- }
- break;
- }
+ Graphic3d_Vec3d anXYZ;
+ myView->Convert (thePoint.x(), thePoint.y(), anXYZ.x(), anXYZ.y(), anXYZ.z());
+ Draw::Set (myPickPntArgVec[0].ToCString(), anXYZ.x());
+ Draw::Set (myPickPntArgVec[1].ToCString(), anXYZ.y());
+ Draw::Set (myPickPntArgVec[2].ToCString(), anXYZ.z());
+ myToPickPnt = false;
}
}
- myX = theXPix;
- myY = theYPix;
+ return AIS_ViewController::UpdateMouseButtons (thePoint, theButtons, theModifiers, theIsEmulated);
}
-//=======================================================================
-//function : Select
+//==============================================================================
+//function : ProcessExpose
//purpose :
-//=======================================================================
-
-void ViewerTest_EventManager::Select (const Standard_Integer theXPressed,
- const Standard_Integer theYPressed,
- const Standard_Integer theXMotion,
- const Standard_Integer theYMotion,
- const Standard_Boolean theIsAutoAllowOverlap)
+//==============================================================================
+void ViewerTest_EventManager::ProcessExpose()
{
- if (myView.IsNull()
- || myCtx.IsNull()
- || Abs (theXPressed - theXMotion) < 2
- || Abs (theYPressed - theYMotion) < 2)
- {
- return;
- }
-
- if (theIsAutoAllowOverlap)
- {
- const Standard_Boolean toAllowOverlap = theYPressed != Min (theYPressed, theYMotion);
- myCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
- }
- myCtx->Select (Min (theXPressed, theXMotion),
- Min (theYPressed, theYMotion),
- Max (theXPressed, theXMotion),
- Max (theYPressed, theYMotion),
- myView,
- Standard_False);
-
- // to restore default state of viewer selector
- if (theIsAutoAllowOverlap)
+ if (!myView.IsNull())
{
- myCtx->MainSelector()->AllowOverlapDetection (Standard_False);
+ myView->Invalidate();
+ FlushViewEvents (myCtx, myView, true);
}
- myView->Redraw();
}
-//=======================================================================
-//function : ShiftSelect
+//==============================================================================
+//function : ProcessConfigure
//purpose :
-//=======================================================================
-
-void ViewerTest_EventManager::ShiftSelect (const Standard_Integer theXPressed,
- const Standard_Integer theYPressed,
- const Standard_Integer theXMotion,
- const Standard_Integer theYMotion,
- const Standard_Boolean theIsAutoAllowOverlap)
+//==============================================================================
+void ViewerTest_EventManager::ProcessConfigure()
{
- if (myView.IsNull()
- || myCtx.IsNull()
- || Abs (theXPressed - theXMotion) < 2
- || Abs (theYPressed - theYMotion) < 2)
+ if (!myView.IsNull())
{
- return;
+ myView->MustBeResized();
+ FlushViewEvents (myCtx, myView, true);
}
-
- if (theIsAutoAllowOverlap)
- {
- const Standard_Boolean toAllowOverlap = theYPressed != Min (theYPressed, theYMotion);
- myCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
- }
- myCtx->ShiftSelect (Min (theXPressed, theXMotion),
- Min (theYPressed, theYMotion),
- Max (theXPressed, theXMotion),
- Max (theYPressed, theYMotion),
- myView,
- Standard_False);
-
- // to restore default state of viewer selector
- if (theIsAutoAllowOverlap)
- {
- myCtx->MainSelector()->AllowOverlapDetection (Standard_False);
- }
- myView->Redraw();
}
//=======================================================================
-//function : Select
+//function : KeyUp
//purpose :
//=======================================================================
-
-void ViewerTest_EventManager::Select()
+void ViewerTest_EventManager::KeyUp (Aspect_VKey theKey,
+ double theTime)
{
- if (myView.IsNull()
- || myCtx.IsNull())
- {
- return;
- }
-
- myCtx->Select (Standard_False);
- myView->Redraw();
+ AIS_ViewController::KeyUp (theKey, theTime);
+ ProcessKeyPress (theKey);
}
-//=======================================================================
-//function : ShiftSelect
+//==============================================================================
+//function : ProcessKeyPress
//purpose :
-//=======================================================================
-
-void ViewerTest_EventManager::ShiftSelect()
+//==============================================================================
+void ViewerTest_EventManager::ProcessKeyPress (Aspect_VKey theKey)
{
- if (myView.IsNull()
- || myCtx.IsNull())
+ if (myCtx.IsNull()
+ || myView.IsNull())
{
return;
}
- myCtx->ShiftSelect (Standard_False);
- myView->Redraw();
-}
-
-//=======================================================================
-//function : Select
-//purpose : Selection with polyline
-//=======================================================================
-
-void ViewerTest_EventManager::Select (const TColgp_Array1OfPnt2d& thePolyline)
-{
- if (myView.IsNull()
- || myCtx.IsNull())
+ switch (theKey)
{
- return;
- }
-
- myCtx->Select (thePolyline, myView, Standard_False);
- myView->Redraw();
-}
+ case Aspect_VKey_A: // AXO
+ {
+ if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
+ {
+ myView->SetProj(V3d_XposYnegZpos);
+ }
+ break;
+ }
+ case Aspect_VKey_D: // Reset
+ {
+ if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
+ {
+ myView->Reset();
+ }
+ break;
+ }
+ case Aspect_VKey_F:
+ {
+ if (myCtx->NbSelected() > 0)
+ {
+ myCtx->FitSelected (myView);
+ }
+ else
+ {
+ myView->FitAll();
+ }
+ break;
+ }
+ case Aspect_VKey_H: // HLR
+ {
+ std::cout << "HLR\n";
+ myView->SetComputedMode (!myView->ComputedMode());
+ myView->Redraw();
+ break;
+ }
+ case Aspect_VKey_P: // Type of HLR
+ {
+ myCtx->DefaultDrawer()->SetTypeOfHLR (myCtx->DefaultDrawer()->TypeOfHLR() == Prs3d_TOH_Algo
+ ? Prs3d_TOH_PolyAlgo
+ : Prs3d_TOH_Algo);
+ if (myCtx->NbSelected() == 0)
+ {
+ AIS_ListOfInteractive aListOfShapes;
+ myCtx->DisplayedObjects (aListOfShapes);
+ for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
+ {
+ if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (anIter.Value()))
+ {
+ aShape->SetTypeOfHLR (aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo
+ ? Prs3d_TOH_Algo
+ : Prs3d_TOH_PolyAlgo);
+ myCtx->Redisplay (aShape, Standard_False);
+ }
+ }
+ }
+ else
+ {
+ for (myCtx->InitSelected(); myCtx->MoreSelected(); myCtx->NextSelected())
+ {
+ if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (myCtx->SelectedInteractive()))
+ {
+ aShape->SetTypeOfHLR (aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo
+ ? Prs3d_TOH_Algo
+ : Prs3d_TOH_PolyAlgo);
+ myCtx->Redisplay (aShape, Standard_False);
+ }
+ }
+ }
+ myCtx->UpdateCurrentViewer();
+ break;
+ }
+ case Aspect_VKey_S:
+ case Aspect_VKey_W:
+ {
+ Standard_Integer aDispMode = AIS_Shaded;
+ if (theKey == Aspect_VKey_S)
+ {
+ aDispMode = AIS_Shaded;
+ std::cout << "setup Shaded display mode\n";
+ }
+ else
+ {
+ aDispMode = AIS_WireFrame;
+ std::cout << "setup WireFrame display mode\n";
+ }
-//=======================================================================
-//function : ShiftSelect
-//purpose : Selection with polyline without erasing of current selection
-//=======================================================================
+ if (myCtx->NbSelected() == 0)
+ {
+ myCtx->SetDisplayMode (aDispMode, true);
+ }
+ else
+ {
+ for (myCtx->InitSelected(); myCtx->MoreSelected(); myCtx->NextSelected())
+ {
+ myCtx->SetDisplayMode (myCtx->SelectedInteractive(), aDispMode, false);
+ }
+ myCtx->UpdateCurrentViewer();
+ }
+ break;
+ }
+ case Aspect_VKey_U: // Unset display mode
+ {
+ std::cout << "reset display mode to defaults\n";
+ if (myCtx->NbSelected() == 0)
+ {
+ myCtx->SetDisplayMode (AIS_WireFrame, true);
+ }
+ else
+ {
+ for (myCtx->InitSelected(); myCtx->MoreSelected(); myCtx->NextSelected())
+ {
+ myCtx->UnsetDisplayMode (myCtx->SelectedInteractive(), false);
+ }
+ myCtx->UpdateCurrentViewer();
+ }
+ break;
+ }
+ case Aspect_VKey_T:
+ {
+ if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
+ {
+ myView->SetProj (V3d_TypeOfOrientation_Zup_Top);
+ }
+ break;
+ }
+ case Aspect_VKey_B:
+ {
+ if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
+ {
+ myView->SetProj (V3d_TypeOfOrientation_Zup_Bottom);
+ }
+ break;
+ }
+ case Aspect_VKey_L:
+ {
+ if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
+ {
+ myView->SetProj (V3d_TypeOfOrientation_Zup_Left);
+ }
+ break;
+ }
+ case Aspect_VKey_R:
+ {
+ if (!ViewerTest_V3dView::IsCurrentViewIn2DMode())
+ {
+ myView->SetProj (V3d_TypeOfOrientation_Zup_Right);
+ }
+ break;
+ }
+ case Aspect_VKey_Comma:
+ {
+ myCtx->HilightNextDetected (myView);
+ break;
+ }
+ case Aspect_VKey_Period:
+ {
+ myCtx->HilightPreviousDetected (myView);
+ break;
+ }
+ case Aspect_VKey_Slash:
+ case Aspect_VKey_NumpadDivide:
+ {
+ Handle(Graphic3d_Camera) aCamera = myView->Camera();
+ if (aCamera->IsStereo())
+ {
+ aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() - 0.01);
+ myView->Redraw();
+ }
+ break;
+ }
+ case Aspect_VKey_NumpadMultiply:
+ {
+ Handle(Graphic3d_Camera) aCamera = myView->Camera();
+ if (aCamera->IsStereo())
+ {
+ aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() + 0.01);
+ myView->Redraw();
+ }
+ break;
+ }
+ case Aspect_VKey_Delete:
+ {
+ if (!myCtx.IsNull()
+ && myCtx->NbSelected() > 0)
+ {
+ Draw_Interprete ("verase");
+ }
+ break;
+ }
+ case Aspect_VKey_Escape:
+ {
+ if (!myCtx.IsNull()
+ && ViewerTest_EventManager::ToCloseViewOnEscape())
+ {
+ Draw_Interprete (ViewerTest_EventManager::ToExitOnCloseView() ? "exit" : "vclose");
+ }
+ }
+ }
-void ViewerTest_EventManager::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline)
-{
- if (myView.IsNull()
- || myCtx.IsNull())
+ if (theKey >= Aspect_VKey_0
+ && theKey <= Aspect_VKey_7)
{
- return;
+ const Standard_Integer aSelMode = theKey - Aspect_VKey_0;
+ bool toEnable = true;
+ if (!myCtx.IsNull())
+ {
+ AIS_ListOfInteractive aPrsList;
+ myCtx->DisplayedObjects (aPrsList);
+ for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More() && toEnable; aPrsIter.Next())
+ {
+ TColStd_ListOfInteger aModes;
+ myCtx->ActivatedModes (aPrsIter.Value(), aModes);
+ for (TColStd_ListOfInteger::Iterator aModeIter (aModes); aModeIter.More() && toEnable; aModeIter.Next())
+ {
+ if (aModeIter.Value() == aSelMode)
+ {
+ toEnable = false;
+ }
+ }
+ }
+ }
+ TCollection_AsciiString aCmd = TCollection_AsciiString ("vselmode ") + aSelMode + (toEnable ? " 1" : " 0");
+ Draw_Interprete (aCmd.ToCString());
}
-
- myCtx->ShiftSelect (thePolyline, myView, Standard_False);
- myView->Redraw();
-}
-
-//=======================================================================
-//function : GetCurrentPosition
-//purpose :
-//=======================================================================
-void ViewerTest_EventManager::GetCurrentPosition (Standard_Integer& theXPix, Standard_Integer& theYPix) const
-{
- theXPix = myX;
- theYPix = myY;
}
#ifndef _ViewerTest_EventManager_HeaderFile
#define _ViewerTest_EventManager_HeaderFile
-#include <Standard.hxx>
-#include <Standard_Type.hxx>
-
-#include <Standard_Integer.hxx>
-#include <Standard_Transient.hxx>
-#include <Standard_Boolean.hxx>
+#include <AIS_ViewController.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
+#include <TCollection_AsciiString.hxx>
+
class AIS_InteractiveContext;
class V3d_View;
-
-class ViewerTest_EventManager;
DEFINE_STANDARD_HANDLE(ViewerTest_EventManager, Standard_Transient)
//! used to manage mouse event (move,select,shiftselect)
//! By default the events are transmitted to interactive context.
-class ViewerTest_EventManager : public Standard_Transient
+class ViewerTest_EventManager : public Standard_Transient, public AIS_ViewController
{
-
+ DEFINE_STANDARD_RTTIEXT(ViewerTest_EventManager, Standard_Transient)
public:
-
- Standard_EXPORT ViewerTest_EventManager(const Handle(V3d_View)& aView, const Handle(AIS_InteractiveContext)& aCtx);
-
- Standard_EXPORT virtual void MoveTo (const Standard_Integer xpix, const Standard_Integer ypix);
-
- Standard_EXPORT virtual void Select();
-
- Standard_EXPORT virtual void ShiftSelect();
-
- Standard_EXPORT virtual void Select (const Standard_Integer theXPressed, const Standard_Integer theYPressed, const Standard_Integer theXMotion, const Standard_Integer theYMotion, const Standard_Boolean theIsAutoAllowOverlap = Standard_True);
-
- Standard_EXPORT virtual void ShiftSelect (const Standard_Integer theXPressed, const Standard_Integer theYPressed, const Standard_Integer theXMotion, const Standard_Integer theYMotion, const Standard_Boolean theIsAutoAllowOverlap = Standard_True);
-
- Standard_EXPORT virtual void Select (const TColgp_Array1OfPnt2d& thePolyline);
-
- Standard_EXPORT virtual void ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline);
-
- const Handle(AIS_InteractiveContext)& Context() const;
-
- //! Gets current mouse position. It tracks change of mouse position
- //! with mouse drugging or with DRAW command call (vmoveto).
- Standard_EXPORT void GetCurrentPosition (Standard_Integer& theXPix, Standard_Integer& theYPix) const;
-
-
-
-
- DEFINE_STANDARD_RTTIEXT(ViewerTest_EventManager,Standard_Transient)
-
-protected:
+ //! Return TRUE if View should be closed on escape.
+ static Standard_Boolean& ToCloseViewOnEscape()
+ {
+ static Standard_Boolean Draw_ToCloseViewOnEsc = Standard_False;
+ return Draw_ToCloseViewOnEsc;
+ }
+ //! Return TRUE if Draw Harness should exit on closing View.
+ static Standard_Boolean& ToExitOnCloseView()
+ {
+ static Standard_Boolean Draw_ToExitOnCloseView = Standard_False;
+ return Draw_ToExitOnCloseView;
+ }
+public:
+ //! Main constructor.
+ Standard_EXPORT ViewerTest_EventManager(const Handle(V3d_View)& aView, const Handle(AIS_InteractiveContext)& aCtx);
+
+ //! Return interactive context.
+ const Handle(AIS_InteractiveContext)& Context() const { return myCtx; }
+
+ //! Returns TRUE if picking point mode has been enabled (for VPick command).
+ Standard_Boolean ToPickPoint() const { return myToPickPnt; }
+
+ //! Start picking point for VPick command.
+ void StartPickPoint (const char* theArgX,
+ const char* theArgY,
+ const char* theArgZ)
+ {
+ myToPickPnt = Standard_True;
+ myPickPntArgVec[0] = theArgX;
+ myPickPntArgVec[1] = theArgY;
+ myPickPntArgVec[2] = theArgZ;
+ }
+
+ //! Handle mouse button press/release event.
+ Standard_EXPORT virtual bool UpdateMouseButtons (const Graphic3d_Vec2i& thePoint,
+ Aspect_VKeyMouse theButtons,
+ Aspect_VKeyFlags theModifiers,
+ bool theIsEmulated) Standard_OVERRIDE;
+
+ //! Release key.
+ Standard_EXPORT virtual void KeyUp (Aspect_VKey theKey,
+ double theTime) Standard_OVERRIDE;
+
+ //! Redraw the View on an Expose Event
+ Standard_EXPORT virtual void ProcessExpose();
+
+ //! Resize View.
+ Standard_EXPORT virtual void ProcessConfigure();
+
+ //! Handle KeyPress event.
+ Standard_EXPORT void ProcessKeyPress (Aspect_VKey theKey);
private:
-
Handle(AIS_InteractiveContext) myCtx;
Handle(V3d_View) myView;
- Standard_Integer myX;
- Standard_Integer myY;
+ TCollection_AsciiString myPickPntArgVec[3];
+ Standard_Boolean myToPickPnt;
};
-
-#include <ViewerTest_EventManager.lxx>
-
-
-
-
-
#endif // _ViewerTest_EventManager_HeaderFile
+++ /dev/null
-// Created on: 1998-08-27
-// Created by: Robert COUBLANC
-// Copyright (c) 1998-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 const Handle(AIS_InteractiveContext)& ViewerTest_EventManager::Context() const
-{return myCtx;}
extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
const Handle(AIS_InteractiveObject)& theAISObj,
Standard_Boolean theReplaceIfExists = Standard_True);
-extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
extern Handle(AIS_InteractiveContext)& TheAISContext();
namespace
--- /dev/null
+// Copyright (c) 2019 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 <ViewerTest_V3dView.hxx>
+
+#include <ViewerTest.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(ViewerTest_V3dView, V3d_View)
+
+// =======================================================================
+// function : ViewerTest_V3dView
+// purpose :
+// =======================================================================
+ViewerTest_V3dView::ViewerTest_V3dView (const Handle(V3d_Viewer)& theViewer,
+ const V3d_TypeOfView theType,
+ bool theIs2dMode)
+: V3d_View (theViewer, theType),
+ myIs2dMode (theIs2dMode)
+{
+ //
+}
+
+// =======================================================================
+// function : ViewerTest_V3dView
+// purpose :
+// =======================================================================
+ViewerTest_V3dView::ViewerTest_V3dView (const Handle(V3d_Viewer)& theViewer,
+ const Handle(V3d_View)& theView)
+: V3d_View (theViewer, theView),
+ myIs2dMode (false)
+{
+ if (Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (theView))
+ {
+ myIs2dMode = aV3dView->IsViewIn2DMode();
+ }
+}
+
+// =======================================================================
+// function : IsCurrentViewIn2DMode
+// purpose :
+// =======================================================================
+bool ViewerTest_V3dView::IsCurrentViewIn2DMode()
+{
+ if (Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView()))
+ {
+ return aV3dView->IsViewIn2DMode();
+ }
+ return false;
+}
+
+// =======================================================================
+// function : SetCurrentView2DMode
+// purpose :
+// =======================================================================
+void ViewerTest_V3dView::SetCurrentView2DMode (bool theIs2d)
+{
+ if (Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView()))
+ {
+ aV3dView->SetView2DMode (theIs2d);
+ }
+}
--- /dev/null
+// Copyright (c) 2019 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 _ViewerTest_V3dView_HeaderFile
+#define _ViewerTest_V3dView_HeaderFile
+
+#include <V3d_View.hxx>
+
+//! Setting additional flag to store 2D mode of the View to avoid scene rotation by mouse/key events
+class ViewerTest_V3dView : public V3d_View
+{
+ DEFINE_STANDARD_RTTIEXT(ViewerTest_V3dView, V3d_View)
+public:
+ //! Initializes the view.
+ Standard_EXPORT ViewerTest_V3dView (const Handle(V3d_Viewer)& theViewer,
+ const V3d_TypeOfView theType = V3d_ORTHOGRAPHIC,
+ bool theIs2dMode = false);
+
+ //! Initializes the view by copying.
+ Standard_EXPORT ViewerTest_V3dView (const Handle(V3d_Viewer)& theViewer,
+ const Handle(V3d_View)& theView);
+
+ //! Returns true if 2D mode is set for the view
+ bool IsViewIn2DMode() const { return myIs2dMode; }
+
+ //! Sets 2D mode for the view
+ void SetView2DMode (bool the2dMode) { myIs2dMode = the2dMode; }
+
+public:
+
+ //! Returns true if active view in 2D mode.
+ Standard_EXPORT static bool IsCurrentViewIn2DMode();
+
+ //! Set if active view in 2D mode.
+ Standard_EXPORT static void SetCurrentView2DMode (bool theIs2d);
+
+private:
+
+ Standard_Boolean myIs2dMode; //!< 2D mode flag
+
+};
+
+#endif // _ViewerTest_V3dView_HeaderFile
// commercial license or contractual agreement.
#include <OpenGl_GlCore20.hxx>
+#include <ViewerTest.hxx>
-#include <AIS_Animation.hxx>
#include <AIS_AnimationCamera.hxx>
#include <AIS_AnimationObject.hxx>
#include <AIS_CameraFrustum.hxx>
#include <AIS_ColorScale.hxx>
-#include <AIS_Manipulator.hxx>
-#include <AIS_RubberBand.hxx>
-#include <AIS_Shape.hxx>
-#include <AIS_InteractiveObject.hxx>
+#include <AIS_InteractiveContext.hxx>
#include <AIS_ListOfInteractive.hxx>
#include <AIS_ListIteratorOfListOfInteractive.hxx>
+#include <AIS_Manipulator.hxx>
+#include <AIS_Shape.hxx>
+#include <Aspect_DisplayConnection.hxx>
#include <Aspect_Grid.hxx>
-#include <DBRep.hxx>
+#include <Aspect_TypeOfLine.hxx>
+#include <Draw.hxx>
+#include <Draw_Appli.hxx>
+#include <Draw_Interpretor.hxx>
#include <Draw_ProgressIndicator.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Pln.hxx>
+#include <gp_Pnt.hxx>
#include <Graphic3d_ArrayOfPolylines.hxx>
+#include <Graphic3d_AspectFillArea3d.hxx>
#include <Graphic3d_AspectMarker3d.hxx>
-#include <Graphic3d_NameOfTextureEnv.hxx>
+#include <Graphic3d_ClipPlane.hxx>
#include <Graphic3d_GraduatedTrihedron.hxx>
+#include <Graphic3d_NameOfTextureEnv.hxx>
+#include <Graphic3d_Texture2Dmanual.hxx>
#include <Graphic3d_TextureEnv.hxx>
#include <Graphic3d_TextureParams.hxx>
#include <Graphic3d_TypeOfTextureFilter.hxx>
-#include <Graphic3d_AspectFillArea3d.hxx>
-#include <ViewerTest.hxx>
-#include <ViewerTest_AutoUpdater.hxx>
-#include <ViewerTest_EventManager.hxx>
-#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
-#include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
-#include <ViewerTest_CmdParser.hxx>
-#include <V3d_AmbientLight.hxx>
-#include <V3d_DirectionalLight.hxx>
-#include <V3d_PositionalLight.hxx>
-#include <V3d_SpotLight.hxx>
+#include <Image_AlienPixMap.hxx>
+#include <Image_Diff.hxx>
+#include <Image_VideoRecorder.hxx>
#include <Message_ProgressSentry.hxx>
-#include <NCollection_DoubleMap.hxx>
+#include <NCollection_DataMap.hxx>
#include <NCollection_List.hxx>
#include <NCollection_Vector.hxx>
-#include <AIS_InteractiveContext.hxx>
-#include <Draw_Interpretor.hxx>
-#include <Draw.hxx>
-#include <Draw_Appli.hxx>
-#include <Image_AlienPixMap.hxx>
-#include <Image_VideoRecorder.hxx>
-#include <OpenGl_GraphicDriver.hxx>
#include <OSD.hxx>
#include <OSD_Timer.hxx>
-#include <TColStd_HSequenceOfAsciiString.hxx>
-#include <TColStd_SequenceOfInteger.hxx>
-#include <TColStd_HSequenceOfReal.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
-#include <TColStd_MapOfAsciiString.hxx>
-#include <Aspect_TypeOfLine.hxx>
-#include <Image_Diff.hxx>
-#include <Aspect_DisplayConnection.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Dir.hxx>
-#include <gp_Pln.hxx>
-#include <PrsMgr_PresentableObject.hxx>
-#include <Graphic3d_ClipPlane.hxx>
-#include <NCollection_DataMap.hxx>
-#include <Graphic3d_Texture2Dmanual.hxx>
+#include <OpenGl_GraphicDriver.hxx>
#include <Prs3d_ShadingAspect.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d_LineAspect.hxx>
#include <Prs3d_Root.hxx>
#include <Prs3d_Text.hxx>
#include <Select3D_SensitivePrimitiveArray.hxx>
+#include <TColStd_HSequenceOfAsciiString.hxx>
+#include <TColStd_SequenceOfInteger.hxx>
+#include <TColStd_HSequenceOfReal.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
+#include <TColStd_MapOfAsciiString.hxx>
+#include <ViewerTest_AutoUpdater.hxx>
+#include <ViewerTest_EventManager.hxx>
+#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
+#include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
+#include <ViewerTest_CmdParser.hxx>
+#include <ViewerTest_V3dView.hxx>
+#include <V3d_AmbientLight.hxx>
+#include <V3d_DirectionalLight.hxx>
+#include <V3d_PositionalLight.hxx>
+#include <V3d_SpotLight.hxx>
#include <tcl.h>
-#ifdef _WIN32
-#undef DrawText
-#endif
-
#include <cstdlib>
#if defined(_WIN32)
#include <tk.h>
#endif
-// Auxiliary definitions
-static const char THE_KEY_DELETE = 127;
-static const char THE_KEY_ESCAPE = 27;
-
//==============================================================================
// VIEWER GLOBAL VARIABLES
//==============================================================================
Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
-extern int VErase (Draw_Interpretor& theDI,
- Standard_Integer theArgNb,
- const char** theArgVec);
-
#if defined(_WIN32)
static Handle(WNT_Window)& VT_GetWindow() {
static Handle(WNT_Window) WNTWin;
return aWindow;
}
extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
-extern void SetCocoaWindowTitle (const Handle(Cocoa_Window)& theWindow, Standard_CString theTitle);
extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
#else
GetDisplayConnection() = theDisplayConnection;
}
-#if defined(_WIN32) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
-Aspect_Handle GetWindowHandle(const Handle(Aspect_Window)& theWindow)
-{
- Aspect_Handle aWindowHandle = (Aspect_Handle)NULL;
-#if defined(_WIN32)
- const Handle (WNT_Window) aWindow = Handle(WNT_Window)::DownCast (theWindow);
- if (!aWindow.IsNull())
- return aWindow->HWindow();
-#elif (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
- const Handle (Xw_Window) aWindow = Handle(Xw_Window)::DownCast (theWindow);
- if (!aWindow.IsNull())
- return aWindow->XWindow();
-#endif
- return aWindowHandle;
-}
-#endif
-
-//! Setting additional flag to store 2D mode of the View to avoid scene rotation by mouse/key events
-class ViewerTest_V3dView : public V3d_View
-{
- DEFINE_STANDARD_RTTI_INLINE(ViewerTest_V3dView, V3d_View)
-public:
- //! Initializes the view.
- ViewerTest_V3dView (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView theType = V3d_ORTHOGRAPHIC,
- bool theIs2dMode = false)
- : V3d_View (theViewer, theType), myIs2dMode (theIs2dMode) {}
-
- //! Initializes the view by copying.
- ViewerTest_V3dView (const Handle(V3d_Viewer)& theViewer, const Handle(V3d_View)& theView)
- : V3d_View (theViewer, theView), myIs2dMode (false)
- {
- if (Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (theView))
- {
- myIs2dMode = aV3dView->IsViewIn2DMode();
- }
- }
-
- //! Returns true if 2D mode is set for the view
- bool IsViewIn2DMode() const { return myIs2dMode; }
-
- //! Sets 2D mode for the view
- void SetView2DMode (bool the2dMode) { myIs2dMode = the2dMode; }
-
-public:
-
- //! Returns true if active view in 2D mode.
- static bool IsCurrentViewIn2DMode()
- {
- if (Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView()))
- {
- return aV3dView->IsViewIn2DMode();
- }
- return false;
- }
-
- //! Set if active view in 2D mode.
- static void SetCurrentView2DMode (bool theIs2d)
- {
- if (Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView()))
- {
- aV3dView->SetView2DMode (theIs2d);
- }
- }
-
-private:
-
- Standard_Boolean myIs2dMode; //!< 2D mode flag
-
-};
-
NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)> ViewerTest_myContexts;
static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
// EVENT GLOBAL VARIABLES
//==============================================================================
-static int Start_Rot = 0;
-Standard_Boolean HasHlrOnBeforeRotation = Standard_False;
-int X_Motion = 0; // Current cursor position
-int Y_Motion = 0;
-int X_ButtonPress = 0; // Last ButtonPress position
-int Y_ButtonPress = 0;
-Standard_Boolean IsDragged = Standard_False;
-Standard_Boolean DragFirst = Standard_False;
Standard_Boolean TheIsAnimating = Standard_False;
-Standard_Boolean Draw_ToExitOnCloseView = Standard_False;
-Standard_Boolean Draw_ToCloseViewOnEsc = Standard_False;
namespace
{
} // namespace
-Standard_EXPORT const Handle(AIS_RubberBand)& GetRubberBand()
-{
- static Handle(AIS_RubberBand) aBand;
- if (aBand.IsNull())
- {
- aBand = new AIS_RubberBand (Quantity_NOC_LIGHTBLUE, Aspect_TOL_SOLID, Quantity_NOC_LIGHTBLUE, 0.4, 1.0);
- aBand->SetDisplayMode (0);
- }
- return aBand;
-}
-
typedef NCollection_Map<AIS_Manipulator*> ViewerTest_MapOfAISManipulators;
Standard_EXPORT ViewerTest_MapOfAISManipulators& GetMapOfAISManipulators()
return anAISContext;
}
-
-//==============================================================================
-//function : SetWindowTitle
-//purpose : Set window title
-//==============================================================================
-
-void SetWindowTitle (const Handle(Aspect_Window)& theWindow,
- Standard_CString theTitle)
-{
-#if defined(_WIN32)
- const TCollection_ExtendedString theTitleW (theTitle);
- SetWindowTextW ((HWND )Handle(WNT_Window)::DownCast(theWindow)->HWindow(), theTitleW.ToWideString());
-#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
- SetCocoaWindowTitle (Handle(Cocoa_Window)::DownCast(theWindow), theTitle);
-#else
- if(GetDisplayConnection()->GetDisplay())
- {
- Window aWindow =
- Handle(Xw_Window)::DownCast(theWindow)->XWindow();
- XStoreName (GetDisplayConnection()->GetDisplay(), aWindow , theTitle);
- }
-#endif
-}
-
//==============================================================================
//function : IsWindowOverlapped
//purpose : Check if theWindow overlapp another view
aTitle = aTitle + aViewNames.GetViewName() + "(*)";
// Change name of current active window
- if (!ViewerTest::CurrentView().IsNull())
+ if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
{
- TCollection_AsciiString anActiveWindowTitle("3D View - ");
- anActiveWindowTitle = anActiveWindowTitle
- + ViewerTest_myViews.Find2 (ViewerTest::CurrentView());
- SetWindowTitle (ViewerTest::CurrentView()->Window(), anActiveWindowTitle.ToCString());
+ aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
}
// Create viewer
}
else if (anArgCase == "-exitonclose")
{
- Draw_ToExitOnCloseView = true;
+ ViewerTest_EventManager::ToExitOnCloseView() = true;
if (anArgIt + 1 < theArgsNb
- && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], Draw_ToExitOnCloseView))
+ && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToExitOnCloseView()))
{
++anArgIt;
}
else if (anArgCase == "-closeonescape"
|| anArgCase == "-closeonesc")
{
- Draw_ToCloseViewOnEsc = true;
+ ViewerTest_EventManager::ToCloseViewOnEscape() = true;
if (anArgIt + 1 < theArgsNb
- && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], Draw_ToCloseViewOnEsc))
+ && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
{
++anArgIt;
}
//function : FindViewIdByWindowHandle
//purpose : Find theView Id in the map of views by window handle
//==============================================================================
-#if defined(_WIN32) || defined(__WIN32__) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
-TCollection_AsciiString FindViewIdByWindowHandle(const Aspect_Handle theWindowHandle)
+#if defined(_WIN32) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
+TCollection_AsciiString FindViewIdByWindowHandle (Aspect_Drawable theWindowHandle)
{
for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
{
- Aspect_Handle aWindowHandle = GetWindowHandle(anIter.Value()->Window());
+ Aspect_Drawable aWindowHandle = anIter.Value()->Window()->NativeHandle();
if (aWindowHandle == theWindowHandle)
return anIter.Key1();
}
Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
if (!anAISContext.IsNull())
{
- if (!ViewerTest::CurrentView().IsNull())
+ if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
{
- TCollection_AsciiString aTitle("3D View - ");
- aTitle = aTitle + ViewerTest_myViews.Find2 (ViewerTest::CurrentView());
- SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
+ aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
}
ViewerTest::CurrentView (aView);
ViewerTest::SetAISContext (anAISContext);
- TCollection_AsciiString aTitle = TCollection_AsciiString("3D View - ") + theViewName + "(*)";
- SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
+ aView->Window()->SetTitle (TCollection_AsciiString("3D View - ") + theViewName + "(*)");
#if defined(_WIN32)
VT_GetWindow() = Handle(WNT_Window)::DownCast(ViewerTest::CurrentView()->Window());
#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
}
}
cout << "3D View - " << theViewName << " was deleted.\n";
- if (Draw_ToExitOnCloseView)
+ if (ViewerTest_EventManager::ToExitOnCloseView())
{
Draw_Interprete ("exit");
}
&& aNameString.IsEmpty()
&& anArg == "none")
{
- TCollection_AsciiString aTitle("3D View - ");
- aTitle = aTitle + ViewerTest_myViews.Find2(ViewerTest::CurrentView());
- SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
+ ViewerTest::CurrentView()->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
VT_GetWindow().Nullify();
ViewerTest::CurrentView (Handle(V3d_View)());
ViewerTest::ResetEventManager();
}
//==============================================================================
-//function : VT_ProcessKeyPress
-//purpose : Handle KeyPress event from a CString
-//==============================================================================
-void VT_ProcessKeyPress (const char* buf_ret)
-{
- //cout << "KeyPress" << endl;
- const Handle(V3d_View) aView = ViewerTest::CurrentView();
- // Letter in alphabetic order
-
- if (!strcasecmp (buf_ret, "A")
- && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
- {
- // AXO
- aView->SetProj(V3d_XposYnegZpos);
- }
- else if (!strcasecmp (buf_ret, "D")
- && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
- {
- // Reset
- aView->Reset();
- }
- else if (!strcasecmp (buf_ret, "F"))
- {
- if (ViewerTest::GetAISContext()->NbSelected() > 0)
- {
- ViewerTest::GetAISContext()->FitSelected (aView);
- }
- else
- {
- // FitAll
- aView->FitAll();
- }
- }
- else if (!strcasecmp (buf_ret, "H"))
- {
- // HLR
- std::cout << "HLR" << std::endl;
- aView->SetComputedMode (!aView->ComputedMode());
- aView->Redraw();
- }
- else if (!strcasecmp (buf_ret, "P"))
- {
- // Type of HLR
- Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
- if (aContext->DefaultDrawer()->TypeOfHLR() == Prs3d_TOH_Algo)
- aContext->DefaultDrawer()->SetTypeOfHLR(Prs3d_TOH_PolyAlgo);
- else
- aContext->DefaultDrawer()->SetTypeOfHLR(Prs3d_TOH_Algo);
- if (aContext->NbSelected()==0)
- {
- AIS_ListOfInteractive aListOfShapes;
- aContext->DisplayedObjects(aListOfShapes);
- for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes);
- anIter.More(); anIter.Next())
- {
- Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
- if (aShape.IsNull())
- continue;
- if (aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo)
- aShape->SetTypeOfHLR (Prs3d_TOH_Algo);
- else
- aShape->SetTypeOfHLR (Prs3d_TOH_PolyAlgo);
- aContext->Redisplay (aShape, Standard_False);
- }
- }
- else
- {
- for (aContext->InitSelected();aContext->MoreSelected();aContext->NextSelected())
- {
- Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aContext->SelectedInteractive());
- if (aShape.IsNull())
- continue;
- if(aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo)
- aShape->SetTypeOfHLR (Prs3d_TOH_Algo);
- else
- aShape->SetTypeOfHLR (Prs3d_TOH_PolyAlgo);
- aContext->Redisplay (aShape, Standard_False);
- }
- }
-
- aContext->UpdateCurrentViewer();
-
- }
- else if (!strcasecmp (buf_ret, "S"))
- {
- std::cout << "setup Shaded display mode" << std::endl;
-
- Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
- if(Ctx->NbSelected()==0)
- Ctx->SetDisplayMode (AIS_Shaded, Standard_True);
- else{
- for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
- Ctx->SetDisplayMode(Ctx->SelectedInteractive(),1,Standard_False);
- Ctx->UpdateCurrentViewer();
- }
- }
- else if (!strcasecmp (buf_ret, "U"))
- {
- // Unset display mode
- std::cout << "reset display mode to defaults" << std::endl;
-
- Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
- if(Ctx->NbSelected()==0)
- Ctx->SetDisplayMode (AIS_WireFrame, Standard_True);
- else{
- for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
- Ctx->UnsetDisplayMode(Ctx->SelectedInteractive(),Standard_False);
- Ctx->UpdateCurrentViewer();
- }
-
- }
- else if (!strcasecmp (buf_ret, "T")
- && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
- {
- // Top
- aView->SetProj(V3d_Zpos);
- }
- else if (!strcasecmp (buf_ret, "B")
- && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
- {
- // Bottom
- aView->SetProj(V3d_Zneg);
- }
- else if (!strcasecmp (buf_ret, "L")
- && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
- {
- // Left
- aView->SetProj(V3d_Xneg);
- }
- else if (!strcasecmp (buf_ret, "R")
- && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
- {
- // Right
- aView->SetProj(V3d_Xpos);
- }
- else if (!strcasecmp (buf_ret, "W"))
- {
- std::cout << "setup WireFrame display mode" << std::endl;
- Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
- if(Ctx->NbSelected()==0)
- Ctx->SetDisplayMode (AIS_WireFrame, Standard_True);
- else{
- for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
- Ctx->SetDisplayMode(Ctx->SelectedInteractive(),0,Standard_False);
- Ctx->UpdateCurrentViewer();
- }
- }
- else if (!strcasecmp (buf_ret, ","))
- {
- ViewerTest::GetAISContext()->HilightNextDetected(ViewerTest::CurrentView());
- }
- else if (!strcasecmp (buf_ret, "."))
- {
- ViewerTest::GetAISContext()->HilightPreviousDetected(ViewerTest::CurrentView());
- }
- else if (!strcasecmp (buf_ret, "/"))
- {
- Handle(Graphic3d_Camera) aCamera = aView->Camera();
- if (aCamera->IsStereo())
- {
- aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() - 0.01);
- aView->Redraw();
- }
- }
- else if (!strcasecmp (buf_ret, "*"))
- {
- Handle(Graphic3d_Camera) aCamera = aView->Camera();
- if (aCamera->IsStereo())
- {
- aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() + 0.01);
- aView->Redraw();
- }
- }
- else if (*buf_ret == THE_KEY_DELETE)
- {
- Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
- if (!aCtx.IsNull()
- && aCtx->NbSelected() > 0)
- {
- Draw_Interprete ("verase");
- }
- }
- else if (*buf_ret == THE_KEY_ESCAPE)
- {
- Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
- if (!aCtx.IsNull()
- && Draw_ToCloseViewOnEsc)
- {
- Draw_Interprete (Draw_ToExitOnCloseView ? "exit" : "vclose");
- }
- }
- else if (*buf_ret >= '0' && *buf_ret <= '7') // Number
- {
- const Standard_Integer aSelMode = Draw::Atoi (buf_ret);
- bool toEnable = true;
- if (const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext())
- {
- AIS_ListOfInteractive aPrsList;
- aCtx->DisplayedObjects (aPrsList);
- for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More() && toEnable; aPrsIter.Next())
- {
- TColStd_ListOfInteger aModes;
- aCtx->ActivatedModes (aPrsIter.Value(), aModes);
- for (TColStd_ListOfInteger::Iterator aModeIter (aModes); aModeIter.More() && toEnable; aModeIter.Next())
- {
- if (aModeIter.Value() == aSelMode)
- {
- toEnable = false;
- }
- }
- }
- }
- TCollection_AsciiString aCmd = TCollection_AsciiString ("vselmode ") + aSelMode + (toEnable ? " 1" : " 0");
- Draw_Interprete (aCmd.ToCString());
- }
-}
-
-//==============================================================================
-//function : VT_ProcessExpose
-//purpose : Redraw the View on an Expose Event
-//==============================================================================
-void VT_ProcessExpose()
-{
- Handle(V3d_View) aView3d = ViewerTest::CurrentView();
- if (!aView3d.IsNull())
- {
- aView3d->Redraw();
- }
-}
-
-//==============================================================================
-//function : VT_ProcessConfigure
-//purpose : Resize the View on an Configure Event
-//==============================================================================
-void VT_ProcessConfigure()
-{
- Handle(V3d_View) aView3d = ViewerTest::CurrentView();
- if (aView3d.IsNull())
- {
- return;
- }
-
- aView3d->MustBeResized();
- aView3d->Update();
- aView3d->Redraw();
-}
-
-//==============================================================================
-//function : VT_ProcessButton1Press
-//purpose : Picking
-//==============================================================================
-Standard_Boolean VT_ProcessButton1Press (Standard_Integer ,
- const char** theArgVec,
- Standard_Boolean theToPick,
- Standard_Boolean theIsShift)
-{
- if (TheIsAnimating)
- {
- TheIsAnimating = Standard_False;
- return Standard_False;
- }
-
- if (theToPick)
- {
- Standard_Real X, Y, Z;
- ViewerTest::CurrentView()->Convert (X_Motion, Y_Motion, X, Y, Z);
-
- Draw::Set (theArgVec[1], X);
- Draw::Set (theArgVec[2], Y);
- Draw::Set (theArgVec[3], Z);
- }
-
- if (theIsShift)
- {
- ViewerTest::CurrentEventManager()->ShiftSelect();
- }
- else
- {
- ViewerTest::CurrentEventManager()->Select();
- }
-
- return Standard_False;
-}
-
-//==============================================================================
-//function : VT_ProcessButton1Release
-//purpose : End selecting
-//==============================================================================
-void VT_ProcessButton1Release (Standard_Boolean theIsShift)
-{
- if (IsDragged)
- {
- IsDragged = Standard_False;
- Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
- if (theIsShift)
- {
- EM->ShiftSelect (X_ButtonPress, Y_ButtonPress,
- X_Motion, Y_Motion);
- }
- else
- {
- EM->Select (X_ButtonPress, Y_ButtonPress,
- X_Motion, Y_Motion);
- }
- }
-}
-
-//==============================================================================
-//function : VT_ProcessButton3Press
-//purpose : Start Rotation
-//==============================================================================
-void VT_ProcessButton3Press()
-{
- if (ViewerTest_V3dView::IsCurrentViewIn2DMode())
- {
- return;
- }
-
- Start_Rot = 1;
- HasHlrOnBeforeRotation = ViewerTest::CurrentView()->ComputedMode();
- if (HasHlrOnBeforeRotation)
- {
- ViewerTest::CurrentView()->SetComputedMode (Standard_False);
- }
- ViewerTest::CurrentView()->StartRotation( X_ButtonPress, Y_ButtonPress );
-}
-
-//==============================================================================
-//function : VT_ProcessButton3Release
-//purpose : End rotation
-//==============================================================================
-void VT_ProcessButton3Release()
-{
- if (Start_Rot)
- {
- Start_Rot = 0;
- if (HasHlrOnBeforeRotation)
- {
- HasHlrOnBeforeRotation = Standard_False;
- ViewerTest::CurrentView()->SetComputedMode (Standard_True);
- ViewerTest::CurrentView()->Redraw();
- }
- }
-}
-
-//==============================================================================
-//function : ProcessControlButton1Motion
-//purpose : Zoom
-//==============================================================================
-
-#if defined(_WIN32) || ! defined(__APPLE__) || defined(MACOSX_USE_GLX)
-static void ProcessControlButton1Motion()
-{
- ViewerTest::CurrentView()->Zoom( X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion);
-
- X_ButtonPress = X_Motion;
- Y_ButtonPress = Y_Motion;
-}
-#endif
-
-//==============================================================================
-//function : VT_ProcessControlButton2Motion
-//purpose : Panning
-//==============================================================================
-void VT_ProcessControlButton2Motion()
-{
- Standard_Integer aDx = X_Motion - X_ButtonPress;
- Standard_Integer aDy = Y_Motion - Y_ButtonPress;
-
- aDy = -aDy; // Xwindow Y axis is from top to Bottom
-
- ViewerTest::CurrentView()->Pan (aDx, aDy);
-
- X_ButtonPress = X_Motion;
- Y_ButtonPress = Y_Motion;
-}
-
-//==============================================================================
-//function : VT_ProcessControlButton3Motion
-//purpose : Rotation
+//function : GetMousePosition
+//purpose :
//==============================================================================
-void VT_ProcessControlButton3Motion()
+void ViewerTest::GetMousePosition (Standard_Integer& theX,
+ Standard_Integer& theY)
{
- if (Start_Rot)
+ if (Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager())
{
- ViewerTest::CurrentView()->Rotation (X_Motion, Y_Motion);
+ theX = aViewCtrl->LastMousePosition().x();
+ theY = aViewCtrl->LastMousePosition().y();
}
}
-//==============================================================================
-//function : VT_ProcessMotion
-//purpose :
-//==============================================================================
-void VT_ProcessMotion()
-{
- //pre-hilights detected objects at mouse position
-
- Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
- EM->MoveTo(X_Motion, Y_Motion);
-}
-
-
-void ViewerTest::GetMousePosition(Standard_Integer& Xpix,Standard_Integer& Ypix)
-{
- Xpix = X_Motion;Ypix=Y_Motion;
-}
-
//==============================================================================
//function : VViewProj
//purpose : Switch view projection
static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
{
-
- di << "Q : Quit the application\n";
-
di << "=========================\n";
di << "F : FitAll\n";
di << "T : TopView\n";
di << "=========================\n";
di << "S : Shading\n";
di << "W : Wireframe\n";
- di << "H : HidelLineRemoval\n";
+ di << "H : HiddenLineRemoval\n";
di << "U : Unset display mode\n";
di << "Delete : Remove selection from viewer\n";
di << "7 : Compound\n";
di << "=========================\n";
- di << "Z : Switch Z clipping On/Off\n";
- di << ", : Hilight next detected\n";
- di << ". : Hilight previous detected\n";
+ di << "< : Hilight next detected\n";
+ di << "> : Hilight previous detected\n";
return 0;
}
#ifdef _WIN32
-static Standard_Boolean Ppick = 0;
-static Standard_Integer Pargc = 0;
-static const char** Pargv = NULL;
-
-
-static LRESULT WINAPI AdvViewerWindowProc( HWND hwnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam )
+static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
+ UINT theMsg,
+ WPARAM wParam,
+ LPARAM lParam )
{
- if (!ViewerTest_myViews.IsEmpty()) {
-
- WPARAM fwKeys = wParam;
+ if (ViewerTest_myViews.IsEmpty())
+ {
+ return ViewerWindowProc (theWinHandle, theMsg, wParam, lParam);
+ }
- switch( Msg ) {
+ switch (theMsg)
+ {
case WM_CLOSE:
- {
- // Delete view from map of views
- ViewerTest::RemoveView(FindViewIdByWindowHandle(hwnd));
- return 0;
- }
- break;
+ {
+ // Delete view from map of views
+ ViewerTest::RemoveView (FindViewIdByWindowHandle (theWinHandle));
+ return 0;
+ }
case WM_ACTIVATE:
- if(LOWORD(wParam) == WA_CLICKACTIVE || LOWORD(wParam) == WA_ACTIVE
- || ViewerTest::CurrentView().IsNull())
+ {
+ if (LOWORD(wParam) == WA_CLICKACTIVE
+ || LOWORD(wParam) == WA_ACTIVE
+ || ViewerTest::CurrentView().IsNull())
{
// Activate inactive window
- if(GetWindowHandle(VT_GetWindow()) != hwnd)
- {
- ActivateView (FindViewIdByWindowHandle(hwnd));
- }
- }
- break;
-
- case WM_LBUTTONUP:
- if (IsDragged && !DragFirst)
- {
- if (!GetActiveAISManipulator().IsNull())
- {
- GetActiveAISManipulator()->StopTransform();
- ViewerTest::GetAISContext()->ClearSelected (Standard_True);
- }
-
- if (ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
- {
- ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
- ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
- }
-
- VT_ProcessButton1Release ((fwKeys & MK_SHIFT) != 0);
- }
- IsDragged = Standard_False;
- return ViewerWindowProc( hwnd, Msg, wParam, lParam );
-
- case WM_RBUTTONUP:
- if (IsDragged && !DragFirst)
- {
- if (!GetActiveAISManipulator().IsNull())
+ if (VT_GetWindow().IsNull()
+ || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
{
- GetActiveAISManipulator()->StopTransform (Standard_False);
- ViewerTest::GetAISContext()->ClearSelected (Standard_True);
+ ActivateView (FindViewIdByWindowHandle (theWinHandle));
}
- IsDragged = Standard_False;
- }
- return ViewerWindowProc (hwnd, Msg, wParam, lParam);
-
- case WM_LBUTTONDOWN:
- if (!GetActiveAISManipulator().IsNull())
- {
- IsDragged = ( fwKeys == MK_LBUTTON );
- }
- else
- {
- IsDragged = ( fwKeys == MK_LBUTTON || fwKeys == ( MK_LBUTTON | MK_SHIFT ) );
- }
-
- if (IsDragged)
- {
- DragFirst = Standard_True;
- X_ButtonPress = LOWORD(lParam);
- Y_ButtonPress = HIWORD(lParam);
- }
- return ViewerWindowProc( hwnd, Msg, wParam, lParam );
-
- case WM_MOUSEMOVE:
- if (IsDragged)
- {
- X_Motion = LOWORD (lParam);
- Y_Motion = HIWORD (lParam);
- if (!GetActiveAISManipulator().IsNull())
- {
- if (DragFirst)
- {
- GetActiveAISManipulator()->StartTransform (X_ButtonPress, Y_ButtonPress, ViewerTest::CurrentView());
- }
- else
- {
- GetActiveAISManipulator()->Transform (X_Motion, Y_Motion, ViewerTest::CurrentView());
- ViewerTest::GetAISContext()->CurrentViewer()->Redraw();
- }
- }
- else
- {
- bool toRedraw = false;
- if (!DragFirst && ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
- {
- ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
- toRedraw = true;
- }
-
- RECT aRect;
- if (GetClientRect (hwnd, &aRect))
- {
- int aHeight = aRect.bottom - aRect.top;
- GetRubberBand()->SetRectangle (X_ButtonPress, aHeight - Y_ButtonPress, X_Motion, aHeight - Y_Motion);
- ViewerTest::GetAISContext()->Display (GetRubberBand(), 0, -1, Standard_False, AIS_DS_Displayed);
- toRedraw = true;
- }
- if (toRedraw)
- {
- ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
- }
- }
-
- DragFirst = Standard_False;
}
- else
- return ViewerWindowProc( hwnd, Msg, wParam, lParam );
break;
-
+ }
default:
- return ViewerWindowProc( hwnd, Msg, wParam, lParam );
+ {
+ return ViewerWindowProc (theWinHandle, theMsg, wParam, lParam);
}
- return 0;
}
- return ViewerWindowProc( hwnd, Msg, wParam, lParam );
+ return 0;
}
-
-static LRESULT WINAPI ViewerWindowProc( HWND hwnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam )
+static LRESULT WINAPI ViewerWindowProc (HWND theWinHandle,
+ UINT theMsg,
+ WPARAM wParam,
+ LPARAM lParam)
{
- static int Up = 1;
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
if (aView.IsNull())
{
- return DefWindowProcW (hwnd, Msg, wParam, lParam);
+ return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
}
- PAINTSTRUCT ps;
-
- switch( Msg ) {
+ switch (theMsg)
+ {
case WM_PAINT:
- BeginPaint(hwnd, &ps);
- EndPaint(hwnd, &ps);
- VT_ProcessExpose();
+ {
+ PAINTSTRUCT aPaint;
+ BeginPaint(theWinHandle, &aPaint);
+ EndPaint (theWinHandle, &aPaint);
+ ViewerTest::CurrentEventManager()->ProcessExpose();
break;
-
+ }
case WM_SIZE:
- VT_ProcessConfigure();
+ {
+ 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:
- VT_ProcessConfigure(); // track window moves to reverse stereo pair
+ {
+ // track window moves to reverse stereo pair
+ aView->MustBeResized();
+ aView->Update();
break;
+ }
default:
break;
}
break;
-
+ }
+ case WM_KEYUP:
case WM_KEYDOWN:
- if ((wParam != VK_SHIFT) && (wParam != VK_CONTROL))
+ {
+ const Aspect_VKey aVKey = WNT_Window::VirtualKeyFromNative ((Standard_Integer )wParam);
+ if (aVKey != Aspect_VKey_UNKNOWN)
{
- char c[2];
- c[0] = (char) wParam;
- c[1] = '\0';
- if (wParam == VK_DELETE)
- {
- c[0] = THE_KEY_DELETE;
- }
- else if (wParam == VK_ESCAPE)
- {
- c[0] = THE_KEY_ESCAPE;
- }
- // comma
- else if (wParam == VK_OEM_COMMA)
- {
- c[0] = ',';
- }
- // dot
- else if (wParam == VK_OEM_PERIOD)
- {
- c[0] = '.';
- }
- else if (wParam == VK_DIVIDE)
+ const double aTimeStamp = ViewerTest::CurrentEventManager()->EventTime();
+ if (theMsg == WM_KEYDOWN)
{
- c[0] = '/';
+ ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
}
- // dot
- else if (wParam == VK_MULTIPLY)
+ else
{
- c[0] = '*';
+ ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
}
- VT_ProcessKeyPress (c);
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
}
break;
-
+ }
case WM_LBUTTONUP:
case WM_MBUTTONUP:
case WM_RBUTTONUP:
- Up = 1;
- VT_ProcessButton3Release();
- break;
-
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)
{
- WPARAM fwKeys = wParam;
-
- Up = 0;
-
- X_ButtonPress = LOWORD(lParam);
- Y_ButtonPress = HIWORD(lParam);
-
- if (Msg == WM_LBUTTONDOWN)
- {
- if ((fwKeys & MK_CONTROL) != 0)
- {
- Ppick = VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT) != 0);
- }
- else
- {
- VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT) != 0);
- }
- }
- else if (Msg == WM_RBUTTONDOWN)
- {
- // Start rotation
- VT_ProcessButton3Press();
- }
+ 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;
}
- break;
-
- case WM_MOUSEWHEEL:
- {
- int aDelta = GET_WHEEL_DELTA_WPARAM (wParam);
- if (wParam & MK_CONTROL)
+ if (theMsg == WM_LBUTTONDOWN
+ || theMsg == WM_MBUTTONDOWN
+ || theMsg == WM_RBUTTONDOWN)
{
- if (aView->Camera()->IsStereo())
+ if (aButton == Aspect_VKeyMouse_LeftButton)
{
- Standard_Real aFocus = aView->Camera()->ZFocus() + (aDelta > 0 ? 0.05 : -0.05);
- if (aFocus > 0.2
- && aFocus < 2.0)
- {
- aView->Camera()->SetZFocus (aView->Camera()->ZFocusType(), aFocus);
- aView->Redraw();
- }
+ TheIsAnimating = Standard_False;
}
+
+ SetFocus (theWinHandle);
+ SetCapture(theWinHandle);
+ ViewerTest::CurrentEventManager()->PressMouseButton (aPos, aButton, aFlags, false);
}
else
{
- aView->Zoom (0, 0, aDelta / 40, aDelta / 40);
+ ReleaseCapture();
+ ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, aButton, aFlags, false);
}
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
break;
}
-
- case WM_MOUSEMOVE:
+ 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))
{
- //cout << "\t WM_MOUSEMOVE" << endl;
- WPARAM fwKeys = wParam;
- X_Motion = LOWORD(lParam);
- Y_Motion = HIWORD(lParam);
+ aPos.SetValues (aCursorPnt.x, aCursorPnt.y);
+ }
- if ( Up &&
- (fwKeys & ( MK_LBUTTON|MK_MBUTTON|MK_RBUTTON )) != 0 )
- {
- Up = 0;
- X_ButtonPress = LOWORD(lParam);
- Y_ButtonPress = HIWORD(lParam);
+ 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);
- if ((fwKeys & MK_RBUTTON) != 0) {
- // Start rotation
- VT_ProcessButton3Press();
- }
- }
+ // 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 ((fwKeys & MK_CONTROL) != 0)
- {
- if ((fwKeys & MK_LBUTTON) != 0)
- {
- ProcessControlButton1Motion();
- }
- else if ((fwKeys & MK_MBUTTON) != 0
- || ((fwKeys & MK_LBUTTON) != 0
- && (fwKeys & MK_RBUTTON) != 0))
- {
- VT_ProcessControlButton2Motion();
- }
- else if ((fwKeys & MK_RBUTTON) != 0)
- {
- VT_ProcessControlButton3Motion();
- }
- }
- else if (GetWindowHandle (VT_GetWindow()) == hwnd)
- {
- VT_ProcessMotion();
- }
+ if (VT_GetWindow().IsNull()
+ || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
+ {
+ // mouse move events come also for inactive windows
+ break;
}
- break;
+ ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
+ break;
+ }
default:
- return DefWindowProcW (hwnd, Msg, wParam, lParam);
+ {
+ return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
}
- return 0L;
+ }
+ return 0L;
}
//==============================================================================
//purpose : Get a Event on the view and dispatch it
//==============================================================================
-
-int ViewerMainLoop(Standard_Integer argc, const char** argv)
+int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
{
- Ppick = (argc > 0)? 1 : 0;
- Pargc = argc;
- Pargv = argv;
+ Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager();
+ if (aViewCtrl.IsNull()
+ || theNbArgs < 4)
+ {
+ return 0;
+ }
- if ( Ppick ) {
- MSG msg;
- msg.wParam = 1;
+ aViewCtrl->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
- cout << "Start picking" << endl;
+ std::cout << "Start picking\n";
- while ( Ppick == 1 ) {
- // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
- if (GetMessageW (&msg, NULL, 0, 0))
- {
- TranslateMessage (&msg);
- DispatchMessageW (&msg);
- }
+ MSG aMsg;
+ aMsg.wParam = 1;
+ while (aViewCtrl->ToPickPoint())
+ {
+ // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
+ if (GetMessageW (&aMsg, NULL, 0, 0))
+ {
+ TranslateMessage (&aMsg);
+ DispatchMessageW (&aMsg);
}
-
- cout << "Picking done" << endl;
}
- return Ppick;
+ std::cout << "Picking done\n";
+ return 0;
}
#elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
return b;
}
-int ViewerMainLoop (Standard_Integer argc, const char** argv)
+int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
{
static XEvent aReport;
- const Standard_Boolean toPick = argc > 0;
- Standard_Boolean toPickMore = toPick;
+ const Standard_Boolean toPick = theNbArgs > 0;
+ if (theNbArgs > 0)
+ {
+ if (ViewerTest::CurrentEventManager().IsNull())
+ {
+ return 0;
+ }
+ ViewerTest::CurrentEventManager()->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
+ }
+
Display* aDisplay = GetDisplayConnection()->GetDisplay();
XNextEvent (aDisplay, &aReport);
case FocusIn:
{
// Activate inactive view
- Window aWindow = GetWindowHandle(VT_GetWindow());
+ Window aWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
if (aWindow != aReport.xfocus.window)
{
ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
}
case Expose:
{
- Window anXWindow = GetWindowHandle (VT_GetWindow());
+ Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
if (anXWindow == aReport.xexpose.window)
{
- VT_ProcessExpose();
+ ViewerTest::CurrentEventManager()->ProcessExpose();
}
// remove all the ExposureMask and process them at once
case ConfigureNotify:
{
// remove all the StructureNotifyMask and process them at once
- Window anXWindow = GetWindowHandle (VT_GetWindow());
+ Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
{
if (!XCheckWindowEvent (aDisplay, anXWindow, StructureNotifyMask, &aReport))
if (anXWindow == aReport.xconfigure.window)
{
- VT_ProcessConfigure();
+ ViewerTest::CurrentEventManager()->ProcessConfigure();
}
break;
}
case KeyPress:
+ case KeyRelease:
{
- KeySym aKeySym;
- char aKeyBuf[11];
- XComposeStatus status_in_out;
- int aKeyLen = XLookupString ((XKeyEvent* )&aReport, (char* )aKeyBuf, 10, &aKeySym, &status_in_out);
- aKeyBuf[aKeyLen] = '\0';
- if (aKeyLen != 0)
- {
- VT_ProcessKeyPress (aKeyBuf);
- }
- break;
- }
- case ButtonPress:
- {
- X_ButtonPress = aReport.xbutton.x;
- Y_ButtonPress = aReport.xbutton.y;
- if (aReport.xbutton.button == Button1)
+ XKeyEvent* aKeyEvent = (XKeyEvent* )&aReport;
+ const KeySym aKeySym = XLookupKeysym (aKeyEvent, 0);
+ const Aspect_VKey aVKey = Xw_Window::VirtualKeyFromNative (aKeySym);
+ if (aVKey != Aspect_VKey_UNKNOWN)
{
- if (aReport.xbutton.state & ControlMask)
+ const double aTimeStamp = ViewerTest::CurrentEventManager()->EventTime();
+ if (aReport.type == KeyPress)
{
- toPickMore = VT_ProcessButton1Press (argc, argv, toPick, (aReport.xbutton.state & ShiftMask) != 0);
+ ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
}
else
{
- IsDragged = Standard_True;
- DragFirst = Standard_True;
+ ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
}
- }
- else if (aReport.xbutton.button == Button3)
- {
- // Start rotation
- VT_ProcessButton3Press();
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
}
break;
}
+ case ButtonPress:
case ButtonRelease:
{
- if (!IsDragged)
+ 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)
{
- VT_ProcessButton3Release();
- break;
+ aButton = Aspect_VKeyMouse_LeftButton;
}
-
- Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
- if (aContext.IsNull())
+ if (aReport.xbutton.button == Button2)
{
- std::cout << "Error: No active view.\n";
- return 0;
+ aButton = Aspect_VKeyMouse_MiddleButton;
}
-
- if (!DragFirst
- && aContext->IsDisplayed (GetRubberBand()))
+ if (aReport.xbutton.button == Button3)
{
- aContext->Remove (GetRubberBand(), Standard_False);
- aContext->CurrentViewer()->RedrawImmediate();
+ aButton = Aspect_VKeyMouse_RightButton;
}
- if (aReport.xbutton.button != Button1)
+ if (aReport.xbutton.state & ControlMask)
{
- break;
+ 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;
}
- const Standard_Boolean isShiftPressed = (aReport.xbutton.state & ShiftMask) != 0;
- if (DragFirst)
+ if (aReport.xbutton.button == Button4
+ || aReport.xbutton.button == Button5)
{
- if (isShiftPressed)
+ if (aReport.type != ButtonPress)
{
- aContext->ShiftSelect (Standard_True);
+ break;
}
- else
+
+ 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)
{
- aContext->Select (Standard_True);
+ TheIsAnimating = Standard_False;
}
+ ViewerTest::CurrentEventManager()->PressMouseButton (aPos, aButton, aFlags, false);
}
else
{
- if (isShiftPressed)
- {
- aContext->ShiftSelect (Min (X_ButtonPress, X_Motion), Min (Y_ButtonPress, Y_Motion),
- Max (X_ButtonPress, X_Motion), Max (Y_ButtonPress, Y_Motion),
- ViewerTest::CurrentView(), Standard_True);
- }
- else
- {
- aContext->Select (Min (X_ButtonPress, X_Motion), Min(Y_ButtonPress, Y_Motion),
- Max (X_ButtonPress, X_Motion), Max(Y_ButtonPress, Y_Motion),
- ViewerTest::CurrentView(), Standard_True);
- }
+ ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, aButton, aFlags, false);
}
- IsDragged = Standard_False;
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
break;
}
case MotionNotify:
{
- Window anXWindow = GetWindowHandle (VT_GetWindow());
+ Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
if (anXWindow != aReport.xmotion.window)
{
break;
}
}
- if (IsDragged)
+ 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)
{
- if (!DragFirst
- && ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
- {
- ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
- }
-
- X_Motion = aReport.xmotion.x;
- Y_Motion = aReport.xmotion.y;
- DragFirst = Standard_False;
+ 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;
+ }
- Window aWindow = GetWindowHandle(VT_GetWindow());
- Window aRoot;
- int anX, anY;
- unsigned int aWidth, aHeight, aBorderWidth, aDepth;
- XGetGeometry (aDisplay, aWindow, &aRoot, &anX, &anY, &aWidth, &aHeight, &aBorderWidth, &aDepth);
- GetRubberBand()->SetRectangle (X_ButtonPress, aHeight - Y_ButtonPress, X_Motion, aHeight - Y_Motion);
- ViewerTest::GetAISContext()->Display (GetRubberBand(), 0, -1, Standard_False, AIS_DS_Displayed);
- ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
+ if (aReport.xmotion.state & ControlMask)
+ {
+ aFlags |= Aspect_VKeyFlags_CTRL;
}
- else
+ if (aReport.xmotion.state & ShiftMask)
{
- X_Motion = aReport.xmotion.x;
- Y_Motion = aReport.xmotion.y;
- if ((aReport.xmotion.state & ControlMask) != 0)
- {
- if ((aReport.xmotion.state & Button1Mask) != 0)
- {
- ProcessControlButton1Motion();
- }
- else if ((aReport.xmotion.state & Button2Mask) != 0)
- {
- VT_ProcessControlButton2Motion();
- }
- else if ((aReport.xmotion.state & Button3Mask) != 0)
- {
- VT_ProcessControlButton3Motion();
- }
- }
- else
- {
- VT_ProcessMotion();
- }
+ 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;
}
}
- return (!toPick || toPickMore) ? 1 : 0;
+ return (!toPick || ViewerTest::CurrentEventManager()->ToPickPoint()) ? 1 : 0;
}
//==============================================================================
XSetWMHints( aDisplay, window, &wmhints);
- XSelectInput( aDisplay, window, ExposureMask | KeyPressMask |
+ XSelectInput( aDisplay, window, ExposureMask | KeyPressMask | KeyReleaseMask |
ButtonPressMask | ButtonReleaseMask |
StructureNotifyMask |
PointerMotionMask |
//purpose :
//==============================================================================
-static int VPick(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
-{ if (ViewerTest::CurrentView().IsNull() ) return 1;
+static int VPick (Draw_Interpretor& ,
+ Standard_Integer theNbArgs,
+ const char** theArgVec)
+{
+ if (ViewerTest::CurrentView().IsNull())
+ {
+ return 1;
+ }
-if ( argc < 4 ) {
- di << argv[0] << "Invalid number of arguments\n";
- return 1;
-}
+ if (theNbArgs < 4)
+ {
+ std::cout << "Syntax error: Invalid number of arguments\n";
+ return 1;
+ }
-while (ViewerMainLoop( argc, argv)) {
-}
+ while (ViewerMainLoop (theNbArgs, theArgVec))
+ {
+ //
+ }
-return 0;
+ return 0;
}
namespace
}
else if (anArg == "-exitonclose")
{
- Draw_ToExitOnCloseView = true;
+ ViewerTest_EventManager::ToExitOnCloseView() = true;
if (anArgIter + 1 < theArgNb
- && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], Draw_ToExitOnCloseView))
+ && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToExitOnCloseView()))
{
++anArgIter;
}
else if (anArg == "-closeonescape"
|| anArg == "-closeonesc")
{
- Draw_ToCloseViewOnEsc = true;
+ ViewerTest_EventManager::ToCloseViewOnEscape() = true;
if (anArgIter + 1 < theArgNb
- && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], Draw_ToCloseViewOnEsc))
+ && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
{
++anArgIter;
}
// pixel positions (x1,y1),...,(xn,yn)
// 4) any of these selections with shift button pressed
//=======================================================================
-static Standard_Integer VSelect (Draw_Interpretor& di,
- Standard_Integer argc,
- const char ** argv)
+static Standard_Integer VSelect (Draw_Interpretor& ,
+ Standard_Integer theNbArgs,
+ const char** theArgVec)
{
- if(argc < 3)
- {
- di << "Usage : " << argv[0] << " x1 y1 [x2 y2 [... xn yn]] [shift_selection = 1|0]\n";
- return 1;
- }
-
- Handle(AIS_InteractiveContext) myAIScontext = ViewerTest::GetAISContext();
- if(myAIScontext.IsNull())
+ const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
+ if (aCtx.IsNull())
{
- di << "use 'vinit' command before " << argv[0] << "\n";
+ std::cout << "Error: no active View\n";
return 1;
}
- const Standard_Boolean isShiftSelection = (argc > 3 && !(argc % 2) && (atoi (argv[argc - 1]) == 1));
- Standard_Integer aCoordsNb = isShiftSelection ? argc - 2 : argc - 1;
- TCollection_AsciiString anArg;
- anArg = isShiftSelection ? argv[argc - 3] : argv[argc - 2];
- anArg.LowerCase();
- if (anArg == "-allowoverlap")
+ NCollection_Sequence<Graphic3d_Vec2i> aPnts;
+ bool isShiftSelection = false, toAllowOverlap = false;
+ for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
{
- Standard_Boolean isValidated = isShiftSelection ? argc == 8
- : argc == 7;
- if (!isValidated)
+ TCollection_AsciiString anArg (theArgVec[anArgIter]);
+ anArg.LowerCase();
+ if (anArg == "-allowoverlap")
+ {
+ toAllowOverlap = true;
+ if (anArgIter + 1 < theNbArgs
+ && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toAllowOverlap))
+ {
+ ++anArgIter;
+ }
+ }
+ else if (anArgIter + 1 < theNbArgs
+ && anArg.IsIntegerValue()
+ && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
{
- di << "Wrong number of arguments! -allowoverlap key is applied only for rectangle selection";
+ const TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
+ aPnts.Append (Graphic3d_Vec2i (anArg.IntegerValue(), anArgNext.IntegerValue()));
+ }
+ else if (anArgIter + 1 == theNbArgs
+ && anArg.IsIntegerValue())
+ {
+ isShiftSelection = anArg.IntegerValue() == 1;
+ }
+ else
+ {
+ std::cout << "Syntax error at '" << anArg << "'\n";
return 1;
}
-
- Standard_Integer isToAllow = isShiftSelection ? Draw::Atoi(argv[argc - 2]) : Draw::Atoi(argv[argc - 1]);
- myAIScontext->MainSelector()->AllowOverlapDetection (isToAllow != 0);
- aCoordsNb -= 2;
+ }
+ if (toAllowOverlap
+ && aPnts.Length() != 2)
+ {
+ std::cout << "Syntax error: -allowoverlap key is applied only for rectangle selection\n";
+ return 1;
+ }
+ if (toAllowOverlap)
+ {
+ aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
}
Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
- aCurrentEventManager->MoveTo(atoi(argv[1]),atoi(argv[2]));
- if(aCoordsNb == 2)
+ if (aPnts.IsEmpty())
{
- if(isShiftSelection)
- aCurrentEventManager->ShiftSelect();
+ if (isShiftSelection)
+ {
+ aCtx->ShiftSelect (false);
+ }
else
- aCurrentEventManager->Select();
+ {
+ aCtx->Select (false);
+ }
+ aCtx->CurrentViewer()->Invalidate();
}
- else if(aCoordsNb == 4)
+ else if (aPnts.Length() == 2)
{
- if(isShiftSelection)
- aCurrentEventManager->ShiftSelect (atoi (argv[1]), atoi (argv[2]), atoi (argv[3]), atoi (argv[4]), Standard_False);
- else
- aCurrentEventManager->Select (atoi (argv[1]), atoi (argv[2]), atoi (argv[3]), atoi (argv[4]), Standard_False);
+ if (toAllowOverlap
+ && aPnts.First().y() < aPnts.Last().y())
+ {
+ std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
+ }
+ else if (!toAllowOverlap
+ && aPnts.First().y() > aPnts.Last().y())
+ {
+ std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
+ }
+ aCurrentEventManager->SelectInViewer (aPnts, isShiftSelection);
}
else
{
- TColgp_Array1OfPnt2d aPolyline (1,aCoordsNb / 2);
-
- for(Standard_Integer i=1;i<=aCoordsNb / 2;++i)
- aPolyline.SetValue(i,gp_Pnt2d(atoi(argv[2*i-1]),atoi(argv[2*i])));
-
- if(isShiftSelection)
- aCurrentEventManager->ShiftSelect(aPolyline);
- else
- aCurrentEventManager->Select(aPolyline);
+ aCurrentEventManager->SelectInViewer (aPnts, isShiftSelection);
}
+ aCurrentEventManager->FlushViewEvents (aCtx, ViewerTest::CurrentView(), true);
return 0;
}
return 1;
}
- ViewerTest::CurrentEventManager()->MoveTo (aMousePos.x(), aMousePos.y());
+ ViewerTest::CurrentEventManager()->ResetPreviousMoveTo();
+ ViewerTest::CurrentEventManager()->UpdateMousePosition (aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
+
gp_Pnt aTopPnt (RealLast(), RealLast(), RealLast());
const Handle(SelectMgr_EntityOwner)& aDetOwner = aContext->DetectedOwner();
for (Standard_Integer aDetIter = 1; aDetIter <= aContext->MainSelector()->NbPicked(); ++aDetIter)
return 0;
}
-//=======================================================================
-//function : VProgressiveMode
-//purpose :
-//=======================================================================
-#if defined(_WIN32)
-static Standard_Integer VProgressiveMode (Draw_Interpretor& /*theDI*/,
- Standard_Integer /*theNbArgs*/,
- const char** /*theArgs*/)
-{
- Handle(V3d_View) aView = ViewerTest::CurrentView();
- if (aView.IsNull())
- {
- std::cerr << "Error: no active viewer!\n";
- return 1;
- }
-
- std::cout << "Press Enter or Escape key to exit progressive rendering mode" << std::endl;
-
- for (;;)
- {
- aView->Redraw();
-
- Standard_Boolean toExit = Standard_False;
-
- MSG aMsg;
- while (PeekMessageW (&aMsg, NULL, 0, 0, PM_REMOVE))
- {
- if (aMsg.message == WM_KEYDOWN && (aMsg.wParam == 0x0d || aMsg.wParam == 0x1b))
- {
- toExit = Standard_True;
- }
-
- TranslateMessage (&aMsg);
- DispatchMessageW (&aMsg);
- }
-
- if (toExit)
- {
- break;
- }
- }
-
- return 0;
-}
-#endif
-
//=======================================================================
//function : VXRotate
//purpose :
std::cout << theArgVec[0] << ": AIS object \"" << aName << "\" has been created.\n";
aManipulator = new ViewerTest_AISManipulator();
+ aManipulator->SetModeActivationOnDetection (true);
aMapAIS.Bind (aManipulator, aName);
}
else
"\n\t\t: selMode color of selection mode"
"\n\t\t: entity color of etected entity",
__FILE__, VDumpSelectionImage, group);
-
-#if defined(_WIN32)
- theCommands.Add("vprogressive",
- "vprogressive",
- __FILE__, VProgressiveMode, group);
-#endif
}
#include <Cocoa_Window.hxx>
#include <ViewerTest.hxx>
+#include <ViewerTest_EventManager.hxx>
#include <V3d_View.hxx>
#include <V3d_Viewer.hxx>
#include <AIS_InteractiveContext.hxx>
extern void ActivateView (const TCollection_AsciiString& theViewName,
Standard_Boolean theToUpdate = Standard_True);
-extern void VT_ProcessExpose();
-extern void VT_ProcessConfigure();
-extern void VT_ProcessKeyPress (const char* theBuffer);
-extern void VT_ProcessMotion();
-extern void VT_ProcessButton3Press();
-extern void VT_ProcessButton3Release();
-extern void VT_ProcessControlButton2Motion();
-extern void VT_ProcessControlButton3Motion();
-extern Standard_Boolean VT_ProcessButton1Press (Standard_Integer theArgsNb,
- const char** theArgsVec,
- Standard_Boolean theToPick,
- Standard_Boolean theIsShift);
-extern void VT_ProcessButton1Release(Standard_Boolean theIsShift);
extern NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
-extern int X_Motion; // Current cursor position
-extern int Y_Motion;
-extern int X_ButtonPress; // Last ButtonPress position
-extern int Y_ButtonPress;
-extern Standard_Boolean IsDragged;
-
-// =======================================================================
-// function : SetCocoaWindowTitle
-// purpose :
-// =======================================================================
-void SetCocoaWindowTitle (const Handle(Cocoa_Window)& theWindow, Standard_CString theTitle)
-{
- NSView* aView = theWindow->HView();
- NSWindow* aWindow = [aView window];
-
- NSString* aTitleNS = [[NSString alloc] initWithUTF8String: theTitle];
- [aWindow setTitle: aTitleNS];
- [aTitleNS release];
-
-}
// =======================================================================
// function : GetCocoaScreenResolution
[aView release];
}
-// =======================================================================
-// function : getMouseCoords
-// purpose : Retrieve cursor position
-// =======================================================================
-static void getMouseCoords (NSView* theView,
- NSEvent* theEvent,
- Standard_Integer& theX,
- Standard_Integer& theY)
+//! Retrieve cursor position
+static Graphic3d_Vec2i getMouseCoords (NSView* theView,
+ NSEvent* theEvent)
{
NSPoint aMouseLoc = [theView convertPoint: [theEvent locationInWindow] fromView: nil];
NSRect aBounds = [theView bounds];
+ return Graphic3d_Vec2i (Standard_Integer(aMouseLoc.x),
+ Standard_Integer(aBounds.size.height - aMouseLoc.y));
+}
- theX = Standard_Integer(aMouseLoc.x);
- theY = Standard_Integer(aBounds.size.height - aMouseLoc.y);
+//! Convert key flags from mouse event.
+static Aspect_VKeyFlags getMouseKeyFlags (NSEvent* theEvent)
+{
+ Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
+ if (([theEvent modifierFlags] & NSEventModifierFlagShift) != 0)
+ {
+ aFlags |= Aspect_VKeyFlags_SHIFT;
+ }
+ if (([theEvent modifierFlags] & NSEventModifierFlagControl) != 0)
+ {
+ aFlags |= Aspect_VKeyFlags_CTRL;
+ }
+ if (([theEvent modifierFlags] & NSEventModifierFlagOption) != 0)
+ {
+ aFlags |= Aspect_VKeyFlags_ALT;
+ }
+ if (([theEvent modifierFlags] & NSEventModifierFlagFunction) != 0)
+ {
+ //aFlags |= Aspect_VKeyFlags_FUNC;
+ }
+ if (([theEvent modifierFlags] & NSEventModifierFlagCommand) != 0)
+ {
+ //aFlags |= Aspect_VKeyFlags_CMD;
+ }
+ return aFlags;
}
@implementation ViewerTest_CocoaEventManagerView
- (void )setFrameSize: (NSSize )theNewSize
{
[super setFrameSize: theNewSize];
- VT_ProcessConfigure();
+ ViewerTest::CurrentEventManager()->ProcessConfigure();
}
// =======================================================================
- (void )drawRect: (NSRect )theDirtyRect
{
(void )theDirtyRect;
- VT_ProcessExpose();
+ if (!ViewerTest::CurrentEventManager().IsNull())
+ {
+ ViewerTest::CurrentEventManager()->ProcessExpose();
+ }
}
// =======================================================================
// =======================================================================
- (void )mouseMoved: (NSEvent* )theEvent
{
- getMouseCoords (self, theEvent, X_Motion, Y_Motion);
- VT_ProcessMotion();
+ const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
+ const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
+ const Aspect_VKeyMouse aButtons = ViewerTest::CurrentEventManager()->PressedMouseButtons();
+ ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
}
// =======================================================================
// =======================================================================
- (void )mouseDown: (NSEvent* )theEvent
{
- getMouseCoords (self, theEvent, X_ButtonPress, Y_ButtonPress);
- VT_ProcessButton1Press (0, NULL, Standard_False, [theEvent modifierFlags] & NSEventModifierFlagShift);
+ const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
+ const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
+ ViewerTest::CurrentEventManager()->PressMouseButton (aPos, Aspect_VKeyMouse_LeftButton, aFlags, false);
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
}
// =======================================================================
// =======================================================================
- (void )mouseUp: (NSEvent* )theEvent
{
- getMouseCoords (self, theEvent, X_Motion, Y_Motion);
- VT_ProcessButton1Release([theEvent modifierFlags] & NSEventModifierFlagShift);
+ const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
+ const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
+ ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, Aspect_VKeyMouse_LeftButton, aFlags, false);
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
}
-
// =======================================================================
// function : mouseDragged
// purpose :
// =======================================================================
- (void )mouseDragged: (NSEvent* )theEvent
{
- IsDragged = Standard_True;
- if ([theEvent modifierFlags] & NSEventModifierFlagControl)
- {
- getMouseCoords (self, theEvent, X_Motion, Y_Motion);
- VT_ProcessControlButton2Motion();
- }
+ const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
+ const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
+ const Aspect_VKeyMouse aButtons = ViewerTest::CurrentEventManager()->PressedMouseButtons();
+ ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
}
// =======================================================================
// =======================================================================
- (void )rightMouseDown: (NSEvent* )theEvent
{
- getMouseCoords (self, theEvent, X_ButtonPress, Y_ButtonPress);
- VT_ProcessButton3Press(); // Start rotation
+ const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
+ const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
+ ViewerTest::CurrentEventManager()->PressMouseButton (aPos, Aspect_VKeyMouse_RightButton, aFlags, false);
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
}
// =======================================================================
// =======================================================================
- (void )rightMouseUp: (NSEvent* )theEvent
{
- (void )theEvent;
- VT_ProcessButton3Release();
+ const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
+ const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
+ ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, Aspect_VKeyMouse_RightButton, aFlags, false);
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
}
// =======================================================================
// =======================================================================
- (void )rightMouseDragged: (NSEvent* )theEvent
{
- if ([theEvent modifierFlags] & NSEventModifierFlagControl)
- {
- getMouseCoords (self, theEvent, X_Motion, Y_Motion);
- VT_ProcessControlButton3Motion();
- }
+ const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
+ const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
+ const Aspect_VKeyMouse aButtons = ViewerTest::CurrentEventManager()->PressedMouseButtons();
+ ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
}
// =======================================================================
// =======================================================================
- (void )scrollWheel: (NSEvent* )theEvent
{
- float aDelta = [theEvent deltaY];
+ const Graphic3d_Vec2i aPos = getMouseCoords (self, theEvent);
+ const Aspect_VKeyFlags aFlags = getMouseKeyFlags (theEvent);
+
+ const Standard_Real aDelta = [theEvent deltaY];
if (Abs (aDelta) < 0.001)
{
// a lot of values near zero can be generated by touchpad
return;
}
- ViewerTest::CurrentView()->Zoom (0, 0, aDelta, aDelta);
+ ViewerTest::CurrentEventManager()->UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDelta, aFlags));
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
}
// =======================================================================
// =======================================================================
- (void )keyDown: (NSEvent* )theEvent
{
- NSString* aStringNs = [theEvent characters];
- if (aStringNs == NULL || [aStringNs length] == 0)
+ unsigned int aKeyCode = [theEvent keyCode];
+ const Aspect_VKey aVKey = Cocoa_Window::VirtualKeyFromNative (aKeyCode);
+ if (aVKey != Aspect_VKey_UNKNOWN)
{
- return;
+ const double aTimeStamp = [theEvent timestamp];
+ ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
}
- const Standard_CString aString = [aStringNs UTF8String];
- VT_ProcessKeyPress (aString);
+ //NSString* aStringNs = [theEvent characters];
+ //if (aStringNs != NULL && [aStringNs length] != 1)
+ //{
+ // const Standard_CString aString = [aStringNs UTF8String];
+ //}
+}
+
+// =======================================================================
+// function : keyUp
+// purpose :
+// =======================================================================
+- (void )keyUp: (NSEvent* )theEvent
+{
+ unsigned int aKeyCode = [theEvent keyCode];
+ const Aspect_VKey aVKey = Cocoa_Window::VirtualKeyFromNative (aKeyCode);
+ if (aVKey != Aspect_VKey_UNKNOWN)
+ {
+ const double aTimeStamp = [theEvent timestamp];
+ ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
+ ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
+ }
}
@end
aYBottom = theY1;
}
+// =======================================================================
+// function : SetTitle
+// purpose :
+// =======================================================================
+void WNT_Window::SetTitle (const TCollection_AsciiString& theTitle)
+{
+ const TCollection_ExtendedString aTitleW (theTitle);
+ SetWindowTextW ((HWND )myHWindow, aTitleW.ToWideString());
+}
+
// =======================================================================
// function : InvalidateContent
// purpose :
}
}
+// =======================================================================
+// function : VirtualKeyFromNative
+// purpose :
+// =======================================================================
+Aspect_VKey WNT_Window::VirtualKeyFromNative (Standard_Integer theKey)
+{
+ if (theKey >= Standard_Integer('0')
+ && theKey <= Standard_Integer('9'))
+ {
+ return Aspect_VKey((theKey - Standard_Integer('0')) + Aspect_VKey_0);
+ }
+ if (theKey >= Standard_Integer('A')
+ && theKey <= Standard_Integer('Z'))
+ {
+ // main latin alphabet keys
+ return Aspect_VKey((theKey - Standard_Integer('A')) + Aspect_VKey_A);
+ }
+ if (theKey >= VK_F1
+ && theKey <= VK_F24)
+ {
+ // special keys
+ if (theKey <= VK_F12)
+ {
+ return Aspect_VKey((theKey - VK_F1) + Aspect_VKey_F1);
+ }
+ return Aspect_VKey_UNKNOWN;
+ }
+ if (theKey >= VK_NUMPAD0
+ && theKey <= VK_NUMPAD9)
+ {
+ // numpad keys
+ return Aspect_VKey((theKey - VK_NUMPAD0) + Aspect_VKey_Numpad0);
+ }
+
+ switch (theKey)
+ {
+ case VK_LBUTTON:
+ case VK_RBUTTON:
+ case VK_CANCEL:
+ case VK_MBUTTON:
+ case VK_XBUTTON1:
+ case VK_XBUTTON2:
+ return Aspect_VKey_UNKNOWN;
+ case VK_BACK:
+ return Aspect_VKey_Backspace;
+ case VK_TAB:
+ return Aspect_VKey_Tab;
+ case VK_CLEAR:
+ return Aspect_VKey_UNKNOWN;
+ case VK_RETURN:
+ return Aspect_VKey_Enter;
+ case VK_SHIFT:
+ return Aspect_VKey_Shift;
+ case VK_CONTROL:
+ return Aspect_VKey_Control;
+ case VK_MENU:
+ return Aspect_VKey_Alt; //Aspect_VKey_Menu;
+ case VK_PAUSE:
+ case VK_CAPITAL:
+ return Aspect_VKey_UNKNOWN;
+ case VK_ESCAPE:
+ return Aspect_VKey_Escape;
+ case VK_CONVERT:
+ case VK_NONCONVERT:
+ case VK_ACCEPT:
+ case VK_MODECHANGE:
+ return Aspect_VKey_UNKNOWN;
+ case VK_SPACE:
+ return Aspect_VKey_Space;
+ case VK_PRIOR:
+ return Aspect_VKey_PageUp;
+ case VK_NEXT:
+ return Aspect_VKey_PageDown;
+ case VK_END:
+ return Aspect_VKey_End;
+ case VK_HOME:
+ return Aspect_VKey_Home;
+ case VK_LEFT:
+ return Aspect_VKey_Left;
+ case VK_UP:
+ return Aspect_VKey_Up;
+ case VK_DOWN:
+ return Aspect_VKey_Down;
+ case VK_RIGHT:
+ return Aspect_VKey_Right;
+ case VK_SELECT:
+ case VK_PRINT:
+ case VK_EXECUTE:
+ case VK_SNAPSHOT:
+ return Aspect_VKey_UNKNOWN;
+ case VK_INSERT:
+ return Aspect_VKey_UNKNOWN; // Aspect_VKey_Insert
+ case VK_DELETE:
+ return Aspect_VKey_Delete;
+ case VK_HELP:
+ case VK_LWIN:
+ case VK_RWIN:
+ case VK_APPS:
+ case VK_SLEEP:
+ return Aspect_VKey_UNKNOWN;
+ case VK_MULTIPLY:
+ return Aspect_VKey_NumpadMultiply;
+ case VK_ADD:
+ return Aspect_VKey_NumpadAdd;
+ case VK_SEPARATOR:
+ case VK_DECIMAL:
+ return Aspect_VKey_UNKNOWN;
+ case VK_SUBTRACT:
+ return Aspect_VKey_NumpadSubtract;
+ case VK_DIVIDE:
+ return Aspect_VKey_NumpadDivide;
+ case VK_NUMLOCK:
+ return Aspect_VKey_Numlock;
+ case VK_SCROLL:
+ return Aspect_VKey_Scroll;
+ case VK_LSHIFT:
+ case VK_RSHIFT:
+ case VK_LCONTROL:
+ case VK_RCONTROL:
+ case VK_LMENU:
+ case VK_RMENU:
+ return Aspect_VKey_UNKNOWN;
+ case VK_BROWSER_BACK:
+ return Aspect_VKey_BrowserBack;
+ case VK_BROWSER_FORWARD:
+ return Aspect_VKey_BrowserForward;
+ case VK_BROWSER_REFRESH:
+ return Aspect_VKey_BrowserRefresh;
+ case VK_BROWSER_STOP:
+ return Aspect_VKey_BrowserStop;
+ case VK_BROWSER_SEARCH:
+ return Aspect_VKey_BrowserSearch;
+ case VK_BROWSER_FAVORITES:
+ return Aspect_VKey_BrowserFavorites;
+ case VK_BROWSER_HOME:
+ return Aspect_VKey_BrowserHome;
+ case VK_VOLUME_MUTE:
+ return Aspect_VKey_VolumeMute;
+ case VK_VOLUME_DOWN:
+ return Aspect_VKey_VolumeDown;
+ case VK_VOLUME_UP:
+ return Aspect_VKey_VolumeUp;
+ case VK_MEDIA_NEXT_TRACK:
+ return Aspect_VKey_MediaNextTrack;
+ case VK_MEDIA_PREV_TRACK:
+ return Aspect_VKey_MediaPreviousTrack;
+ case VK_MEDIA_STOP:
+ return Aspect_VKey_MediaStop;
+ case VK_MEDIA_PLAY_PAUSE:
+ return Aspect_VKey_MediaPlayPause;
+ case VK_OEM_1:
+ return Aspect_VKey_Semicolon;
+ case VK_OEM_PLUS:
+ return Aspect_VKey_Plus;
+ case VK_OEM_COMMA:
+ return Aspect_VKey_Comma;
+ case VK_OEM_MINUS:
+ return Aspect_VKey_Minus;
+ case VK_OEM_PERIOD:
+ return Aspect_VKey_Period;
+ case VK_OEM_2:
+ return Aspect_VKey_Slash;
+ case VK_OEM_3:
+ return Aspect_VKey_Tilde;
+ case VK_OEM_4:
+ return Aspect_VKey_BracketLeft;
+ case VK_OEM_5:
+ return Aspect_VKey_Backslash;
+ case VK_OEM_6:
+ return Aspect_VKey_BracketRight;
+ case VK_OEM_7:
+ return Aspect_VKey_Apostrophe;
+ }
+ return Aspect_VKey_UNKNOWN;
+}
+
+// =======================================================================
+// function : MouseKeyFlagsFromEvent
+// purpose :
+// =======================================================================
+Aspect_VKeyFlags WNT_Window::MouseKeyFlagsFromEvent (WPARAM theKeys)
+{
+ Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
+ if ((theKeys & MK_CONTROL) != 0)
+ {
+ aFlags |= Aspect_VKeyFlags_CTRL;
+ }
+ if ((theKeys & MK_SHIFT) != 0)
+ {
+ aFlags |= Aspect_VKeyFlags_SHIFT;
+ }
+ if (GetKeyState (VK_MENU) < 0)
+ {
+ aFlags |= Aspect_VKeyFlags_ALT;
+ }
+ return aFlags;
+}
+
+// =======================================================================
+// function : MouseKeyFlagsAsync
+// purpose :
+// =======================================================================
+Aspect_VKeyFlags WNT_Window::MouseKeyFlagsAsync()
+{
+ Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
+ if ((GetAsyncKeyState (VK_CONTROL) & 0x8000) != 0)
+ {
+ aFlags |= Aspect_VKeyFlags_CTRL;
+ }
+ if ((GetAsyncKeyState (VK_SHIFT) & 0x8000) != 0)
+ {
+ aFlags |= Aspect_VKeyFlags_SHIFT;
+ }
+ if ((GetAsyncKeyState (VK_MENU) & 0x8000) != 0)
+ {
+ aFlags |= Aspect_VKeyFlags_ALT;
+ }
+ return aFlags;
+}
+
+// =======================================================================
+// function : MouseButtonsFromEvent
+// purpose :
+// =======================================================================
+Aspect_VKeyMouse WNT_Window::MouseButtonsFromEvent (WPARAM theKeys)
+{
+ Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE;
+ if ((theKeys & MK_LBUTTON) != 0)
+ {
+ aButtons |= Aspect_VKeyMouse_LeftButton;
+ }
+ if ((theKeys & MK_MBUTTON) != 0)
+ {
+ aButtons |= Aspect_VKeyMouse_MiddleButton;
+ }
+ if ((theKeys & MK_RBUTTON) != 0)
+ {
+ aButtons |= Aspect_VKeyMouse_RightButton;
+ }
+ return aButtons;
+}
+
+// =======================================================================
+// function : MouseButtonsAsync
+// purpose :
+// =======================================================================
+Aspect_VKeyMouse WNT_Window::MouseButtonsAsync()
+{
+ Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE;
+ const bool isSwapped = GetSystemMetrics (SM_SWAPBUTTON) != 0;
+
+ if ((GetAsyncKeyState (!isSwapped ? VK_LBUTTON : VK_RBUTTON) & 0x8000) != 0)
+ {
+ aButtons |= Aspect_VKeyMouse_LeftButton;
+ }
+ if ((GetAsyncKeyState (VK_MBUTTON) & 0x8000) != 0)
+ {
+ aButtons |= Aspect_VKeyMouse_MiddleButton;
+ }
+ if ((GetAsyncKeyState (!isSwapped ? VK_RBUTTON : VK_LBUTTON) & 0x8000) != 0)
+ {
+ aButtons |= Aspect_VKeyMouse_RightButton;
+ }
+ return aButtons;
+}
+
#endif // _WIN32
#ifndef _WNT_Window_HeaderFile
#define _WNT_Window_HeaderFile
-#include <Standard.hxx>
+#include <Aspect_Window.hxx>
#if defined(_WIN32) && !defined(OCCT_UWP)
-#include <Standard_Type.hxx>
-#include <Standard_Integer.hxx>
+#include <Aspect_Drawable.hxx>
+#include <Aspect_VKey.hxx>
#include <Aspect_Handle.hxx>
-#include <Standard_Boolean.hxx>
-#include <Aspect_Window.hxx>
-#include <Standard_CString.hxx>
+#include <Standard_Type.hxx>
#include <WNT_Dword.hxx>
-#include <Quantity_NameOfColor.hxx>
-#include <Standard_Address.hxx>
-#include <Aspect_TypeOfResize.hxx>
-#include <Aspect_Drawable.hxx>
-class WNT_WClass;
-class Aspect_WindowDefinitionError;
-class Aspect_WindowError;
+class WNT_WClass;
-class WNT_Window;
DEFINE_STANDARD_HANDLE(WNT_Window, Aspect_Window)
//! This class defines Windows NT window
class WNT_Window : public Aspect_Window
{
+public:
+
+ //! Convert WInAPI virtual key (VK_ enumeration) into Aspect_VKey.
+ Standard_EXPORT static Aspect_VKey VirtualKeyFromNative (Standard_Integer theKey);
+
+ //! Convert WPARAM from mouse event to key flags.
+ Standard_EXPORT static Aspect_VKeyFlags MouseKeyFlagsFromEvent (WPARAM theKeys);
+
+ //! Convert WPARAM from mouse event to mouse buttons bitmask.
+ Standard_EXPORT static Aspect_VKeyMouse MouseButtonsFromEvent (WPARAM theKeys);
+
+ //! Use GetAsyncKeyState() to fetch actual mouse key flags regardless of event loop.
+ Standard_EXPORT static Aspect_VKeyFlags MouseKeyFlagsAsync();
+
+ //! Use GetAsyncKeyState() to fetch actual mouse buttons state regardless of event loop.
+ Standard_EXPORT static Aspect_VKeyMouse MouseButtonsAsync();
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
//! Returns nothing on Windows
virtual Aspect_FBConfig NativeFBConfig() const Standard_OVERRIDE { return NULL; }
+ //! Sets window title.
+ Standard_EXPORT virtual void SetTitle (const TCollection_AsciiString& theTitle) Standard_OVERRIDE;
+
//! 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;
#include <Message.hxx>
#include <Message_Messenger.hxx>
+//#include <X11/XF86keysym.h>
+
#if defined(HAVE_EGL) || defined(HAVE_GLES2)
#include <EGL/egl.h>
#ifndef EGL_OPENGL_ES3_BIT
theHeight = aWinAttr.height;
}
+// =======================================================================
+// function : SetTitle
+// purpose :
+// =======================================================================
+void Xw_Window::SetTitle (const TCollection_AsciiString& theTitle)
+{
+ if (myXWindow != 0)
+ {
+ XStoreName (myDisplay->GetDisplay(), myXWindow, theTitle.ToCString());
+ }
+}
+
// =======================================================================
// function : InvalidateContent
// purpose :
XFlush (aDispX);
}
+// =======================================================================
+// function : VirtualKeyFromNative
+// purpose :
+// =======================================================================
+Aspect_VKey Xw_Window::VirtualKeyFromNative (unsigned long theKey)
+{
+ if (theKey >= XK_0
+ && theKey <= XK_9)
+ {
+ return Aspect_VKey(theKey - XK_0 + Aspect_VKey_0);
+ }
+
+ if (theKey >= XK_A
+ && theKey <= XK_Z)
+ {
+ return Aspect_VKey(theKey - XK_A + Aspect_VKey_A);
+ }
+
+ if (theKey >= XK_a
+ && theKey <= XK_z)
+ {
+ return Aspect_VKey(theKey - XK_a + Aspect_VKey_A);
+ }
+
+ if (theKey >= XK_F1
+ && theKey <= XK_F24)
+ {
+ if (theKey <= XK_F12)
+ {
+ return Aspect_VKey(theKey - XK_F1 + Aspect_VKey_F1);
+ }
+ return Aspect_VKey_UNKNOWN;
+ }
+
+ switch (theKey)
+ {
+ case XK_space:
+ return Aspect_VKey_Space;
+ case XK_apostrophe:
+ return Aspect_VKey_Apostrophe;
+ case XK_comma:
+ return Aspect_VKey_Comma;
+ case XK_minus:
+ return Aspect_VKey_Minus;
+ case XK_period:
+ return Aspect_VKey_Period;
+ case XK_semicolon:
+ return Aspect_VKey_Semicolon;
+ case XK_equal:
+ return Aspect_VKey_Equal;
+ case XK_bracketleft:
+ return Aspect_VKey_BracketLeft;
+ case XK_backslash:
+ return Aspect_VKey_Backslash;
+ case XK_bracketright:
+ return Aspect_VKey_BracketRight;
+ case XK_BackSpace:
+ return Aspect_VKey_Backspace;
+ case XK_Tab:
+ return Aspect_VKey_Tab;
+ //case XK_Linefeed:
+ case XK_Return:
+ case XK_KP_Enter:
+ return Aspect_VKey_Enter;
+ //case XK_Pause:
+ // return Aspect_VKey_Pause;
+ case XK_Escape:
+ return Aspect_VKey_Escape;
+ case XK_Home:
+ return Aspect_VKey_Home;
+ case XK_Left:
+ return Aspect_VKey_Left;
+ case XK_Up:
+ return Aspect_VKey_Up;
+ case XK_Right:
+ return Aspect_VKey_Right;
+ case XK_Down:
+ return Aspect_VKey_Down;
+ case XK_Prior:
+ return Aspect_VKey_PageUp;
+ case XK_Next:
+ return Aspect_VKey_PageDown;
+ case XK_End:
+ return Aspect_VKey_End;
+ //case XK_Insert:
+ // return Aspect_VKey_Insert;
+ case XK_Menu:
+ return Aspect_VKey_Menu;
+ case XK_Num_Lock:
+ return Aspect_VKey_Numlock;
+ //case XK_KP_Delete:
+ // return Aspect_VKey_NumDelete;
+ case XK_KP_Multiply:
+ return Aspect_VKey_NumpadMultiply;
+ case XK_KP_Add:
+ return Aspect_VKey_NumpadAdd;
+ //case XK_KP_Separator:
+ // return Aspect_VKey_Separator;
+ case XK_KP_Subtract:
+ return Aspect_VKey_NumpadSubtract;
+ //case XK_KP_Decimal:
+ // return Aspect_VKey_Decimal;
+ case XK_KP_Divide:
+ return Aspect_VKey_NumpadDivide;
+ case XK_Shift_L:
+ case XK_Shift_R:
+ return Aspect_VKey_Shift;
+ case XK_Control_L:
+ case XK_Control_R:
+ return Aspect_VKey_Control;
+ //case XK_Caps_Lock:
+ // return Aspect_VKey_CapsLock;
+ case XK_Alt_L:
+ case XK_Alt_R:
+ return Aspect_VKey_Alt;
+ //case XK_Super_L:
+ //case XK_Super_R:
+ // return Aspect_VKey_Super;
+ case XK_Delete:
+ return Aspect_VKey_Delete;
+
+ case 0x1008FF11: // XF86AudioLowerVolume
+ return Aspect_VKey_VolumeDown;
+ case 0x1008FF12: // XF86AudioMute
+ return Aspect_VKey_VolumeMute;
+ case 0x1008FF13: // XF86AudioRaiseVolume
+ return Aspect_VKey_VolumeUp;
+
+ case 0x1008FF14: // XF86AudioPlay
+ return Aspect_VKey_MediaPlayPause;
+ case 0x1008FF15: // XF86AudioStop
+ return Aspect_VKey_MediaStop;
+ case 0x1008FF16: // XF86AudioPrev
+ return Aspect_VKey_MediaPreviousTrack;
+ case 0x1008FF17: // XF86AudioNext
+ return Aspect_VKey_MediaNextTrack;
+
+ case 0x1008FF18: // XF86HomePage
+ return Aspect_VKey_BrowserHome;
+ case 0x1008FF26: // XF86Back
+ return Aspect_VKey_BrowserBack;
+ case 0x1008FF27: // XF86Forward
+ return Aspect_VKey_BrowserForward;
+ case 0x1008FF28: // XF86Stop
+ return Aspect_VKey_BrowserStop;
+ case 0x1008FF29: // XF86Refresh
+ return Aspect_VKey_BrowserRefresh;
+ }
+ return Aspect_VKey_UNKNOWN;
+}
+
#endif // Win32 or Mac OS X
#include <Aspect_Window.hxx>
+#include <Aspect_VKey.hxx>
#include <Aspect_DisplayConnection.hxx>
#include <Aspect_FillMethod.hxx>
#include <Aspect_GradientFillMethod.hxx>
//! This class defines XLib window intended for creation of OpenGL context.
class Xw_Window : public Aspect_Window
{
+public:
+
+ //! Convert X11 virtual key (KeySym) into Aspect_VKey.
+ Standard_EXPORT static Aspect_VKey VirtualKeyFromNative (unsigned long theKey);
public:
return myFBConfig;
}
+ //! Sets window title.
+ Standard_EXPORT virtual void SetTitle (const TCollection_AsciiString& theTitle) Standard_OVERRIDE;
+
//! Invalidate entire window content through generation of Expose event.
//! This method does not aggregate multiple calls into single event - dedicated event will be sent on each call.
//! When NULL display connection is specified, the connection specified on window creation will be used.
vselect 0 0
-vselect 75 230 235 320 -allowoverlap 1 1
-vselect 350 150 380 170 1
+vselect 75 230 235 320 -allowoverlap 1 1
+vselect 350 150 380 170 -allowOverlap 1 1
vnbselected
set aNbSelected4 [vnbselected]
if {$aNbSelected4 != 13} {