1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-03 17:19:39 +00:00

- 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; Shortcut* shortcut = *it;
if (shortcut->isActive()) if (shortcut->isActive())
{
shortcut->activate(false); 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-left", "Free camera roll left", QKeySequence(Qt::Key_Q));
declareShortcut ("free-roll-right", "Free camera roll right", QKeySequence(Qt::Key_E)); 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)); declareShortcut ("free-speed-mode", "Free camera speed mode toggle", QKeySequence(Qt::Key_F));
declareSeparator (); declareSeparator ();
declareShortcut ("orbit-up", "Orbit camera up", QKeySequence(Qt::Key_W)); declareShortcut ("orbit-up", "Orbit camera up", QKeySequence(Qt::Key_W));
declareShortcut ("orbit-down", "Orbit camera down", QKeySequence(Qt::Key_S)); 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-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-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)); 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) 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::LocalLeft = osg::Vec3d(1, 0, 0);
const osg::Vec3d CameraController::LocalForward = osg::Vec3d(0, 0, 1); const osg::Vec3d CameraController::LocalForward = osg::Vec3d(0, 0, 1);
CameraController::CameraController() CameraController::CameraController(QObject* parent)
: mActive(false) : QObject(parent)
, mActive(false)
, mInverted(false) , mInverted(false)
, mCameraSensitivity(1/650.f) , mCameraSensitivity(1/650.f)
, mSecondaryMoveMult(50) , mSecondaryMoveMult(50)
@ -163,8 +164,9 @@ namespace CSVRender
Free Camera Controller Free Camera Controller
*/ */
FreeCameraController::FreeCameraController(CSMPrefs::ShortcutEventHandler* handler) FreeCameraController::FreeCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent)
: mLockUpright(false) : CameraController(parent)
, mLockUpright(false)
, mModified(false) , mModified(false)
, mFast(false) , mFast(false)
, mLeft(false) , mLeft(false)
@ -178,6 +180,16 @@ namespace CSVRender
, mRotSpeed(osg::PI / 2) , mRotSpeed(osg::PI / 2)
, mSpeedMult(8) , 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); CSMPrefs::Shortcut* forwardShortcut = new CSMPrefs::Shortcut("free-forward", this);
forwardShortcut->enable(false); forwardShortcut->enable(false);
handler->addShortcut(forwardShortcut); handler->addShortcut(forwardShortcut);
@ -211,7 +223,7 @@ namespace CSVRender
CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("free-speed-mode", this); CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("free-speed-mode", this);
speedModeShortcut->enable(false); speedModeShortcut->enable(false);
handler->addShortcut(speedModeShortcut); handler->addShortcut(speedModeShortcut);
connect(speedModeShortcut, SIGNAL(activated(bool)), this, SLOT(swapSpeedMode(bool))); connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
} }
double FreeCameraController::getLinearSpeed() const double FreeCameraController::getLinearSpeed() const
@ -261,13 +273,13 @@ namespace CSVRender
if (!isActive()) if (!isActive())
return false; return false;
if (mode == "p-navi") if (mNaviPrimary)
{ {
double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0); double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0);
yaw(x * scalar); yaw(x * scalar);
pitch(y * scalar); pitch(y * scalar);
} }
else if (mode == "s-navi") else if (mNaviSecondary)
{ {
osg::Vec3d movement; osg::Vec3d movement;
movement += LocalLeft * -x * getSecondaryMovementMultiplier(); movement += LocalLeft * -x * getSecondaryMovementMultiplier();
@ -384,54 +396,58 @@ namespace CSVRender
getCamera()->setViewMatrixAsLookAt(eye, center, mUp); getCamera()->setViewMatrixAsLookAt(eye, center, mUp);
} }
void FreeCameraController::naviPrimary(bool active)
{
mNaviPrimary = active;
}
void FreeCameraController::naviSecondary(bool active)
{
mNaviSecondary = active;
}
void FreeCameraController::forward(bool active) void FreeCameraController::forward(bool active)
{ {
if (isActive()) mForward = active;
mForward = active;
} }
void FreeCameraController::left(bool active) void FreeCameraController::left(bool active)
{ {
if (isActive()) mLeft = active;
mLeft = active;
} }
void FreeCameraController::backward(bool active) void FreeCameraController::backward(bool active)
{ {
if (isActive()) mBackward = active;
mBackward = active;
} }
void FreeCameraController::right(bool active) void FreeCameraController::right(bool active)
{ {
if (isActive()) mRight = active;
mRight = active;
} }
void FreeCameraController::rollLeft(bool active) void FreeCameraController::rollLeft(bool active)
{ {
if (isActive()) mRollLeft = active;
mRollLeft = active;
} }
void FreeCameraController::rollRight(bool 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 Orbit Camera Controller
*/ */
OrbitCameraController::OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler) OrbitCameraController::OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent)
: mInitialized(false) : CameraController(parent)
, mInitialized(false)
, mFast(false) , mFast(false)
, mLeft(false) , mLeft(false)
, mRight(false) , mRight(false)
@ -445,6 +461,16 @@ namespace CSVRender
, mOrbitSpeed(osg::PI / 4) , mOrbitSpeed(osg::PI / 4)
, mOrbitSpeedMult(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); CSMPrefs::Shortcut* upShortcut = new CSMPrefs::Shortcut("orbit-up", this);
upShortcut->enable(false); upShortcut->enable(false);
handler->addShortcut(upShortcut); handler->addShortcut(upShortcut);
@ -478,7 +504,7 @@ namespace CSVRender
CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("orbit-speed-mode", this); CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("orbit-speed-mode", this);
speedModeShortcut->enable(false); speedModeShortcut->enable(false);
handler->addShortcut(speedModeShortcut); handler->addShortcut(speedModeShortcut);
connect(speedModeShortcut, SIGNAL(activated(bool)), this, SLOT(swapSpeedMode(bool))); connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
} }
osg::Vec3d OrbitCameraController::getCenter() const osg::Vec3d OrbitCameraController::getCenter() const
@ -537,13 +563,13 @@ namespace CSVRender
if (!mInitialized) if (!mInitialized)
initialize(); initialize();
if (mode == "p-navi") if (mNaviPrimary)
{ {
double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0); double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0);
rotateHorizontal(x * scalar); rotateHorizontal(x * scalar);
rotateVertical(-y * scalar); rotateVertical(-y * scalar);
} }
else if (mode == "s-navi") else if (mNaviSecondary)
{ {
osg::Vec3d movement; osg::Vec3d movement;
movement += LocalLeft * x * getSecondaryMovementMultiplier(); movement += LocalLeft * x * getSecondaryMovementMultiplier();
@ -696,28 +722,34 @@ namespace CSVRender
getCamera()->setViewMatrixAsLookAt(mCenter + offset, mCenter, up); 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) void OrbitCameraController::up(bool active)
{ {
if (isActive()) mUp = active;
mUp = active;
} }
void OrbitCameraController::left(bool active) void OrbitCameraController::left(bool active)
{ {
if (isActive()) mLeft = active;
mLeft = active;
} }
void OrbitCameraController::down(bool active) void OrbitCameraController::down(bool active)
{ {
if (isActive()) mDown = active;
mDown = active;
} }
void OrbitCameraController::right(bool active) void OrbitCameraController::right(bool active)
{ {
if (isActive()) mRight = active;
mRight = active;
} }
void OrbitCameraController::rollLeft(bool active) void OrbitCameraController::rollLeft(bool active)
@ -728,13 +760,11 @@ namespace CSVRender
void OrbitCameraController::rollRight(bool active) 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 LocalLeft;
static const osg::Vec3d LocalForward; static const osg::Vec3d LocalForward;
CameraController(); CameraController(QObject* parent);
virtual ~CameraController(); virtual ~CameraController();
bool isActive() const; bool isActive() const;
@ -83,7 +83,7 @@ namespace CSVRender
public: public:
FreeCameraController(CSMPrefs::ShortcutEventHandler* handler); FreeCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent=0);
double getLinearSpeed() const; double getLinearSpeed() const;
double getRotationalSpeed() const; double getRotationalSpeed() const;
@ -112,6 +112,7 @@ namespace CSVRender
void stabilize(); void stabilize();
bool mLockUpright, mModified; bool mLockUpright, mModified;
bool mNaviPrimary, mNaviSecondary;
bool mFast, mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight; bool mFast, mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight;
osg::Vec3d mUp; osg::Vec3d mUp;
@ -121,13 +122,15 @@ namespace CSVRender
private slots: private slots:
void naviPrimary(bool active);
void naviSecondary(bool active);
void forward(bool active); void forward(bool active);
void left(bool active); void left(bool active);
void backward(bool active); void backward(bool active);
void right(bool active); void right(bool active);
void rollLeft(bool active); void rollLeft(bool active);
void rollRight(bool active); void rollRight(bool active);
void swapSpeedMode(bool active); void swapSpeedMode();
}; };
class OrbitCameraController : public CameraController class OrbitCameraController : public CameraController
@ -136,7 +139,7 @@ namespace CSVRender
public: public:
OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler); OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent=0);
osg::Vec3d getCenter() const; osg::Vec3d getCenter() const;
double getOrbitSpeed() const; double getOrbitSpeed() const;
@ -167,6 +170,7 @@ namespace CSVRender
void zoom(double value); void zoom(double value);
bool mInitialized; bool mInitialized;
bool mNaviPrimary, mNaviSecondary;
bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight; bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight;
unsigned int mPickingMask; unsigned int mPickingMask;
osg::Vec3d mCenter; osg::Vec3d mCenter;
@ -177,13 +181,15 @@ namespace CSVRender
private slots: private slots:
void naviPrimary(bool active);
void naviSecondary(bool active);
void up(bool active); void up(bool active);
void left(bool active); void left(bool active);
void down(bool active); void down(bool active);
void right(bool active); void right(bool active);
void rollLeft(bool active); void rollLeft(bool active);
void rollRight(bool active); void rollRight(bool active);
void swapSpeedMode(bool active); void swapSpeedMode();
}; };
} }

