Changes in shortcut design.

- Handle input in centralized class for potential conflict resolution.
- Remove wrapper class for QShortcut; it should be unnecessary.
- Added customizable shortcut usage to orbit camera mode.
pull/29/head
Aesylwinn 9 years ago
parent 3fa4fdb839
commit e8626e588a

@ -113,7 +113,7 @@ opencs_units (view/prefs
opencs_units (model/prefs
state setting intsetting doublesetting boolsetting enumsetting coloursetting shortcut
shortcutmanager shortcutsetting
shortcuteventhandler shortcutmanager shortcutsetting
)
opencs_units_noqt (model/prefs

@ -14,6 +14,8 @@ namespace CSMPrefs
, mName(name)
, mCurrentPos(0)
, mLastPos(0)
, mActive(false)
, mEnabled(true)
{
State::get().getShortcutManager().addShortcut(this);
setSequence(State::get().getShortcutManager().getSequence(name));
@ -24,116 +26,64 @@ namespace CSMPrefs
State::get().getShortcutManager().removeShortcut(this);
}
const std::string& Shortcut::getName() const
bool Shortcut::isActive() const
{
return mName;
return mActive;
}
const QKeySequence& Shortcut::getSequence() const
bool Shortcut::isEnabled() const
{
return mSequence;
return mEnabled;
}
void Shortcut::setSequence(const QKeySequence& sequence)
const std::string& Shortcut::getName() const
{
mSequence = sequence;
mCurrentPos = 0;
mLastPos = sequence.count() - 1;
return mName;
}
void Shortcut::keyPressEvent(QKeyEvent* event)
const QKeySequence& Shortcut::getSequence() const
{
int withMod = event->key() | event->modifiers();
int noMod = event->key();
if (withMod == mSequence[mCurrentPos] || (mCurrentPos > 0 && noMod == mSequence[mCurrentPos]))
{
if (mCurrentPos == mLastPos)
{
activated(true);
}
else
++mCurrentPos;
}
return mSequence;
}
void Shortcut::keyReleaseEvent(QKeyEvent* event)
int Shortcut::getPosition() const
{
const int KeyMask = 0x01FFFFFF;
if ((mSequence[mCurrentPos] & KeyMask) == event->key())
{
if (mCurrentPos == mLastPos)
{
activated(false);
mCurrentPos = 0; // Resets to start, maybe shouldn't?
}
else if (mCurrentPos > 0)
{
--mCurrentPos;
}
}
return mCurrentPos;
}
void Shortcut::mousePressEvent(QMouseEvent* event)
int Shortcut::getLastPosition() const
{
int withMod = event->button() | (int)event->modifiers();
int noMod = event->button();
if (withMod == mSequence[mCurrentPos] || (mCurrentPos > 0 && noMod == mSequence[mCurrentPos]))
{
if (mCurrentPos == mLastPos)
activated(true);
else
++mCurrentPos;
}
return mLastPos;
}
void Shortcut::mouseReleaseEvent(QMouseEvent* event)
void Shortcut::setPosition(int pos)
{
const int MouseMask = 0x0000001F;
if ((mSequence[mCurrentPos] & MouseMask) == event->button())
{
if (mCurrentPos == mLastPos)
{
activated(false);
mCurrentPos = 0;
}
else if (mCurrentPos > 0)
{
--mCurrentPos;
}
}
mCurrentPos = pos;
}
QShortcutWrapper::QShortcutWrapper(const std::string& name, QShortcut* shortcut)
: QObject(shortcut)
, mName(name)
, mShortcut(shortcut)
void Shortcut::setSequence(const QKeySequence& sequence)
{
State::get().getShortcutManager().addShortcut(this);
setSequence(State::get().getShortcutManager().getSequence(name));
mSequence = sequence;
mCurrentPos = 0;
mLastPos = sequence.count() - 1;
}
QShortcutWrapper::~QShortcutWrapper()
void Shortcut::activate(bool state)
{
State::get().getShortcutManager().removeShortcut(this);
}
mActive = state;
emit activated(state);
const std::string& QShortcutWrapper::getName() const
{
return mName;
if (state)
emit activated();
}
const QKeySequence& QShortcutWrapper::getSequence() const
void Shortcut::enable(bool state)
{
return mSequence;
mEnabled = state;
}
void QShortcutWrapper::setSequence(const QKeySequence& sequence)
QString Shortcut::toString() const
{
mSequence = sequence;
mShortcut->setKey(sequence);
return QString(State::get().getShortcutManager().sequenceToString(mSequence).data());
}
}

@ -1,8 +1,11 @@
#ifndef CSM_PREFS_SHORTCUT_H
#define CSM_PREFS_SHORTCUT_H
#include <string>
#include <QKeySequence>
#include <QObject>
#include <QString>
class QKeyEvent;
class QMouseEvent;
@ -20,10 +23,24 @@ namespace CSMPrefs
Shortcut(const std::string& name, QObject* parent);
~Shortcut();
bool isActive() const;
bool isEnabled() const;
const std::string& getName() const;
const QKeySequence& getSequence() const;
/// The position in the sequence
int getPosition() const;
/// The position in the sequence
int getLastPosition() const;
void setSequence(const QKeySequence& sequence);
/// The position in the sequence
void setPosition(int pos);
void activate(bool state);
void enable(bool state);
QString toString() const;
private:
@ -32,39 +49,16 @@ namespace CSMPrefs
int mCurrentPos;
int mLastPos;
public slots:
void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
bool mActive;
bool mEnabled;
signals:
/// Triggered when the shortcut is activated or deactived; can be determined from \p active
void activated(bool active);
};
/// Wraps a QShortcut object so that the sequence can be modified by the settings
class QShortcutWrapper : public QObject
{
Q_OBJECT
public:
/// Triggered when the shortcut is activated or deactived; can be determined from \p state
void activated(bool state);
QShortcutWrapper(const std::string& name, QShortcut* shortcut);
~QShortcutWrapper();
const std::string& getName() const;
const QKeySequence& getSequence() const;
void setSequence(const QKeySequence& sequence);
private:
std::string mName;
QKeySequence mSequence;
QShortcut* mShortcut;
/// Trigger when activated; convenience signal.
void activated();
};
}

