441 lines
14 KiB
C++
441 lines
14 KiB
C++
/***************************************************************************
|
|
* 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/SbVec2f.h>
|
|
#include <Inventor/SbVec2s.h>
|
|
#include <Inventor/SbVec3f.h>
|
|
#include <Inventor/SbPlane.h>
|
|
#include <Inventor/SbRotation.h>
|
|
#include <Inventor/SbTime.h>
|
|
#include <Inventor/events/SoEvents.h>
|
|
#include <QCursor>
|
|
#include <QEvent>
|
|
#include <Base/BaseClass.h>
|
|
#include <Gui/Namespace.h>
|
|
#include <FCGlobal.h>
|
|
|
|
// forward declarations
|
|
class SoEvent;
|
|
class SoMouseWheelEvent;
|
|
class SoMotion3Event;
|
|
class SoQtViewer;
|
|
class SoCamera;
|
|
class SoSensor;
|
|
class SbSphereSheetProjector;
|
|
|
|
namespace Gui {
|
|
|
|
class View3DInventorViewer;
|
|
class AbstractMouseSelection;
|
|
|
|
/**
|
|
* @author Werner Mayer
|
|
*/
|
|
class GuiExport NavigationStyleEvent : public QEvent
|
|
{
|
|
public:
|
|
NavigationStyleEvent(const Base::Type& s);
|
|
~NavigationStyleEvent();
|
|
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();
|
|
|
|
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 OrbitStyle {
|
|
Turntable,
|
|
Trackball
|
|
};
|
|
|
|
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();
|
|
virtual ~NavigationStyle();
|
|
|
|
NavigationStyle& operator = (const NavigationStyle& ns);
|
|
void setViewer(View3DInventorViewer*);
|
|
|
|
void setAnimationEnabled(const SbBool enable);
|
|
SbBool isAnimationEnabled() const;
|
|
|
|
void startAnimating(const SbVec3f& axis, float velocity);
|
|
void stopAnimating();
|
|
SbBool isAnimating() 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;
|
|
|
|
void updateAnimation();
|
|
void redraw();
|
|
|
|
void setCameraOrientation(const SbRotation& rot, SbBool moveTocenter=false);
|
|
void lookAtPoint(const SbVec3f&);
|
|
void boxZoom(const SbBox2s& box);
|
|
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;
|
|
|
|
void setOrbitStyle(OrbitStyle style);
|
|
OrbitStyle getOrbitStyle() const;
|
|
|
|
protected:
|
|
void initialize();
|
|
void finalize();
|
|
|
|
void interactiveCountInc();
|
|
void interactiveCountDec();
|
|
int getInteractiveCount() const;
|
|
|
|
SbBool isViewing() const;
|
|
void setViewing(SbBool);
|
|
SbBool isSeekMode() const;
|
|
void setSeekMode(SbBool enable);
|
|
SbBool seekToPoint(const SbVec2s screenpos);
|
|
void seekToPoint(const SbVec3f& scenepos);
|
|
SbBool lookAtPoint(const SbVec2s screenpos);
|
|
SbVec3f getRotationCenter(SbBool*) const;
|
|
|
|
void reorientCamera(SoCamera * camera, const SbRotation & rot);
|
|
void panCamera(SoCamera * camera,
|
|
float vpaspect,
|
|
const SbPlane & panplane,
|
|
const SbVec2f & previous,
|
|
const SbVec2f & current);
|
|
void pan(SoCamera* camera);
|
|
void panToCenter(const SbPlane & pplane, const SbVec2f & currpos);
|
|
int getDelta() const;
|
|
void zoom(SoCamera * camera, float diffvalue);
|
|
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 doRotate(SoCamera * camera, float angle, const SbVec2f& pos);
|
|
void spin(const SbVec2f & pointerpos);
|
|
SbBool doSpin();
|
|
void spin_simplified(SoCamera *cam, 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);
|
|
|
|
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;
|
|
ViewerMode currentmode;
|
|
SoMouseButtonEvent mouseDownConsumedEvent;
|
|
SbVec2f lastmouseposition;
|
|
SbVec2s globalPos;
|
|
SbVec2s localPos;
|
|
SbPlane panningplane;
|
|
SbTime prevRedrawTime;
|
|
SbTime centerTime;
|
|
SbBool lockrecenter;
|
|
SbBool menuenabled;
|
|
SbBool ctrldown, shiftdown, altdown;
|
|
SbBool button1down, button2down, button3down;
|
|
SbBool invertZoom;
|
|
SbBool zoomAtCursor;
|
|
float zoomStep;
|
|
|
|
/** @name Mouse model */
|
|
//@{
|
|
AbstractMouseSelection* mouseSelection;
|
|
std::vector<SbVec2s> pcPolygon;
|
|
SelectionRole selectedRole;
|
|
//@}
|
|
|
|
/** @name Spinning data */
|
|
//@{
|
|
SbBool spinanimatingallowed;
|
|
int spinsamplecounter;
|
|
SbRotation spinincrement;
|
|
SbRotation spinRotation;
|
|
SbSphereSheetProjector * spinprojector;
|
|
//@}
|
|
|
|
private:
|
|
NavigationStyle(const NavigationStyle&);
|
|
struct NavigationStyleP* pimpl;
|
|
friend struct NavigationStyleP;
|
|
};
|
|
|
|
/** 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();
|
|
|
|
public:
|
|
UserNavigationStyle(){}
|
|
~UserNavigationStyle(){}
|
|
virtual const char* mouseButtons(ViewerMode) = 0;
|
|
virtual std::string userFriendlyName() const;
|
|
static std::map<Base::Type, std::string> getUserFriendlyNames();
|
|
};
|
|
|
|
class GuiExport InventorNavigationStyle : public UserNavigationStyle {
|
|
typedef UserNavigationStyle inherited;
|
|
|
|
TYPESYSTEM_HEADER();
|
|
|
|
public:
|
|
InventorNavigationStyle();
|
|
~InventorNavigationStyle();
|
|
const char* mouseButtons(ViewerMode);
|
|
virtual std::string userFriendlyName() const;
|
|
|
|
protected:
|
|
SbBool processSoEvent(const SoEvent * const ev);
|
|
};
|
|
|
|
class GuiExport CADNavigationStyle : public UserNavigationStyle {
|
|
typedef UserNavigationStyle inherited;
|
|
|
|
TYPESYSTEM_HEADER();
|
|
|
|
public:
|
|
CADNavigationStyle();
|
|
~CADNavigationStyle();
|
|
const char* mouseButtons(ViewerMode);
|
|
|
|
protected:
|
|
SbBool processSoEvent(const SoEvent * const ev);
|
|
|
|
private:
|
|
SbBool lockButton1;
|
|
};
|
|
|
|
class GuiExport RevitNavigationStyle : public UserNavigationStyle {
|
|
typedef UserNavigationStyle inherited;
|
|
|
|
TYPESYSTEM_HEADER();
|
|
|
|
public:
|
|
RevitNavigationStyle();
|
|
~RevitNavigationStyle();
|
|
const char* mouseButtons(ViewerMode);
|
|
|
|
protected:
|
|
SbBool processSoEvent(const SoEvent * const ev);
|
|
|
|
private:
|
|
SbBool lockButton1;
|
|
};
|
|
|
|
class GuiExport BlenderNavigationStyle : public UserNavigationStyle {
|
|
typedef UserNavigationStyle inherited;
|
|
|
|
TYPESYSTEM_HEADER();
|
|
|
|
public:
|
|
BlenderNavigationStyle();
|
|
~BlenderNavigationStyle();
|
|
const char* mouseButtons(ViewerMode);
|
|
|
|
protected:
|
|
SbBool processSoEvent(const SoEvent * const ev);
|
|
|
|
private:
|
|
SbBool lockButton1;
|
|
};
|
|
|
|
class GuiExport MayaGestureNavigationStyle : public UserNavigationStyle {
|
|
typedef UserNavigationStyle inherited;
|
|
|
|
TYPESYSTEM_HEADER();
|
|
|
|
public:
|
|
MayaGestureNavigationStyle();
|
|
~MayaGestureNavigationStyle();
|
|
const char* mouseButtons(ViewerMode);
|
|
|
|
protected:
|
|
SbBool processSoEvent(const SoEvent * const ev);
|
|
|
|
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 {
|
|
typedef UserNavigationStyle inherited;
|
|
|
|
TYPESYSTEM_HEADER();
|
|
|
|
public:
|
|
TouchpadNavigationStyle();
|
|
~TouchpadNavigationStyle();
|
|
const char* mouseButtons(ViewerMode);
|
|
|
|
protected:
|
|
SbBool processSoEvent(const SoEvent * const ev);
|
|
};
|
|
|
|
class GuiExport OpenCascadeNavigationStyle : public UserNavigationStyle {
|
|
typedef UserNavigationStyle inherited;
|
|
|
|
TYPESYSTEM_HEADER();
|
|
|
|
public:
|
|
OpenCascadeNavigationStyle();
|
|
~OpenCascadeNavigationStyle();
|
|
const char* mouseButtons(ViewerMode);
|
|
|
|
protected:
|
|
SbBool processSoEvent(const SoEvent * const ev);
|
|
};
|
|
|
|
class GuiExport OpenSCADNavigationStyle : public UserNavigationStyle {
|
|
typedef UserNavigationStyle inherited;
|
|
|
|
TYPESYSTEM_HEADER();
|
|
|
|
public:
|
|
OpenSCADNavigationStyle();
|
|
~OpenSCADNavigationStyle();
|
|
const char* mouseButtons(ViewerMode);
|
|
|
|
protected:
|
|
SbBool processSoEvent(const SoEvent * const ev);
|
|
};
|
|
|
|
class GuiExport TinkerCADNavigationStyle : public UserNavigationStyle {
|
|
typedef UserNavigationStyle inherited;
|
|
|
|
TYPESYSTEM_HEADER();
|
|
|
|
public:
|
|
TinkerCADNavigationStyle();
|
|
~TinkerCADNavigationStyle();
|
|
const char* mouseButtons(ViewerMode);
|
|
|
|
protected:
|
|
SbBool processSoEvent(const SoEvent * const ev);
|
|
};
|
|
|
|
} // namespace Gui
|
|
|
|
Q_DECLARE_OPERATORS_FOR_FLAGS(Gui::NavigationStyle::RotationCenterModes)
|
|
|
|
#endif // GUI_NAVIGATIONSTYLE_H
|