- Further extended usage of new shortcut class

- Refactored camera classes to take advantage of Qt's reference counting
- Removed some of the old implementation
This commit is contained in:
Aesylwinn 2016-07-19 22:04:15 -04:00
parent d8fa3fd1de
commit faa84e0a35
10 changed files with 265 additions and 275 deletions

View file

@ -69,7 +69,10 @@ namespace CSMPrefs
Shortcut* shortcut = *it;
if (shortcut->isActive())
{
shortcut->activate(false);
shortcut->setPosition(0);
}
}
}

View file

@ -236,6 +236,7 @@ void CSMPrefs::State::declare()
declareShortcut ("free-roll-left", "Free camera roll left", QKeySequence(Qt::Key_Q));
declareShortcut ("free-roll-right", "Free camera roll right", QKeySequence(Qt::Key_E));
declareShortcut ("free-speed-mode", "Free camera speed mode toggle", QKeySequence(Qt::Key_F));
declareSeparator ();
declareShortcut ("orbit-up", "Orbit camera up", QKeySequence(Qt::Key_W));
declareShortcut ("orbit-down", "Orbit camera down", QKeySequence(Qt::Key_S));
@ -245,6 +246,19 @@ void CSMPrefs::State::declare()
declareShortcut ("orbit-roll-right", "Orbit camera roll right", QKeySequence(Qt::Key_E));
declareShortcut ("orbit-speed-mode", "Orbit camera speed mode toggle", QKeySequence(Qt::Key_F));
declareShortcut ("orbit-center-selection", "Centers the camera on the selected item", QKeySequence(Qt::Key_C));
declareSeparator ();
declareShortcut ("scene-navi-primary", "Camera rotation from mouse movement", QKeySequence(Qt::LeftButton));
declareShortcut ("scene-navi-secondary", "Camera translation from mouse movement",
QKeySequence(Qt::ControlModifier | (int)Qt::LeftButton));
declareShortcut ("scene-edit-primary", "Scene primary edit button", QKeySequence(Qt::RightButton));
declareShortcut ("scene-edit-secondary", "Scene secondary edit button",
QKeySequence(Qt::ControlModifier | (int)Qt::RightButton));
declareShortcut ("scene-select-primary", "Scene primary select button", QKeySequence(Qt::MiddleButton));
declareShortcut ("scene-select-secondary", "Scene secondary select button",
QKeySequence(Qt::ControlModifier | (int)Qt::MiddleButton));
declareShortcut ("scene-edit-abort", "Scene editor abort key", QKeySequence(Qt::Key_Escape));
declareShortcut ("scene-focus-toolbar", "Change focus in scene editor", QKeySequence(Qt::Key_T));
}
void CSMPrefs::State::declareCategory (const std::string& key)

View file