@ -0,0 +1,171 @@
#include "shortcuteventhandler.hpp"
#include <algorithm>
#include <iostream>
#include <QEvent>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QWidget>
#include "shortcut.hpp"
namespace CSMPrefs
{
ShortcutEventHandler::ShortcutEventHandler(QObject* parent)
: QObject(parent)
{
}
void ShortcutEventHandler::addShortcut(Shortcut* shortcut)
{
mShortcuts.push_back(shortcut);
}
void ShortcutEventHandler::removeShortcut(Shortcut* shortcut)
{
std::remove(mShortcuts.begin(), mShortcuts.end(), shortcut);
}
bool ShortcutEventHandler::eventFilter(QObject* watched, QEvent* event)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
unsigned int mod = (unsigned int) keyEvent->modifiers();
unsigned int key = (unsigned int) keyEvent->key();
if (!keyEvent->isAutoRepeat())
return activate(mod, key);
}
else if (event->type() == QEvent::KeyRelease)
{
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
unsigned int key = (unsigned int) keyEvent->key();
if (!keyEvent->isAutoRepeat())
return deactivate(key);
}
else if (event->type() == QEvent::MouseButtonPress)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
unsigned int mod = (unsigned int) mouseEvent->modifiers();
unsigned int button = (unsigned int) mouseEvent->button();
return activate(mod, button);
}
else if (event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
unsigned int button = (unsigned int) mouseEvent->button();
return deactivate(button);
}
else if (event->type() == QEvent::FocusOut)
{
// Deactivate in case events are missed
for (std::vector<Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
{
Shortcut* shortcut = *it;
if (shortcut->isActive())
shortcut->activate(false);
}
}
return false;
}
bool ShortcutEventHandler::activate(unsigned int mod, unsigned int button)
{
std::vector<std::pair<MatchResult, Shortcut*> > potentials;
bool used = false;
// Find potential activations
for (std::vector<Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
{
Shortcut* shortcut = *it;
int pos = shortcut->getPosition();
int lastPos = shortcut->getLastPosition();
MatchResult result = match(mod, button, shortcut->getSequence()[pos]);
if (!shortcut->isEnabled())
continue;
if (result == Matches_WithMod || result == Matches_NoMod)
{
if (pos < lastPos && (result == Matches_WithMod || pos > 0))
{
shortcut->setPosition(pos+1);
used = true;
}
else if (pos == lastPos)
{
potentials.push_back(std::make_pair(result, shortcut));
}
}
}
// Only activate the best match; in exact conflicts, this will favor the first shortcut added.
if (!potentials.empty())
{
std::sort(potentials.begin(), potentials.end(), ShortcutEventHandler::sort);
potentials.front().second->activate(true);
used = true;
}
return used;
}
bool ShortcutEventHandler::deactivate(unsigned int button)
{
const int KeyMask = 0x01FFFFFF;
bool used = false;
for (std::vector<Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
{
Shortcut* shortcut = *it;
int pos = shortcut->getPosition();
MatchResult result = match(0, button, shortcut->getSequence()[pos] & KeyMask);
if (result != Matches_Not)
{
if (shortcut->isActive())
shortcut->activate(false);
shortcut->setPosition(0);
used = true;
}
}
return used;
}
ShortcutEventHandler::MatchResult ShortcutEventHandler::match(unsigned int mod, unsigned int button,
unsigned int value)
{
if ((mod | button) == value)
{
return Matches_WithMod;
}
else if (button == value)
{
return Matches_NoMod;
}
else
{
return Matches_Not;
}
}
bool ShortcutEventHandler::sort(const std::pair<MatchResult, Shortcut*>& left,
const std::pair<MatchResult, Shortcut*>& right)
{
if (left.first == Matches_WithMod && left.first != right.first)
return true;
else
return left.second->getPosition() >= right.second->getPosition();
}
}

@ -0,0 +1,54 @@
#ifndef CSM_PREFS_SHORTCUT_EVENT_HANDLER_H
#define CSM_PREFS_SHORTCUT_EVENT_HANDLER_H
#include <vector>
#include <QObject>
class QEvent;
class QWidget;
namespace CSMPrefs
{
class Shortcut;
/// Users of this class should install it as an event handler
class ShortcutEventHandler : public QObject
{
Q_OBJECT
public:
ShortcutEventHandler(QObject* parent=0);
void addShortcut(Shortcut* shortcut);
void removeShortcut(Shortcut* shortcut);
protected:
bool eventFilter(QObject* watched, QEvent* event);
private:
enum MatchResult
{
Matches_WithMod,
Matches_NoMod,
Matches_Not
};
bool activate(unsigned int mod, unsigned int button);
bool deactivate(unsigned int button);
MatchResult match(unsigned int mod, unsigned int button, unsigned int value);
// Prefers Matches_WithMod and a larger number of buttons
static bool sort(const std::pair<MatchResult, Shortcut*>& left,
const std::pair<MatchResult, Shortcut*>& right);
std::vector<Shortcut*> mShortcuts;
};
}
#endif

@ -16,11 +16,6 @@ namespace CSMPrefs
mShortcuts.insert(std::make_pair(shortcut->getName(), shortcut));
}
void ShortcutManager::addShortcut(QShortcutWrapper* wrapper)
{
mShortcutWrappers.insert(std::make_pair(wrapper->getName(), wrapper));
}
void ShortcutManager::removeShortcut(Shortcut* shortcut)
{
std::pair<ShortcutMap::iterator, ShortcutMap::iterator> range = mShortcuts.equal_range(shortcut->getName());
@ -38,24 +33,6 @@ namespace CSMPrefs
}
}
void ShortcutManager::removeShortcut(QShortcutWrapper* wrapper)
{
std::pair<ShortcutWrapperMap::iterator, ShortcutWrapperMap::iterator> range = mShortcutWrappers.equal_range(
wrapper->getName());
for (ShortcutWrapperMap::iterator it = range.first; it != range.second;)
{
if (it->second == wrapper)
{
mShortcutWrappers.erase(it++);
}
else
{
++it;
}
}
}
QKeySequence ShortcutManager::getSequence(const std::string& name) const
{
QKeySequence sequence;
@ -85,17 +62,11 @@ namespace CSMPrefs
// Change active shortcuts
std::pair<ShortcutMap::iterator, ShortcutMap::iterator> rangeS = mShortcuts.equal_range(name);
std::pair<ShortcutWrapperMap::iterator, ShortcutWrapperMap::iterator> rangeW = mShortcutWrappers.equal_range(name);
for (ShortcutMap::iterator it = rangeS.first; it != rangeS.second; ++it)
{
it->second->setSequence(sequence);
}
for (ShortcutWrapperMap::iterator it = rangeW.first; it != rangeW.second; ++it)
{
it->second->setSequence(sequence);
}
}
std::string ShortcutManager::sequenceToString(const QKeySequence& seq)