View file

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

View file

@ -138,7 +138,7 @@ namespace CSVRender
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool); 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: signals:

View file

@ -77,7 +77,7 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
mView->setSceneData(mRootNode); 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->addEventHandler(new osgViewer::StatsHandler);
mView->getCamera()->setCullMask(~(Mask_UpdateVisitor)); mView->getCamera()->setCullMask(~(Mask_UpdateVisitor));
@ -165,12 +165,11 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
mShortcutHandler = new CSMPrefs::ShortcutEventHandler(this); mShortcutHandler = new CSMPrefs::ShortcutEventHandler(this);
installEventFilter(mShortcutHandler); installEventFilter(mShortcutHandler);
mFreeCamControl.reset(new FreeCameraController(mShortcutHandler)); mFreeCamControl = new FreeCameraController(mShortcutHandler, this);
mOrbitCamControl.reset(new OrbitCameraController(mShortcutHandler)); mOrbitCamControl = new OrbitCameraController(mShortcutHandler, this);
mCurrentCamControl = mFreeCamControl.get(); mCurrentCamControl = mFreeCamControl;
mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain); mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain);
selectNavigationMode("free");
// we handle lighting manually // we handle lighting manually
mView->setLightingMode(osgViewer::View::NO_LIGHT); mView->setLightingMode(osgViewer::View::NO_LIGHT);
@ -183,9 +182,9 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
setMouseTracking(true); setMouseTracking(true);
setFocusPolicy(Qt::ClickFocus); setFocusPolicy(Qt::ClickFocus);
/// \todo make shortcut configurable mFocusToolbarShortcut = new CSMPrefs::Shortcut("scene-focus-toolbar", this);
//QShortcut *focusToolbar = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut); mShortcutHandler->addShortcut(mFocusToolbarShortcut);
//connect (focusToolbar, SIGNAL (activated()), this, SIGNAL (focusToolbarRequest())); connect(mFocusToolbarShortcut, SIGNAL(activated()), this, SIGNAL(focusToolbarRequest()));
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)), connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
this, SLOT (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)); 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) 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(); mPrevMouseX = event->x();
mPrevMouseY = event->y(); mPrevMouseY = event->y();
} }
void SceneWidget::focusOutEvent (QFocusEvent *event)
{
mCurrentCamControl->resetInput();
}
void SceneWidget::wheelEvent(QWheelEvent *event) void SceneWidget::wheelEvent(QWheelEvent *event)
{ {
mCurrentCamControl->handleMouseMoveEvent("t-navi", event->delta(), 0); mCurrentCamControl->handleMouseMoveEvent("t-navi", event->delta(), 0);
@ -371,10 +352,6 @@ void SceneWidget::settingChanged (const CSMPrefs::Setting *setting)
{ {
mOrbitCamControl->setOrbitSpeedMultiplier(setting->toDouble()); mOrbitCamControl->setOrbitSpeedMultiplier(setting->toDouble());
} }
else
{
storeMappingSetting(setting);
}
} }
void SceneWidget::selectNavigationMode (const std::string& mode) void SceneWidget::selectNavigationMode (const std::string& mode)
@ -382,73 +359,23 @@ void SceneWidget::selectNavigationMode (const std::string& mode)
if (mode=="1st") if (mode=="1st")
{ {
mCurrentCamControl->setCamera(NULL); mCurrentCamControl->setCamera(NULL);
mCurrentCamControl = mFreeCamControl.get(); mCurrentCamControl = mFreeCamControl;
mCurrentCamControl->setCamera(getCamera()); mFreeCamControl->setCamera(getCamera());
mFreeCamControl->fixUpAxis(CameraController::WorldUp); mFreeCamControl->fixUpAxis(CameraController::WorldUp);
} }
else if (mode=="free") else if (mode=="free")
{ {
mCurrentCamControl->setCamera(NULL); mCurrentCamControl->setCamera(NULL);
mCurrentCamControl = mFreeCamControl.get(); mCurrentCamControl = mFreeCamControl;
mCurrentCamControl->setCamera(getCamera()); mFreeCamControl->setCamera(getCamera());
mFreeCamControl->unfixUpAxis(); mFreeCamControl->unfixUpAxis();
} }
else if (mode=="orbit") else if (mode=="orbit")
{ {
mCurrentCamControl->setCamera(NULL); mCurrentCamControl->setCamera(NULL);
mCurrentCamControl = mOrbitCamControl.get(); mCurrentCamControl = mOrbitCamControl;
mCurrentCamControl->setCamera(getCamera()); 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); RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
virtual ~RenderWidget(); virtual ~RenderWidget();
/// Initiates a request to redraw the view
void flagAsModified(); void flagAsModified();
void setVisibilityMask(int mask); void setVisibilityMask(int mask);
@ -65,19 +66,21 @@ namespace CSVRender
protected: protected:
osg::ref_ptr<osgViewer::View> mView; osg::ref_ptr<osgViewer::View> mView;
osg::ref_ptr<osg::Group> mRootNode;
osg::Group* mRootNode;
QTimer mTimer; QTimer mTimer;
}; };
// Extension of RenderWidget to support lighting mode selection & toolbar /// Extension of RenderWidget to support lighting mode selection & toolbar
class SceneWidget : public RenderWidget class SceneWidget : public RenderWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSystem, QWidget* parent = 0, SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSystem, QWidget* parent = 0,
Qt::WindowFlags f = 0, bool retrieveInput = true); Qt::WindowFlags f = 0, bool retrieveInput = true);
virtual ~SceneWidget(); virtual ~SceneWidget();
CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent); CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent);
@ -88,21 +91,14 @@ namespace CSVRender
///< \note The actual ambient colour may differ based on lighting settings. ///< \note The actual ambient colour may differ based on lighting settings.
protected: protected:
void setLighting (Lighting *lighting); void setLighting (Lighting *lighting);
///< \attention The ownership of \a lighting is not transferred to *this. ///< \attention The ownership of \a lighting is not transferred to *this.
void setAmbient(const osg::Vec4f& ambient); void setAmbient(const osg::Vec4f& ambient);
virtual void mousePressEvent (QMouseEvent *event);
virtual void mouseReleaseEvent (QMouseEvent *event);
virtual void mouseMoveEvent (QMouseEvent *event); virtual void mouseMoveEvent (QMouseEvent *event);
virtual void wheelEvent (QWheelEvent *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; boost::shared_ptr<Resource::ResourceSystem> mResourceSystem;
@ -115,13 +111,13 @@ namespace CSVRender
LightingBright mLightingBright; LightingBright mLightingBright;
int mPrevMouseX, mPrevMouseY; int mPrevMouseX, mPrevMouseY;
std::string mMouseMode;
std::auto_ptr<FreeCameraController> mFreeCamControl; FreeCameraController* mFreeCamControl;
std::auto_ptr<OrbitCameraController> mOrbitCamControl; OrbitCameraController* mOrbitCamControl;
CameraController* mCurrentCamControl; CameraController* mCurrentCamControl;
std::map<std::pair<Qt::MouseButton, bool>, std::string> mButtonMapping;
CSMPrefs::ShortcutEventHandler *mShortcutHandler; CSMPrefs::ShortcutEventHandler *mShortcutHandler;
CSMPrefs::Shortcut* mFocusToolbarShortcut;
private: private:
bool mCamPositionSet; bool mCamPositionSet;
@ -149,7 +145,9 @@ namespace CSVRender
class CompositeViewer : public QObject, public osgViewer::CompositeViewer class CompositeViewer : public QObject, public osgViewer::CompositeViewer
{ {
Q_OBJECT Q_OBJECT
public: public:
CompositeViewer(); CompositeViewer();
static CompositeViewer& get(); static CompositeViewer& get();

View file

@ -16,6 +16,8 @@
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/prefs/shortcut.hpp"
#include "../../model/prefs/shortcuteventhandler.hpp"
#include "../../model/prefs/state.hpp" #include "../../model/prefs/state.hpp"
#include "../render/orbitcameramode.hpp" #include "../render/orbitcameramode.hpp"
@ -31,10 +33,23 @@
#include "cameracontroller.hpp" #include "cameracontroller.hpp"
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
: SceneWidget (document.getData().getResourceSystem(), parent, 0, false), mSceneElements(0), mRun(0), mDocument(document), : SceneWidget (document.getData().getResourceSystem(), parent, 0, false)
mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false), mDragX(0), mDragY(0), mDragFactor(0), , mSceneElements(0)
mDragWheelFactor(0), mDragShiftFactor(0), , mRun(0)
mToolTipPos (-1, -1), mShowToolTips(false), mToolTipDelay(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); setAcceptDrops(true);
@ -80,6 +95,27 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg
CSMPrefs::get()["3D Scene Input"].update(); CSMPrefs::get()["3D Scene Input"].update();
CSMPrefs::get()["Tooltips"].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 () CSVRender::WorldspaceWidget::~WorldspaceWidget ()
@ -409,7 +445,7 @@ void CSVRender::WorldspaceWidget::abortDrag()
editMode.dragAborted(); editMode.dragAborted();
mDragging = false; 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) void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event)
{ {
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData()); 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); dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).setEditLock (mLocked);
mDragging = false; mDragging = false;
mDragMode.clear(); mDragMode = InteractionType_None;
} }
void CSVRender::WorldspaceWidget::showToolTip() void CSVRender::WorldspaceWidget::showToolTip()
@ -615,17 +612,17 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
editMode.drag (event->pos(), diffX, diffY, factor); 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()); EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
if (mDragMode=="p-edit") if (mDragMode == InteractionType_PrimaryEdit)
mDragging = editMode.primaryEditStartDrag (event->pos()); mDragging = editMode.primaryEditStartDrag (event->pos());
else if (mDragMode=="s-edit") else if (mDragMode == InteractionType_SecondaryEdit)
mDragging = editMode.secondaryEditStartDrag (event->pos()); mDragging = editMode.secondaryEditStartDrag (event->pos());
else if (mDragMode=="p-select") else if (mDragMode == InteractionType_PrimarySelect)
mDragging = editMode.primarySelectStartDrag (event->pos()); mDragging = editMode.primarySelectStartDrag (event->pos());
else if (mDragMode=="s-select") else if (mDragMode == InteractionType_SecondarySelect)
mDragging = editMode.secondarySelectStartDrag (event->pos()); mDragging = editMode.secondarySelectStartDrag (event->pos());
if (mDragging) 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) void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
{ {
if (mDragging) if (mDragging)
@ -713,27 +670,17 @@ void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
SceneWidget::wheelEvent(event); SceneWidget::wheelEvent(event);
} }
void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event) void CSVRender::WorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, InteractionType type, bool shift)
{
if(event->key() == Qt::Key_Escape)
{
abortDrag();
}
else
SceneWidget::keyPressEvent(event);
}
void CSVRender::WorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, bool shift)
{ {
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()); EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
if (button=="p-edit") if (type == InteractionType_PrimaryEdit)
editMode.primaryEditPressed (hit); editMode.primaryEditPressed (hit);
else if (button=="s-edit") else if (type == InteractionType_SecondaryEdit)
editMode.secondaryEditPressed (hit); editMode.secondaryEditPressed (hit);
else if (button=="p-select") else if (type == InteractionType_PrimarySelect)
editMode.primarySelectPressed (hit); editMode.primarySelectPressed (hit);
else if (button=="s-select") else if (type == InteractionType_SecondarySelect)
editMode.secondarySelectPressed (hit); editMode.secondarySelectPressed (hit);
} }
@ -741,3 +688,48 @@ CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
{ {
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent()); 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 namespace CSMPrefs
{ {
class Setting; class Setting;
class Shortcut;
} }
namespace CSMWorld namespace CSMWorld
@ -55,7 +56,7 @@ namespace CSVRender
unsigned int mInteractionMask; unsigned int mInteractionMask;
CSVWidget::SceneToolMode *mEditMode; CSVWidget::SceneToolMode *mEditMode;
bool mLocked; bool mLocked;
std::string mDragMode; int mDragMode;
bool mDragging; bool mDragging;
int mDragX; int mDragX;
int mDragY; int mDragY;
@ -67,6 +68,12 @@ namespace CSVRender
bool mShowToolTips; bool mShowToolTips;
int mToolTipDelay; int mToolTipDelay;
CSMPrefs::Shortcut* mPrimaryEditShortcut;
CSMPrefs::Shortcut* mSecondaryEditShortcut;
CSMPrefs::Shortcut* mPrimarySelectShortcut;
CSMPrefs::Shortcut* mSecondarySelectShortcut;
CSMPrefs::Shortcut* mAbortShortcut;
public: public:
enum DropType enum DropType
@ -85,6 +92,15 @@ namespace CSVRender
ignored //either mixed cells, or not cells 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 (CSMDoc::Document& document, QWidget *parent = 0);
~WorldspaceWidget (); ~WorldspaceWidget ();
@ -171,12 +187,6 @@ namespace CSVRender
/// Erase all overrides and restore the visual representation to its true state. /// Erase all overrides and restore the visual representation to its true state.
virtual void reset (unsigned int elementMask) = 0; 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: protected:
/// Visual elements in a scene /// Visual elements in a scene
@ -197,16 +207,9 @@ namespace CSVRender
virtual void updateOverlay(); virtual void updateOverlay();
virtual void mouseMoveEvent (QMouseEvent *event); virtual void mouseMoveEvent (QMouseEvent *event);
virtual void mousePressEvent (QMouseEvent *event);
virtual void mouseReleaseEvent (QMouseEvent *event);
virtual void wheelEvent (QWheelEvent *event); virtual void wheelEvent (QWheelEvent *event);
virtual void keyPressEvent (QKeyEvent *event);
virtual void handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, virtual void handleMouseClick (const WorldspaceHitResult& hit, InteractionType type, bool shift);
bool shift);
/// \return Is \a key a button mapping setting? (ignored otherwise)
virtual bool storeMappingSetting (const CSMPrefs::Setting *setting);
virtual void settingChanged (const CSMPrefs::Setting *setting); virtual void settingChanged (const CSMPrefs::Setting *setting);
@ -222,6 +225,16 @@ namespace CSVRender
virtual std::string getStartupInstruction() = 0; 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: private slots:
virtual void referenceableDataChanged (const QModelIndex& topLeft, virtual void referenceableDataChanged (const QModelIndex& topLeft,
@ -255,6 +268,14 @@ namespace CSVRender
void showToolTip(); void showToolTip();
void primaryEdit(bool activate);
void secondaryEdit(bool activate);
void primarySelect(bool activate);
void secondarySelect(bool activate);
protected slots: protected slots:
void elementSelectionChanged(); void elementSelectionChanged();