@ -32,8 +32,9 @@ namespace CSVRender
const osg::Vec3d CameraController::LocalLeft = osg::Vec3d(1, 0, 0);
const osg::Vec3d CameraController::LocalForward = osg::Vec3d(0, 0, 1);
CameraController::CameraController()
: mActive(false)
CameraController::CameraController(QObject* parent)
: QObject(parent)
, mActive(false)
, mInverted(false)
, mCameraSensitivity(1/650.f)
, mSecondaryMoveMult(50)
@ -163,8 +164,9 @@ namespace CSVRender
Free Camera Controller
*/
FreeCameraController::FreeCameraController(CSMPrefs::ShortcutEventHandler* handler)
: mLockUpright(false)
FreeCameraController::FreeCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent)
: CameraController(parent)
, mLockUpright(false)
, mModified(false)
, mFast(false)
, mLeft(false)
@ -178,6 +180,16 @@ namespace CSVRender
, mRotSpeed(osg::PI / 2)
, mSpeedMult(8)
{
CSMPrefs::Shortcut* naviPrimaryShortcut = new CSMPrefs::Shortcut("scene-navi-primary", this);
naviPrimaryShortcut->enable(false);
handler->addShortcut(naviPrimaryShortcut);
connect(naviPrimaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviPrimary(bool)));
CSMPrefs::Shortcut* naviSecondaryShortcut = new CSMPrefs::Shortcut("scene-navi-secondary", this);
naviSecondaryShortcut->enable(false);
handler->addShortcut(naviSecondaryShortcut);
connect(naviSecondaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviSecondary(bool)));
CSMPrefs::Shortcut* forwardShortcut = new CSMPrefs::Shortcut("free-forward", this);
forwardShortcut->enable(false);
handler->addShortcut(forwardShortcut);
@ -211,7 +223,7 @@ namespace CSVRender
CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("free-speed-mode", this);
speedModeShortcut->enable(false);
handler->addShortcut(speedModeShortcut);
connect(speedModeShortcut, SIGNAL(activated(bool)), this, SLOT(swapSpeedMode(bool)));
connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
}
double FreeCameraController::getLinearSpeed() const
@ -261,13 +273,13 @@ namespace CSVRender
if (!isActive())
return false;
if (mode == "p-navi")
if (mNaviPrimary)
{
double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0);
yaw(x * scalar);
pitch(y * scalar);
}
else if (mode == "s-navi")
else if (mNaviSecondary)
{
osg::Vec3d movement;
movement += LocalLeft * -x * getSecondaryMovementMultiplier();
@ -384,54 +396,58 @@ namespace CSVRender
getCamera()->setViewMatrixAsLookAt(eye, center, mUp);
}
void FreeCameraController::naviPrimary(bool active)
{
mNaviPrimary = active;
}
void FreeCameraController::naviSecondary(bool active)
{
mNaviSecondary = active;
}
void FreeCameraController::forward(bool active)
{
if (isActive())
mForward = active;
mForward = active;
}
void FreeCameraController::left(bool active)
{
if (isActive())
mLeft = active;
mLeft = active;
}
void FreeCameraController::backward(bool active)
{
if (isActive())
mBackward = active;
mBackward = active;
}
void FreeCameraController::right(bool active)
{
if (isActive())
mRight = active;
mRight = active;
}
void FreeCameraController::rollLeft(bool active)
{
if (isActive())
mRollLeft = active;
mRollLeft = active;
}
void FreeCameraController::rollRight(bool active)
{
if (isActive())
mRollRight = active;
mRollRight = active;
}
void FreeCameraController::swapSpeedMode(bool active)
void FreeCameraController::swapSpeedMode()
{
if (isActive() && active)
mFast = !mFast;
mFast = !mFast;
}
/*
Orbit Camera Controller
*/
OrbitCameraController::OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler)
: mInitialized(false)
OrbitCameraController::OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent)
: CameraController(parent)
, mInitialized(false)
, mFast(false)
, mLeft(false)
, mRight(false)
@ -445,6 +461,16 @@ namespace CSVRender
, mOrbitSpeed(osg::PI / 4)
, mOrbitSpeedMult(4)
{
CSMPrefs::Shortcut* naviPrimaryShortcut = new CSMPrefs::Shortcut("scene-navi-primary", this);
naviPrimaryShortcut->enable(false);
handler->addShortcut(naviPrimaryShortcut);
connect(naviPrimaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviPrimary(bool)));
CSMPrefs::Shortcut* naviSecondaryShortcut = new CSMPrefs::Shortcut("scene-navi-secondary", this);
naviSecondaryShortcut->enable(false);
handler->addShortcut(naviSecondaryShortcut);
connect(naviSecondaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviSecondary(bool)));
CSMPrefs::Shortcut* upShortcut = new CSMPrefs::Shortcut("orbit-up", this);
upShortcut->enable(false);
handler->addShortcut(upShortcut);
@ -478,7 +504,7 @@ namespace CSVRender
CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("orbit-speed-mode", this);
speedModeShortcut->enable(false);
handler->addShortcut(speedModeShortcut);
connect(speedModeShortcut, SIGNAL(activated(bool)), this, SLOT(swapSpeedMode(bool)));
connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
}
osg::Vec3d OrbitCameraController::getCenter() const
@ -537,13 +563,13 @@ namespace CSVRender
if (!mInitialized)
initialize();
if (mode == "p-navi")
if (mNaviPrimary)
{
double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0);
rotateHorizontal(x * scalar);
rotateVertical(-y * scalar);
}
else if (mode == "s-navi")
else if (mNaviSecondary)
{
osg::Vec3d movement;
movement += LocalLeft * x * getSecondaryMovementMultiplier();
@ -696,28 +722,34 @@ namespace CSVRender
getCamera()->setViewMatrixAsLookAt(mCenter + offset, mCenter, up);
}
void OrbitCameraController::naviPrimary(bool active)
{
mNaviPrimary = active;
}
void OrbitCameraController::naviSecondary(bool active)
{
mNaviSecondary = active;
}
void OrbitCameraController::up(bool active)
{
if (isActive())
mUp = active;
mUp = active;
}
void OrbitCameraController::left(bool active)
{
if (isActive())
mLeft = active;
mLeft = active;
}
void OrbitCameraController::down(bool active)
{
if (isActive())
mDown = active;
mDown = active;
}
void OrbitCameraController::right(bool active)
{
if (isActive())
mRight = active;
mRight = active;
}
void OrbitCameraController::rollLeft(bool active)
@ -728,13 +760,11 @@ namespace CSVRender
void OrbitCameraController::rollRight(bool active)
{
if (isActive())
mRollRight = active;
mRollRight = active;
}
void OrbitCameraController::swapSpeedMode(bool active)
void OrbitCameraController::swapSpeedMode()
{
if (isActive() && active)
mFast = !mFast;
mFast = !mFast;
}
}