@ -9,7 +9,6 @@
namespace CSMPrefs
{
class Shortcut;
class QShortcutWrapper;
/// Class used to track and update shortcuts/sequences
class ShortcutManager : public QObject
@ -20,13 +19,9 @@ namespace CSMPrefs
/// The shortcut class will do this automatically
void addShortcut(Shortcut* shortcut);
/// The wrapper class will do this automatically
void addShortcut(QShortcutWrapper* wrapper);
/// The shortcut class will do this automatically
void removeShortcut(Shortcut* shortcut);
/// The wrapper class will do this automatically
void removeShortcut(QShortcutWrapper* wrapper);
QKeySequence getSequence(const std::string& name) const;
void setSequence(const std::string& name, const QKeySequence& sequence);
@ -38,12 +33,9 @@ namespace CSMPrefs
// Need a multimap in case multiple shortcuts share the same name
typedef std::multimap<std::string, Shortcut*> ShortcutMap;
typedef std::multimap<std::string, QShortcutWrapper*> ShortcutWrapperMap;
typedef std::map<std::string, QKeySequence> SequenceMap;
ShortcutMap mShortcuts;
ShortcutWrapperMap mShortcutWrappers;
SequenceMap mSequences;
};
}

@ -236,6 +236,15 @@ 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));
declareShortcut ("orbit-left", "Orbit camera left", QKeySequence(Qt::Key_A));
declareShortcut ("orbit-right", "Orbit camera right", QKeySequence(Qt::Key_D));
declareShortcut ("orbit-roll-left", "Orbit camera roll left", QKeySequence(Qt::Key_Q));
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));
}
void CSMPrefs::State::declareCategory (const std::string& key)

