FreeCAD / src /Gui /Navigation /NavigationStyle.h
AbdulElahGwaith's picture
Upload folder using huggingface_hub
985c397 verified
// SPDX-License-Identifier: LGPL-2.1-or-later
/***************************************************************************
* Copyright (c) 2008 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_NAVIGATIONSTYLE_H
#define GUI_NAVIGATIONSTYLE_H
#include <Inventor/C/basic.h>
#include <Inventor/SbBox2s.h>
#include <Inventor/SbPlane.h>
#include <Inventor/SbRotation.h>
#include <Inventor/SbSphere.h>
#include <Inventor/SbTime.h>
#include <Inventor/SbVec2f.h>
#include <Inventor/SbVec2s.h>
#include <Inventor/SbVec3f.h>
#include <Inventor/events/SoEvents.h>
#include <QEvent>
#include <QAction>
#include <Base/BaseClass.h>
#include <Base/SmartPtrPy.h>
#include <Gui/Namespace.h>
#include <FCGlobal.h>
#include <memory>
#include <optional>
// forward declarations
class SoEvent;
class SoMouseWheelEvent;
class SoMotion3Event;
class SoQtViewer;
class SoCamera;
class SoSensor;
class SbSphereSheetProjector;
// NOLINTBEGIN(cppcoreguidelines-avoid*, readability-avoid-const-params-in-decls)
namespace Gui
{
class View3DInventorViewer;
class NavigationAnimator;
class AbstractMouseSelection;
class NavigationAnimation;
/**
* @author Werner Mayer
*/
class GuiExport NavigationStyleEvent: public QEvent
{
public:
explicit NavigationStyleEvent(const Base::Type& s);
~NavigationStyleEvent() override;
const Base::Type& style() const;
private:
Base::Type t;
};
/**
* The navigation style base class
* @author Werner Mayer
*/
class GuiExport NavigationStyle: public Base::BaseClass
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
enum ViewerMode
{
IDLE,
INTERACT,
ZOOMING,
BOXZOOM,
PANNING,
DRAGGING,
SPINNING,
SEEK_WAIT_MODE,
SEEK_MODE,
SELECTION
};
enum SelectionMode
{
Lasso = 0, /**< Select objects using a lasso. */
Rectangle = 1, /**< Select objects using a rectangle. */
Rubberband = 2, /**< Select objects using a rubberband. */
BoxZoom = 3, /**< Perform a box zoom. */
Clip = 4, /**< Clip objects using a lasso. */
};
enum class ClarifySelectionMode
{
Default, /**< Long press with LMB to trigger clarify selection */
Ctrl /**< Long press with Ctrl+LMB to trigger clarify selection */
};
enum OrbitStyle
{
Turntable,
Trackball,
FreeTurntable,
TrackballClassic,
RoundedArcball
};
enum class RotationCenterMode
{
WindowCenter = 0, /**< The center of the window */
ScenePointAtCursor = 1, /**< Find the point in the scene at the cursor position. If there is
no point then the focal plane is used */
FocalPointAtCursor = 2, /**< Find the point on the focal plane at the cursor position. */
BoundingBoxCenter = 4 /**< Find the center point of the bounding box of the scene. */
};
Q_DECLARE_FLAGS(RotationCenterModes, RotationCenterMode)
public:
NavigationStyle();
~NavigationStyle() override;
NavigationStyle(const NavigationStyle&) = delete;
NavigationStyle& operator=(const NavigationStyle& ns);
void setViewer(View3DInventorViewer*);
void setAnimationEnabled(const SbBool enable);
void setSpinningAnimationEnabled(const SbBool enable);
SbBool isAnimationEnabled() const;
SbBool isSpinningAnimationEnabled() const;
SbBool isAnimating() const;
SbBool isSpinning() const;
void startAnimating(const std::shared_ptr<NavigationAnimation>& animation, bool wait = false) const;
void stopAnimating() const;
void setSensitivity(float);
float getSensitivity() const;
void setResetCursorPosition(SbBool);
SbBool isResetCursorPosition() const;
void setZoomInverted(SbBool);
SbBool isZoomInverted() const;
void setZoomStep(float);
void setZoomAtCursor(SbBool);
SbBool isZoomAtCursor() const;
void zoomIn();
void zoomOut();
void setRotationCenterMode(RotationCenterModes);
RotationCenterModes getRotationCenterMode() const;
void setRotationCenter(const SbVec3f& cnt);
SbVec3f getFocalPoint() const;
SoCamera* getCamera() const;
std::shared_ptr<NavigationAnimation> setCameraOrientation(
const SbRotation& orientation,
SbBool moveToCenter = false
) const;
std::shared_ptr<NavigationAnimation> translateCamera(const SbVec3f& translation) const;
#if (COIN_MAJOR_VERSION * 100 + COIN_MINOR_VERSION * 10 + COIN_MICRO_VERSION < 403)
void findBoundingSphere();
#endif
void reorientCamera(SoCamera* camera, const SbRotation& rotation);
void reorientCamera(SoCamera* camera, const SbRotation& rotation, const SbVec3f& rotationCenter);
void boxZoom(const SbBox2s& box);
// Scale the camera inplace
void scale(float factor);
virtual void viewAll();
void setViewingMode(const ViewerMode newmode);
int getViewingMode() const;
virtual SbBool processEvent(const SoEvent* const ev);
virtual SbBool processMotionEvent(const SoMotion3Event* const ev);
virtual SbBool processKeyboardEvent(const SoKeyboardEvent* const event);
virtual SbBool processClickEvent(const SoMouseButtonEvent* const event);
virtual SbBool processWheelEvent(const SoMouseWheelEvent* const event);
void setPopupMenuEnabled(const SbBool on);
SbBool isPopupMenuEnabled() const;
void startSelection(AbstractMouseSelection*);
void startSelection(SelectionMode = Lasso);
void abortSelection();
void stopSelection();
SbBool isSelecting() const;
const std::vector<SbVec2s>& getPolygon(SelectionRole* role = nullptr) const;
bool isDraggerUnderCursor(const SbVec2s pos) const;
virtual ClarifySelectionMode clarifySelectionMode() const
{
return ClarifySelectionMode::Default;
}
void setOrbitStyle(OrbitStyle style);
OrbitStyle getOrbitStyle() const;
SbBool isViewing() const;
void setViewing(SbBool);
SbVec3f getRotationCenter(SbBool&) const;
std::optional<SbVec2s>& getRightClickPosition();
PyObject* getPyObject() override;
protected:
void initialize();
void finalize();
void interactiveCountInc();
void interactiveCountDec();
int getInteractiveCount() const;
SbBool isSeekMode() const;
void setSeekMode(SbBool enable);
SbBool seekToPoint(const SbVec2s screenpos);
void seekToPoint(const SbVec3f& scenepos);
void lookAtPoint(const SbVec2s screenpos);
void lookAtPoint(const SbVec3f& position);
void panCamera(
SoCamera* camera,
float vpaspect,
const SbPlane& panplane,
const SbVec2f& previous,
const SbVec2f& current
);
void setupPanningPlane(const SoCamera* camera);
int getDelta() const;
void zoom(SoCamera* camera, float diffvalue);
virtual void zoomByCursor(const SbVec2f& thispos, const SbVec2f& prevpos);
void doZoom(SoCamera* camera, int wheeldelta, const SbVec2f& pos);
void doZoom(SoCamera* camera, float logzoomfactor, const SbVec2f& pos);
void doScale(SoCamera* camera, float factor);
void doRotate(SoCamera* camera, float angle, const SbVec2f& pos);
void spin(const SbVec2f& pointerpos);
SbBool doSpin();
void spin_simplified(SbVec2f curpos, SbVec2f prevpos);
void moveCursorPosition();
void saveCursorPosition(const SoEvent* const ev);
SbVec2f normalizePixelPos(SbVec2s pixpos);
SbVec2f normalizePixelPos(SbVec2f pixpos);
SbBool handleEventInForeground(const SoEvent* const e);
virtual SbBool processSoEvent(const SoEvent* const ev);
void syncWithEvent(const SoEvent* const ev);
virtual void openPopupMenu(const SbVec2s& position);
private:
void spinInternal(const SbVec2f& pointerpos, const SbVec2f& lastpos);
void spinSimplifiedInternal(const SbVec2f curpos, const SbVec2f prevpos);
bool isNavigationStyleAction(QAction* action, QActionGroup* navMenuGroup) const;
QWidget* findView3DInventorWidget() const;
void applyNavigationStyleChange(QAction* selectedAction);
protected:
void clearLog();
void addToLog(const SbVec2s pos, const SbTime time);
void syncModifierKeys(const SoEvent* const ev);
protected:
struct
{ // tracking mouse movement in a log
short size;
short historysize;
SbVec2s* position;
SbTime* time;
} log;
View3DInventorViewer* viewer {nullptr};
NavigationAnimator* animator;
SbBool animationEnabled;
ViewerMode currentmode;
SoMouseButtonEvent mouseDownConsumedEvent;
SbVec2f lastmouseposition;
SbVec2s globalPos;
SbVec2s localPos;
SbPlane panningplane;
SbTime centerTime;
SbBool lockrecenter;
SbBool menuenabled;
SbBool ctrldown, shiftdown, altdown;
SbBool button1down, button2down, button3down;
SbBool invertZoom;
SbBool zoomAtCursor;
float zoomStep;
SbBool hasDragged;
SbBool hasPanned;
SbBool hasZoomed;
/** @name Mouse model */
//@{
AbstractMouseSelection* mouseSelection {nullptr};
std::vector<SbVec2s> pcPolygon;
SelectionRole selectedRole;
//@}
/** @name Spinning data */
//@{
SbBool spinningAnimationEnabled;
int spinsamplecounter;
SbRotation spinincrement;
SbSphereSheetProjector* spinprojector;
//@}
Py::SmartPtr pythonObject;
// store the position where right-click occurred just before
// the menu popped up
std::optional<SbVec2s> rightClickPosition;
private:
friend class NavigationAnimator;
SbVec3f rotationCenter;
SbBool rotationCenterFound;
SbBool rotationCenterIsScenePointAtCursor;
NavigationStyle::RotationCenterModes rotationCenterMode;
float sensitivity;
SbBool resetcursorpos;
#if (COIN_MAJOR_VERSION * 100 + COIN_MINOR_VERSION * 10 + COIN_MICRO_VERSION < 403)
SbSphere boundingSphere;
#endif
};
/** Sub-classes of this class appear in the preference dialog where users can
* choose their favorite navigation style.
* All other classes that inherit directly from NavigationStyle do not appear
* in the above dialog.
* This mechanism is useful to implement special navigation styles which are
* only needed for certain purposes. Thus, it should not be possible to be
* choosable by the user
* @author Werner Mayer
*/
class GuiExport UserNavigationStyle: public NavigationStyle
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
UserNavigationStyle() = default;
~UserNavigationStyle() override = default;
virtual const char* mouseButtons(ViewerMode) = 0;
virtual std::string userFriendlyName() const;
static std::map<Base::Type, std::string> getUserFriendlyNames();
};
class GuiExport InventorNavigationStyle: public UserNavigationStyle
{
using inherited = UserNavigationStyle;
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
InventorNavigationStyle();
~InventorNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
std::string userFriendlyName() const override;
ClarifySelectionMode clarifySelectionMode() const override
{
return ClarifySelectionMode::Ctrl;
}
protected:
SbBool processSoEvent(const SoEvent* const ev) override;
};
class GuiExport CADNavigationStyle: public UserNavigationStyle
{
using inherited = UserNavigationStyle;
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
CADNavigationStyle();
~CADNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
protected:
SbBool processSoEvent(const SoEvent* const ev) override;
private:
SbBool lockButton1 {false};
};
class GuiExport RevitNavigationStyle: public UserNavigationStyle
{
using inherited = UserNavigationStyle;
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
RevitNavigationStyle();
~RevitNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
protected:
SbBool processSoEvent(const SoEvent* const ev) override;
private:
SbBool lockButton1 {false};
};
class GuiExport BlenderNavigationStyle: public UserNavigationStyle
{
using inherited = UserNavigationStyle;
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
BlenderNavigationStyle();
~BlenderNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
protected:
SbBool processSoEvent(const SoEvent* const ev) override;
private:
SbBool lockButton1 {false};
};
class GuiExport SolidWorksNavigationStyle: public UserNavigationStyle
{
using inherited = UserNavigationStyle;
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
SolidWorksNavigationStyle();
~SolidWorksNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
protected:
SbBool processSoEvent(const SoEvent* const ev) override;
private:
SbBool lockButton1 {false};
};
class GuiExport MayaGestureNavigationStyle: public UserNavigationStyle
{
using inherited = UserNavigationStyle;
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
MayaGestureNavigationStyle();
~MayaGestureNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
protected:
void zoomByCursor(const SbVec2f& thispos, const SbVec2f& prevpos) override;
SbBool processSoEvent(const SoEvent* const ev) override;
SbVec2s mousedownPos; // the position where some mouse button was pressed (local pixel coordinates).
short mouseMoveThreshold; // setting. Minimum move required to consider it a move (in pixels).
bool mouseMoveThresholdBroken; // a flag that the move threshold was surpassed since last mousedown.
int mousedownConsumedCount; // a flag for remembering that a mousedown of button1/button2 was
// consumed.
SoMouseButtonEvent mousedownConsumedEvents[5]; // the event that was consumed and is to be
// refired. 2 should be enough, but just for a
// case of the maximum 5 buttons...
bool testMoveThreshold(const SbVec2s currentPos) const;
bool thisClickIsComplex; // a flag that becomes set when a complex clicking pattern is detected
// (i.e., two or more mouse buttons were down at the same time).
bool inGesture; // a flag that is used to filter out mouse events during gestures.
};
class GuiExport TouchpadNavigationStyle: public UserNavigationStyle
{
using inherited = UserNavigationStyle;
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
TouchpadNavigationStyle();
~TouchpadNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
protected:
SbBool processSoEvent(const SoEvent* const ev) override;
private:
SbBool blockPan {false}; // Used to block the first pan in a mouse movement to prevent big jumps
};
class GuiExport OpenCascadeNavigationStyle: public UserNavigationStyle
{
using inherited = UserNavigationStyle;
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
OpenCascadeNavigationStyle();
~OpenCascadeNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
protected:
SbBool processSoEvent(const SoEvent* const ev) override;
};
class GuiExport OpenSCADNavigationStyle: public UserNavigationStyle
{
using inherited = UserNavigationStyle;
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
OpenSCADNavigationStyle();
~OpenSCADNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
ClarifySelectionMode clarifySelectionMode() const override
{
return ClarifySelectionMode::Ctrl;
}
protected:
SbBool processSoEvent(const SoEvent* const ev) override;
};
class GuiExport TinkerCADNavigationStyle: public UserNavigationStyle
{
using inherited = UserNavigationStyle;
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
TinkerCADNavigationStyle();
~TinkerCADNavigationStyle() override;
const char* mouseButtons(ViewerMode) override;
protected:
SbBool processSoEvent(const SoEvent* const ev) override;
};
} // namespace Gui
// NOLINTEND(cppcoreguidelines-avoid*, readability-avoid-const-params-in-decls)
Q_DECLARE_OPERATORS_FOR_FLAGS(Gui::NavigationStyle::RotationCenterModes)
#endif // GUI_NAVIGATIONSTYLE_H