View file

@ -37,7 +37,7 @@ namespace CSVRender
static const osg::Vec3d LocalLeft;
static const osg::Vec3d LocalForward;
CameraController();
CameraController(QObject* parent);
virtual ~CameraController();
bool isActive() const;
@ -83,7 +83,7 @@ namespace CSVRender
public:
FreeCameraController(CSMPrefs::ShortcutEventHandler* handler);
FreeCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent=0);
double getLinearSpeed() const;
double getRotationalSpeed() const;
@ -112,6 +112,7 @@ namespace CSVRender
void stabilize();
bool mLockUpright, mModified;
bool mNaviPrimary, mNaviSecondary;
bool mFast, mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight;
osg::Vec3d mUp;
@ -121,13 +122,15 @@ namespace CSVRender
private slots:
void naviPrimary(bool active);
void naviSecondary(bool active);
void forward(bool active);
void left(bool active);
void backward(bool active);
void right(bool active);
void rollLeft(bool active);
void rollRight(bool active);
void swapSpeedMode(bool active);
void swapSpeedMode();
};
class OrbitCameraController : public CameraController
@ -136,7 +139,7 @@ namespace CSVRender
public:
OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler);
OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent=0);
osg::Vec3d getCenter() const;
double getOrbitSpeed() const;
@ -167,6 +170,7 @@ namespace CSVRender
void zoom(double value);
bool mInitialized;
bool mNaviPrimary, mNaviSecondary;
bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight;
unsigned int mPickingMask;
osg::Vec3d mCenter;
@ -177,13 +181,15 @@ namespace CSVRender
private slots:
void naviPrimary(bool active);
void naviSecondary(bool active);
void up(bool active);
void left(bool active);
void down(bool active);
void right(bool active);
void rollLeft(bool active);
void rollRight(bool active);
void swapSpeedMode(bool active);
void swapSpeedMode();
};
}

View file