@ -15,6 +15,7 @@
#include <osgUtil/LineSegmentIntersector>
#include "../../model/prefs/shortcut.hpp"
#include "../../model/prefs/shortcuteventhandler.hpp"
#include "scenewidget.hpp"
@ -81,7 +82,25 @@ namespace CSVRender
mActive = (mCamera != NULL);
if (mActive)
{
onActivate();
QList<CSMPrefs::Shortcut*> shortcuts = findChildren<CSMPrefs::Shortcut*>();
for (QList<CSMPrefs::Shortcut*>::iterator it = shortcuts.begin(); it != shortcuts.end(); ++it)
{
(*it)->enable(true);
}
}
else
{
QList<CSMPrefs::Shortcut*> shortcuts = findChildren<CSMPrefs::Shortcut*>();
for (QList<CSMPrefs::Shortcut*>::iterator it = shortcuts.begin(); it != shortcuts.end(); ++it)
{
(*it)->enable(false);
}
}
}
void CameraController::setCameraSensitivity(double value)
@ -144,7 +163,7 @@ namespace CSVRender
Free Camera Controller
*/
FreeCameraController::FreeCameraController(SceneWidget* scene)
FreeCameraController::FreeCameraController(CSMPrefs::ShortcutEventHandler* handler)
: mLockUpright(false)
, mModified(false)
, mFast(false)
@ -160,31 +179,38 @@ namespace CSVRender
, mSpeedMult(8)
{
CSMPrefs::Shortcut* forwardShortcut = new CSMPrefs::Shortcut("free-forward", this);
scene->addShortcut(forwardShortcut);
forwardShortcut->enable(false);
handler->addShortcut(forwardShortcut);
connect(forwardShortcut, SIGNAL(activated(bool)), this, SLOT(forward(bool)));
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("free-left", this);
scene->addShortcut(leftShortcut);
leftShortcut->enable(false);
handler->addShortcut(leftShortcut);
connect(leftShortcut, SIGNAL(activated(bool)), this, SLOT(left(bool)));
CSMPrefs::Shortcut* backShortcut = new CSMPrefs::Shortcut("free-backward", this);
scene->addShortcut(backShortcut);
backShortcut->enable(false);
handler->addShortcut(backShortcut);
connect(backShortcut, SIGNAL(activated(bool)), this, SLOT(backward(bool)));
CSMPrefs::Shortcut* rightShortcut = new CSMPrefs::Shortcut("free-right", this);
scene->addShortcut(rightShortcut);
rightShortcut->enable(false);
handler->addShortcut(rightShortcut);
connect(rightShortcut, SIGNAL(activated(bool)), this, SLOT(right(bool)));
CSMPrefs::Shortcut* rollLeftShortcut = new CSMPrefs::Shortcut("free-roll-left", this);
scene->addShortcut(rollLeftShortcut);
rollLeftShortcut->enable(false);
handler->addShortcut(rollLeftShortcut);
connect(rollLeftShortcut, SIGNAL(activated(bool)), this, SLOT(rollLeft(bool)));
CSMPrefs::Shortcut* rollRightShortcut = new CSMPrefs::Shortcut("free-roll-right", this);
scene->addShortcut(rollRightShortcut);
rollRightShortcut->enable(false);
handler->addShortcut(rollRightShortcut);
connect(rollRightShortcut, SIGNAL(activated(bool)), this, SLOT(rollRight(bool)));
CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("free-speed-mode", this);
scene->addShortcut(speedModeShortcut);
speedModeShortcut->enable(false);
handler->addShortcut(speedModeShortcut);
connect(speedModeShortcut, SIGNAL(activated(bool)), this, SLOT(swapSpeedMode(bool)));
}
@ -230,14 +256,6 @@ namespace CSVRender
mLockUpright = false;
}
bool FreeCameraController::handleKeyEvent(QKeyEvent* event, bool pressed)
{
if (!isActive())
return false;
return true;
}
bool FreeCameraController::handleMouseMoveEvent(std::string mode, int x, int y)
{
if (!isActive())
@ -412,7 +430,7 @@ namespace CSVRender
Orbit Camera Controller
*/
OrbitCameraController::OrbitCameraController(SceneWidget* widget)
OrbitCameraController::OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler)
: mInitialized(false)
, mFast(false)
, mLeft(false)
@ -427,6 +445,40 @@ namespace CSVRender
, mOrbitSpeed(osg::PI / 4)
, mOrbitSpeedMult(4)
{
CSMPrefs::Shortcut* upShortcut = new CSMPrefs::Shortcut("orbit-up", this);
upShortcut->enable(false);
handler->addShortcut(upShortcut);
connect(upShortcut, SIGNAL(activated(bool)), this, SLOT(up(bool)));
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("orbit-left", this);
leftShortcut->enable(false);
handler->addShortcut(leftShortcut);
connect(leftShortcut, SIGNAL(activated(bool)), this, SLOT(left(bool)));
CSMPrefs::Shortcut* downShortcut = new CSMPrefs::Shortcut("orbit-down", this);
downShortcut->enable(false);
handler->addShortcut(downShortcut);
connect(downShortcut, SIGNAL(activated(bool)), this, SLOT(down(bool)));
CSMPrefs::Shortcut* rightShortcut = new CSMPrefs::Shortcut("orbit-right", this);
rightShortcut->enable(false);
handler->addShortcut(rightShortcut);
connect(rightShortcut, SIGNAL(activated(bool)), this, SLOT(right(bool)));
CSMPrefs::Shortcut* rollLeftShortcut = new CSMPrefs::Shortcut("orbit-roll-left", this);
rollLeftShortcut->enable(false);
handler->addShortcut(rollLeftShortcut);
connect(rollLeftShortcut, SIGNAL(activated(bool)), this, SLOT(rollLeft(bool)));
CSMPrefs::Shortcut* rollRightShortcut = new CSMPrefs::Shortcut("orbit-roll-right", this);
rollRightShortcut->enable(false);
handler->addShortcut(rollRightShortcut);
connect(rollRightShortcut, SIGNAL(activated(bool)), this, SLOT(rollRight(bool)));
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)));
}
osg::Vec3d OrbitCameraController::getCenter() const
@ -477,50 +529,6 @@ namespace CSVRender
mPickingMask = value;
}
bool OrbitCameraController::handleKeyEvent(QKeyEvent* event, bool pressed)
{
if (!isActive())
return false;
if (!mInitialized)
initialize();
if (event->key() == Qt::Key_Q)
{
mRollLeft = pressed;
}
else if (event->key() == Qt::Key_E)
{
mRollRight = pressed;
}
else if (event->key() == Qt::Key_A)
{
mLeft = pressed;
}
else if (event->key() == Qt::Key_D)
{
mRight = pressed;
}
else if (event->key() == Qt::Key_W)
{
mUp = pressed;
}
else if (event->key() == Qt::Key_S)
{
mDown = pressed;
}
else if (event->key() == Qt::Key_Shift)
{
mFast = pressed;
}
else
{
return false;
}
return true;
}
bool OrbitCameraController::handleMouseMoveEvent(std::string mode, int x, int y)
{
if (!isActive())
@ -687,4 +695,46 @@ namespace CSVRender
getCamera()->setViewMatrixAsLookAt(mCenter + offset, mCenter, up);
}
void OrbitCameraController::up(bool active)
{
if (isActive())
mUp = active;
}
void OrbitCameraController::left(bool active)
{
if (isActive())
mLeft = active;
}
void OrbitCameraController::down(bool active)
{
if (isActive())
mDown = active;
}
void OrbitCameraController::right(bool active)
{
if (isActive())
mRight = active;
}
void OrbitCameraController::rollLeft(bool active)
{
if (isActive())
mRollLeft = active;
}
void OrbitCameraController::rollRight(bool active)
{
if (isActive())
mRollRight = active;
}
void OrbitCameraController::swapSpeedMode(bool active)
{
if (isActive() && active)
mFast = !mFast;
}
}

@ -16,6 +16,11 @@ namespace osg
class Group;
}
namespace CSMPrefs
{
class ShortcutEventHandler;
}
namespace CSVRender
{
class SceneWidget;
@ -52,7 +57,6 @@ namespace CSVRender
// moves the camera to an intelligent position
void setup(osg::Group* root, unsigned int mask, const osg::Vec3d& up);
virtual bool handleKeyEvent(QKeyEvent* event, bool pressed) = 0;
virtual bool handleMouseMoveEvent(std::string mode, int x, int y) = 0;
virtual void update(double dt) = 0;
@ -79,7 +83,7 @@ namespace CSVRender
public:
FreeCameraController(SceneWidget* widget);
FreeCameraController(CSMPrefs::ShortcutEventHandler* handler);
double getLinearSpeed() const;
double getRotationalSpeed() const;
@ -92,7 +96,6 @@ namespace CSVRender
void fixUpAxis(const osg::Vec3d& up);
void unfixUpAxis();
bool handleKeyEvent(QKeyEvent* event, bool pressed);
bool handleMouseMoveEvent(std::string mode, int x, int y);
void update(double dt);
@ -133,7 +136,7 @@ namespace CSVRender
public:
OrbitCameraController(SceneWidget* widget);
OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler);
osg::Vec3d getCenter() const;
double getOrbitSpeed() const;
@ -145,7 +148,6 @@ namespace CSVRender
void setOrbitSpeedMultiplier(double value);
void setPickingMask(unsigned int value);
bool handleKeyEvent(QKeyEvent* event, bool pressed);
bool handleMouseMoveEvent(std::string mode, int x, int y);
void update(double dt);
@ -172,6 +174,16 @@ namespace CSVRender
double mOrbitSpeed;
double mOrbitSpeedMult;
private slots:
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);
};
}