@ -142,15 +142,14 @@ void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
"terrain-move");
}
void CSVRender::PagedWorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, const std::string& button,
void CSVRender::PagedWorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, InteractionType type,
bool shift)
{
if (hit.tag && hit.tag->getMask()==Mask_CellArrow)
{
if (button=="p-edit" || button=="s-edit")
if (type == InteractionType_PrimaryEdit || type == InteractionType_SecondaryEdit)
{
if (CellArrowTag *cellArrowTag =
dynamic_cast<CSVRender::CellArrowTag *> (hit.tag.get()))
if (CellArrowTag *cellArrowTag = dynamic_cast<CSVRender::CellArrowTag *> (hit.tag.get()))
{
CellArrow *arrow = cellArrowTag->getCellArrow();
@ -173,7 +172,7 @@ void CSVRender::PagedWorldspaceWidget::handleMouseClick (const WorldspaceHitResu
if (shift)
{
if (button=="p-edit")
if (type == InteractionType_PrimaryEdit)
addCellSelection (x, y);
else
moveCellSelection (x, y);
@ -191,7 +190,7 @@ void CSVRender::PagedWorldspaceWidget::handleMouseClick (const WorldspaceHitResu
modified = true;
}
if (button=="s-edit")
if (type == InteractionType_SecondaryEdit)
{
if (mCells.find (coordinates)!=mCells.end())
{
@ -210,7 +209,7 @@ void CSVRender::PagedWorldspaceWidget::handleMouseClick (const WorldspaceHitResu
}
}
WorldspaceWidget::handleMouseClick (hit, button, shift);
WorldspaceWidget::handleMouseClick (hit, type, shift);
}
void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,

View file

@ -138,7 +138,7 @@ namespace CSVRender
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);
virtual void handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, bool shift);
virtual void handleMouseClick (const WorldspaceHitResult& hit, InteractionType type, bool shift);
signals:

View file

@ -77,7 +77,7 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
mView->setSceneData(mRootNode);
// Press S to reveal profiling stats
// Add ability to signal osg to show its statistics for debugging purposes
mView->addEventHandler(new osgViewer::StatsHandler);
mView->getCamera()->setCullMask(~(Mask_UpdateVisitor));
@ -165,12 +165,11 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
mShortcutHandler = new CSMPrefs::ShortcutEventHandler(this);
installEventFilter(mShortcutHandler);
mFreeCamControl.reset(new FreeCameraController(mShortcutHandler));
mOrbitCamControl.reset(new OrbitCameraController(mShortcutHandler));
mCurrentCamControl = mFreeCamControl.get();
mFreeCamControl = new FreeCameraController(mShortcutHandler, this);
mOrbitCamControl = new OrbitCameraController(mShortcutHandler, this);
mCurrentCamControl = mFreeCamControl;
mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain);
selectNavigationMode("free");
// we handle lighting manually
mView->setLightingMode(osgViewer::View::NO_LIGHT);
@ -183,9 +182,9 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
setMouseTracking(true);
setFocusPolicy(Qt::ClickFocus);
/// \todo make shortcut configurable
//QShortcut *focusToolbar = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut);
//connect (focusToolbar, SIGNAL (activated()), this, SIGNAL (focusToolbarRequest()));
mFocusToolbarShortcut = new CSMPrefs::Shortcut("scene-focus-toolbar", this);
mShortcutHandler->addShortcut(mFocusToolbarShortcut);
connect(mFocusToolbarShortcut, SIGNAL(activated()), this, SIGNAL(focusToolbarRequest()));
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
@ -279,32 +278,14 @@ void SceneWidget::setDefaultAmbient (const osg::Vec4f& colour)
setAmbient(mLighting->getAmbientColour(&mDefaultAmbient));
}
void SceneWidget::mousePressEvent (QMouseEvent *event)
{
mMouseMode = mapButton(event);
mPrevMouseX = event->x();
mPrevMouseY = event->y();
}
void SceneWidget::mouseReleaseEvent (QMouseEvent *event)
{
mMouseMode = "";
}
void SceneWidget::mouseMoveEvent (QMouseEvent *event)
{
mCurrentCamControl->handleMouseMoveEvent(mMouseMode, event->x() - mPrevMouseX, event->y() - mPrevMouseY);
mCurrentCamControl->handleMouseMoveEvent("TODO", event->x() - mPrevMouseX, event->y() - mPrevMouseY);
mPrevMouseX = event->x();
mPrevMouseY = event->y();
}
void SceneWidget::focusOutEvent (QFocusEvent *event)
{
mCurrentCamControl->resetInput();
}
void SceneWidget::wheelEvent(QWheelEvent *event)
{
mCurrentCamControl->handleMouseMoveEvent("t-navi", event->delta(), 0);
@ -371,10 +352,6 @@ void SceneWidget::settingChanged (const CSMPrefs::Setting *setting)
{
mOrbitCamControl->setOrbitSpeedMultiplier(setting->toDouble());
}
else
{
storeMappingSetting(setting);
}
}
void SceneWidget::selectNavigationMode (const std::string& mode)
@ -382,73 +359,23 @@ void SceneWidget::selectNavigationMode (const std::string& mode)
if (mode=="1st")
{
mCurrentCamControl->setCamera(NULL);
mCurrentCamControl = mFreeCamControl.get();
mCurrentCamControl->setCamera(getCamera());
mCurrentCamControl = mFreeCamControl;
mFreeCamControl->setCamera(getCamera());
mFreeCamControl->fixUpAxis(CameraController::WorldUp);
}
else if (mode=="free")
{
mCurrentCamControl->setCamera(NULL);
mCurrentCamControl = mFreeCamControl.get();
mCurrentCamControl->setCamera(getCamera());
mCurrentCamControl = mFreeCamControl;
mFreeCamControl->setCamera(getCamera());
mFreeCamControl->unfixUpAxis();
}
else if (mode=="orbit")
{
mCurrentCamControl->setCamera(NULL);
mCurrentCamControl = mOrbitCamControl.get();
mCurrentCamControl->setCamera(getCamera());
mCurrentCamControl = mOrbitCamControl;
mOrbitCamControl->setCamera(getCamera());
}
}
bool SceneWidget::storeMappingSetting (const CSMPrefs::Setting *setting)
{
if (setting->getParent()->getKey()!="3D Scene Input")
return false;
static const char * const sMappingSettings[] =
{
"p-navi", "s-navi",
0
};
for (int i=0; sMappingSettings[i]; ++i)
if (setting->getKey()==sMappingSettings[i])
{
QString value = QString::fromUtf8 (setting->toString().c_str());
Qt::MouseButton button = Qt::NoButton;
if (value.endsWith ("Left Mouse-Button"))
button = Qt::LeftButton;
else if (value.endsWith ("Right Mouse-Button"))
button = Qt::RightButton;
else if (value.endsWith ("Middle Mouse-Button"))
button = Qt::MiddleButton;
else
return false;
bool ctrl = value.startsWith ("Ctrl-");
mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i];
return true;
}
return false;
}
std::string SceneWidget::mapButton (QMouseEvent *event)
{
std::pair<Qt::MouseButton, bool> phyiscal (
event->button(), event->modifiers() & Qt::ControlModifier);
std::map<std::pair<Qt::MouseButton, bool>, std::string>::const_iterator iter =
mButtonMapping.find (phyiscal);
if (iter!=mButtonMapping.end())
return iter->second;
return "";
}
}