@ -20,6 +20,7 @@
#include "../../model/prefs/state.hpp"
#include "../../model/prefs/shortcut.hpp"
#include "../../model/prefs/shortcuteventhandler.hpp"
#include "lighting.hpp"
#include "mask.hpp"
@ -159,13 +160,13 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
, mHasDefaultAmbient(false)
, mPrevMouseX(0)
, mPrevMouseY(0)
, mFreeCamControl(0)
, mOrbitCamControl(0)
, mCurrentCamControl(0)
, mCamPositionSet(false)
{
mFreeCamControl.reset(new FreeCameraController(this));
mOrbitCamControl.reset(new OrbitCameraController(this));
mShortcutHandler = new CSMPrefs::ShortcutEventHandler(this);
installEventFilter(mShortcutHandler);
mFreeCamControl.reset(new FreeCameraController(mShortcutHandler));
mOrbitCamControl.reset(new OrbitCameraController(mShortcutHandler));
mCurrentCamControl = mFreeCamControl.get();
mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain);
@ -201,6 +202,8 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
SceneWidget::~SceneWidget()
{
removeEventFilter(mShortcutHandler);
// Since we're holding on to the scene templates past the existance of this graphics context, we'll need to manually release the created objects
mResourceSystem->getSceneManager()->releaseGLObjects(mView->getCamera()->getGraphicsContext()->getState());
}
@ -276,57 +279,17 @@ void SceneWidget::setDefaultAmbient (const osg::Vec4f& colour)
setAmbient(mLighting->getAmbientColour(&mDefaultAmbient));
}
bool SceneWidget::event(QEvent *event)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
SceneWidget::keyPressEvent(keyEvent);
}
else if (event->type() == QEvent::KeyRelease)
{
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
SceneWidget::keyReleaseEvent(keyEvent);
}
else if (event->type() == QEvent::MouseButtonPress)
{
QMouseEvent* keyEvent = static_cast<QMouseEvent*>(event);
SceneWidget::mousePressEvent(keyEvent);
}
else if (event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent* keyEvent = static_cast<QMouseEvent*>(event);
SceneWidget::mouseReleaseEvent(keyEvent);
}
else
{
return RenderWidget::event(event);
}
return true;
}
void SceneWidget::mousePressEvent (QMouseEvent *event)
{
mMouseMode = mapButton(event);
mPrevMouseX = event->x();
mPrevMouseY = event->y();
for (std::vector<CSMPrefs::Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
{
(*it)->mousePressEvent(event);
}
}
void SceneWidget::mouseReleaseEvent (QMouseEvent *event)
{
mMouseMode = "";
for (std::vector<CSMPrefs::Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
{
(*it)->mouseReleaseEvent(event);
}
}
void SceneWidget::mouseMoveEvent (QMouseEvent *event)
@ -347,26 +310,6 @@ void SceneWidget::wheelEvent(QWheelEvent *event)
mCurrentCamControl->handleMouseMoveEvent("t-navi", event->delta(), 0);
}
void SceneWidget::keyPressEvent (QKeyEvent *event)
{
mCurrentCamControl->handleKeyEvent(event, true);
for (std::vector<CSMPrefs::Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
{
(*it)->keyPressEvent(event);
}
}
void SceneWidget::keyReleaseEvent (QKeyEvent *event)
{
mCurrentCamControl->handleKeyEvent(event, false);
for (std::vector<CSMPrefs::Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
{
(*it)->keyReleaseEvent(event);
}
}
void SceneWidget::update(double dt)
{
if (mCamPositionSet)
@ -508,9 +451,4 @@ std::string SceneWidget::mapButton (QMouseEvent *event)
return "";
}
void SceneWidget::addShortcut(CSMPrefs::Shortcut* shortcut)
{
mShortcuts.push_back(shortcut);
}
}

@ -7,14 +7,15 @@
#include <QWidget>
#include <QTimer>
#include <osgViewer/View>
#include <osgViewer/CompositeViewer>
#include <boost/shared_ptr.hpp>
#include "lightingday.hpp"
#include "lightingnight.hpp"
#include "lightingbright.hpp"
#include <osgViewer/View>
#include <osgViewer/CompositeViewer>
namespace Resource
{
@ -37,6 +38,7 @@ namespace CSMPrefs
{
class Setting;
class Shortcut;
class ShortcutEventHandler;
}
namespace CSVRender
@ -85,21 +87,16 @@ namespace CSVRender
void setDefaultAmbient (const osg::Vec4f& colour);
///< \note The actual ambient colour may differ based on lighting settings.
void addShortcut(CSMPrefs::Shortcut* shortcut);
protected:
void setLighting (Lighting *lighting);
///< \attention The ownership of \a lighting is not transferred to *this.
void setAmbient(const osg::Vec4f& ambient);
virtual bool event(QEvent *event);
virtual void mousePressEvent (QMouseEvent *event);
virtual void mouseReleaseEvent (QMouseEvent *event);
virtual void mouseMoveEvent (QMouseEvent *event);
virtual void wheelEvent (QWheelEvent *event);
virtual void keyPressEvent (QKeyEvent *event);
virtual void keyReleaseEvent (QKeyEvent *event);
virtual void focusOutEvent (QFocusEvent *event);
/// \return Is \a key a button mapping setting? (ignored otherwise)
@ -124,7 +121,7 @@ namespace CSVRender
CameraController* mCurrentCamControl;
std::map<std::pair<Qt::MouseButton, bool>, std::string> mButtonMapping;
std::vector<CSMPrefs::Shortcut*> mShortcuts;
CSMPrefs::ShortcutEventHandler *mShortcutHandler;
private:
bool mCamPositionSet;

Loading…
Cancel
Save