View file

@ -56,6 +56,7 @@ namespace CSVRender
RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
virtual ~RenderWidget();
/// Initiates a request to redraw the view
void flagAsModified();
void setVisibilityMask(int mask);
@ -65,19 +66,21 @@ namespace CSVRender
protected:
osg::ref_ptr<osgViewer::View> mView;
osg::Group* mRootNode;
osg::ref_ptr<osg::Group> mRootNode;
QTimer mTimer;
};
// Extension of RenderWidget to support lighting mode selection & toolbar
/// Extension of RenderWidget to support lighting mode selection & toolbar
class SceneWidget : public RenderWidget
{
Q_OBJECT
public:
SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSystem, QWidget* parent = 0,
Qt::WindowFlags f = 0, bool retrieveInput = true);
virtual ~SceneWidget();
CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent);
@ -88,21 +91,14 @@ namespace CSVRender
///< \note The actual ambient colour may differ based on lighting settings.
protected:
void setLighting (Lighting *lighting);
///< \attention The ownership of \a lighting is not transferred to *this.
void setAmbient(const osg::Vec4f& ambient);
virtual void mousePressEvent (QMouseEvent *event);
virtual void mouseReleaseEvent (QMouseEvent *event);
virtual void mouseMoveEvent (QMouseEvent *event);
virtual void wheelEvent (QWheelEvent *event);
virtual void focusOutEvent (QFocusEvent *event);
/// \return Is \a key a button mapping setting? (ignored otherwise)
virtual bool storeMappingSetting (const CSMPrefs::Setting *setting);
std::string mapButton (QMouseEvent *event);
boost::shared_ptr<Resource::ResourceSystem> mResourceSystem;
@ -115,13 +111,13 @@ namespace CSVRender
LightingBright mLightingBright;
int mPrevMouseX, mPrevMouseY;
std::string mMouseMode;
std::auto_ptr<FreeCameraController> mFreeCamControl;
std::auto_ptr<OrbitCameraController> mOrbitCamControl;
FreeCameraController* mFreeCamControl;
OrbitCameraController* mOrbitCamControl;
CameraController* mCurrentCamControl;
std::map<std::pair<Qt::MouseButton, bool>, std::string> mButtonMapping;
CSMPrefs::ShortcutEventHandler *mShortcutHandler;
CSMPrefs::Shortcut* mFocusToolbarShortcut;
private:
bool mCamPositionSet;
@ -149,7 +145,9 @@ namespace CSVRender
class CompositeViewer : public QObject, public osgViewer::CompositeViewer
{
Q_OBJECT
public:
CompositeViewer();
static CompositeViewer& get();

View file

@ -16,6 +16,8 @@
#include "../../model/world/universalid.hpp"
#include "../../model/world/idtable.hpp"
#include "../../model/prefs/shortcut.hpp"
#include "../../model/prefs/shortcuteventhandler.hpp"
#include "../../model/prefs/state.hpp"
#include "../render/orbitcameramode.hpp"
@ -31,10 +33,23 @@
#include "cameracontroller.hpp"
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
: SceneWidget (document.getData().getResourceSystem(), parent, 0, false), mSceneElements(0), mRun(0), mDocument(document),
mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false), mDragX(0), mDragY(0), mDragFactor(0),
mDragWheelFactor(0), mDragShiftFactor(0),
mToolTipPos (-1, -1), mShowToolTips(false), mToolTipDelay(0)
: SceneWidget (document.getData().getResourceSystem(), parent, 0, false)
, mSceneElements(0)
, mRun(0)
, mDocument(document)
, mInteractionMask (0)
, mEditMode (0)
, mLocked (false)
, mDragMode(InteractionType_None)
, mDragging (false)
, mDragX(0)
, mDragY(0)
, mDragFactor(0)
, mDragWheelFactor(0)
, mDragShiftFactor(0)
, mToolTipPos (-1, -1)
, mShowToolTips(false)
, mToolTipDelay(0)
{
setAcceptDrops(true);
@ -80,6 +95,27 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg
CSMPrefs::get()["3D Scene Input"].update();
CSMPrefs::get()["Tooltips"].update();
// Shortcuts
mPrimaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-primary", this);
mShortcutHandler->addShortcut(mPrimaryEditShortcut);
connect(mPrimaryEditShortcut, SIGNAL(activated(bool)), this, SLOT(primaryEdit(bool)));
mSecondaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-secondary", this);
mShortcutHandler->addShortcut(mSecondaryEditShortcut);
connect(mSecondaryEditShortcut, SIGNAL(activated(bool)), this, SLOT(secondaryEdit(bool)));
mPrimarySelectShortcut = new CSMPrefs::Shortcut("scene-select-primary", this);
mShortcutHandler->addShortcut(mPrimarySelectShortcut);
connect(mPrimarySelectShortcut, SIGNAL(activated(bool)), this, SLOT(primarySelect(bool)));
mSecondarySelectShortcut = new CSMPrefs::Shortcut("scene-select-secondary", this);
mShortcutHandler->addShortcut(mSecondarySelectShortcut);
connect(mSecondarySelectShortcut, SIGNAL(activated(bool)), this, SLOT(secondarySelect(bool)));
mAbortShortcut = new CSMPrefs::Shortcut("scene-edit-abort", this);
mShortcutHandler->addShortcut(mAbortShortcut);
connect(mSecondaryEditShortcut, SIGNAL(activated()), this, SLOT(abortDrag()));
}
CSVRender::WorldspaceWidget::~WorldspaceWidget ()
@ -409,7 +445,7 @@ void CSVRender::WorldspaceWidget::abortDrag()
editMode.dragAborted();
mDragging = false;
mDragMode.clear();
mDragMode = InteractionType_None;
}
}
@ -453,45 +489,6 @@ void CSVRender::WorldspaceWidget::dragMoveEvent(QDragMoveEvent *event)
}
}
bool CSVRender::WorldspaceWidget::storeMappingSetting (const CSMPrefs::Setting *setting)
{
static const char * const sMappingSettings[] =
{
"p-edit", "s-edit",
"p-select", "s-select",
0
};
if (setting->getParent()->getKey()=="3D Scene Input")
{
for (int i=0; sMappingSettings[i]; ++i)
{
if (setting->getKey()==sMappingSettings[i])
{
QString value = QString::fromUtf8 (setting->toString().c_str());
Qt::MouseButton button = Qt::NoButton;
if (value.endsWith ("Left Mouse-Button"))
button = Qt::LeftButton;
else if (value.endsWith ("Right Mouse-Button"))
button = Qt::RightButton;
else if (value.endsWith ("Middle Mouse-Button"))
button = Qt::MiddleButton;
else
return false;
bool ctrl = value.startsWith ("Ctrl-");
mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i];
return true;
}
}
}
return SceneWidget::storeMappingSetting(setting);
}
void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event)
{
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
@ -567,7 +564,7 @@ void CSVRender::WorldspaceWidget::editModeChanged (const std::string& id)
{
dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).setEditLock (mLocked);
mDragging = false;
mDragMode.clear();
mDragMode = InteractionType_None;
}
void CSVRender::WorldspaceWidget::showToolTip()
@ -615,17 +612,17 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
editMode.drag (event->pos(), diffX, diffY, factor);
}
else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="p-select" || mDragMode=="s-select")
else if (mDragMode != InteractionType_None)
{
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
if (mDragMode=="p-edit")
if (mDragMode == InteractionType_PrimaryEdit)
mDragging = editMode.primaryEditStartDrag (event->pos());
else if (mDragMode=="s-edit")
else if (mDragMode == InteractionType_SecondaryEdit)
mDragging = editMode.secondaryEditStartDrag (event->pos());
else if (mDragMode=="p-select")
else if (mDragMode == InteractionType_PrimarySelect)
mDragging = editMode.primarySelectStartDrag (event->pos());
else if (mDragMode=="s-select")
else if (mDragMode == InteractionType_SecondarySelect)
mDragging = editMode.secondarySelectStartDrag (event->pos());
if (mDragging)
@ -656,46 +653,6 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
}
}
void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event)
{
std::string button = mapButton (event);
if (button=="p-edit" || button=="s-edit" ||
button=="p-select" || button=="s-select")
{
if (!mDragging)
mDragMode = button;
}
else
SceneWidget::mousePressEvent(event);
}
void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event)
{
std::string button = mapButton (event);
mDragMode.clear();
if (button=="p-edit" || button=="s-edit" ||
button=="p-select" || button=="s-select")
{
if (mDragging)
{
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
editMode.dragCompleted(event->pos());
mDragging = false;
}
else
{
WorldspaceHitResult hit = mousePick(event->pos(), getInteractionMask());
handleMouseClick (hit, button, event->modifiers() & Qt::ShiftModifier);
}
}
else
SceneWidget::mouseReleaseEvent(event);
}
void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
{
if (mDragging)
@ -713,27 +670,17 @@ void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
SceneWidget::wheelEvent(event);
}
void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
{
if(event->key() == Qt::Key_Escape)
{
abortDrag();
}
else
SceneWidget::keyPressEvent(event);
}
void CSVRender::WorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, bool shift)
void CSVRender::WorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, InteractionType type, bool shift)
{
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
if (button=="p-edit")
if (type == InteractionType_PrimaryEdit)
editMode.primaryEditPressed (hit);
else if (button=="s-edit")
else if (type == InteractionType_SecondaryEdit)
editMode.secondaryEditPressed (hit);
else if (button=="p-select")
else if (type == InteractionType_PrimarySelect)
editMode.primarySelectPressed (hit);
else if (button=="s-select")
else if (type == InteractionType_SecondarySelect)
editMode.secondarySelectPressed (hit);
}
@ -741,3 +688,48 @@ CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
{
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
}
void CSVRender::WorldspaceWidget::primaryEdit(bool activate)
{
handleInteraction(InteractionType_PrimaryEdit, activate);
}
void CSVRender::WorldspaceWidget::secondaryEdit(bool activate)
{
handleInteraction(InteractionType_SecondaryEdit, activate);
}
void CSVRender::WorldspaceWidget::primarySelect(bool activate)
{
handleInteraction(InteractionType_PrimarySelect, activate);
}
void CSVRender::WorldspaceWidget::secondarySelect(bool activate)
{
handleInteraction(InteractionType_SecondarySelect, activate);
}
void CSVRender::WorldspaceWidget::handleInteraction(InteractionType type, bool activate)
{
if (activate)
{
if (!mDragging)
mDragMode = type;
}
else
{
mDragMode = InteractionType_None;
if (mDragging)
{
EditMode* editMode = getEditMode();
editMode->dragCompleted(mapFromGlobal(QCursor::pos()));
mDragging = false;
}
else
{
WorldspaceHitResult hit = mousePick(mapFromGlobal(QCursor::pos()), getInteractionMask());
handleMouseClick(hit, type, false);
}
}
}

View file

@ -15,6 +15,7 @@
namespace CSMPrefs
{
class Setting;
class Shortcut;
}
namespace CSMWorld
@ -55,7 +56,7 @@ namespace CSVRender
unsigned int mInteractionMask;
CSVWidget::SceneToolMode *mEditMode;
bool mLocked;
std::string mDragMode;
int mDragMode;
bool mDragging;
int mDragX;
int mDragY;
@ -67,6 +68,12 @@ namespace CSVRender
bool mShowToolTips;
int mToolTipDelay;
CSMPrefs::Shortcut* mPrimaryEditShortcut;
CSMPrefs::Shortcut* mSecondaryEditShortcut;
CSMPrefs::Shortcut* mPrimarySelectShortcut;
CSMPrefs::Shortcut* mSecondarySelectShortcut;
CSMPrefs::Shortcut* mAbortShortcut;
public:
enum DropType
@ -85,6 +92,15 @@ namespace CSVRender
ignored //either mixed cells, or not cells
};
enum InteractionType
{
InteractionType_PrimaryEdit,
InteractionType_PrimarySelect,
InteractionType_SecondaryEdit,
InteractionType_SecondarySelect,
InteractionType_None
};
WorldspaceWidget (CSMDoc::Document& document, QWidget *parent = 0);
~WorldspaceWidget ();
@ -171,12 +187,6 @@ namespace CSVRender
/// Erase all overrides and restore the visual representation to its true state.
virtual void reset (unsigned int elementMask) = 0;
/// \note Drags will be automatically aborted when the aborting is triggered
/// (either explicitly or implicitly) from within this class. This function only
/// needs to be called, when the drag abort is triggered externally (e.g. from
/// an edit mode).
void abortDrag();
protected:
/// Visual elements in a scene
@ -197,16 +207,9 @@ namespace CSVRender
virtual void updateOverlay();
virtual void mouseMoveEvent (QMouseEvent *event);
virtual void mousePressEvent (QMouseEvent *event);
virtual void mouseReleaseEvent (QMouseEvent *event);
virtual void wheelEvent (QWheelEvent *event);
virtual void keyPressEvent (QKeyEvent *event);
virtual void handleMouseClick (const WorldspaceHitResult& hit, const std::string& button,
bool shift);
/// \return Is \a key a button mapping setting? (ignored otherwise)
virtual bool storeMappingSetting (const CSMPrefs::Setting *setting);
virtual void handleMouseClick (const WorldspaceHitResult& hit, InteractionType type, bool shift);
virtual void settingChanged (const CSMPrefs::Setting *setting);
@ -222,6 +225,16 @@ namespace CSVRender
virtual std::string getStartupInstruction() = 0;
void handleInteraction(InteractionType type, bool activate);
public slots:
/// \note Drags will be automatically aborted when the aborting is triggered
/// (either explicitly or implicitly) from within this class. This function only
/// needs to be called, when the drag abort is triggered externally (e.g. from
/// an edit mode).
void abortDrag();
private slots:
virtual void referenceableDataChanged (const QModelIndex& topLeft,
@ -255,6 +268,14 @@ namespace CSVRender
void showToolTip();
void primaryEdit(bool activate);
void secondaryEdit(bool activate);
void primarySelect(bool activate);
void secondarySelect(bool activate);
protected slots:
void elementSelectionChanged();