Changed shortcut design to allow a configurable second output. Also

re-added shift for temporarily changing camera speed.
pull/990/head
Aesylwinn 9 years ago
parent 1b5273f2b7
commit 455d227f3c

@ -11,24 +11,41 @@ namespace CSMPrefs
{
Shortcut::Shortcut(const std::string& name, QObject* parent)
: QObject(parent)
, mEnabled(true)
, mName(name)
, mSecondaryMode(SM_Ignore)
, mModifier(0)
, mCurrentPos(0)
, mLastPos(0)
, mActive(false)
, mEnabled(true)
, mActivationStatus(AS_Inactive)
, mModifierStatus(false)
{
State::get().getShortcutManager().addShortcut(this);
setSequence(State::get().getShortcutManager().getSequence(name));
ShortcutManager::SequenceData data = State::get().getShortcutManager().getSequence(name);
setSequence(data.first);
setModifier(data.second);
}
Shortcut::~Shortcut()
Shortcut::Shortcut(const std::string& name, SecondaryMode secMode, QObject* parent)
: QObject(parent)
, mEnabled(true)
, mName(name)
, mSecondaryMode(secMode)
, mModifier(0)
, mCurrentPos(0)
, mLastPos(0)
, mActivationStatus(AS_Inactive)
, mModifierStatus(false)
{
State::get().getShortcutManager().removeShortcut(this);
State::get().getShortcutManager().addShortcut(this);
ShortcutManager::SequenceData data = State::get().getShortcutManager().getSequence(name);
setSequence(data.first);
setModifier(data.second);
}
bool Shortcut::isActive() const
Shortcut::~Shortcut()
{
return mActive;
State::get().getShortcutManager().removeShortcut(this);
}
bool Shortcut::isEnabled() const
@ -41,11 +58,21 @@ namespace CSMPrefs
return mName;
}
Shortcut::SecondaryMode Shortcut::getSecondaryMode() const
{
return mSecondaryMode;
}
const QKeySequence& Shortcut::getSequence() const
{
return mSequence;
}
int Shortcut::getModifier() const
{
return mModifier;
}
int Shortcut::getPosition() const
{
return mCurrentPos;
@ -56,9 +83,19 @@ namespace CSMPrefs
return mLastPos;
}
void Shortcut::setPosition(int pos)
Shortcut::ActivationStatus Shortcut::getActivationStatus() const
{
mCurrentPos = pos;
return mActivationStatus;
}
bool Shortcut::getModifierStatus() const
{
return mModifierStatus;
}
void Shortcut::enable(bool state)
{
mEnabled = state;
}
void Shortcut::setSequence(const QKeySequence& sequence)
@ -68,22 +105,28 @@ namespace CSMPrefs
mLastPos = sequence.count() - 1;
}
void Shortcut::activate(bool state)
void Shortcut::setModifier(int modifier)
{
mActive = state;
emit activated(state);
mModifier = modifier;
}
if (state)
emit activated();
void Shortcut::setPosition(int pos)
{
mCurrentPos = pos;
}
void Shortcut::enable(bool state)
void Shortcut::setActivationStatus(ActivationStatus status)
{
mEnabled = state;
mActivationStatus = status;
}
void Shortcut::setModifierStatus(bool status)
{
mModifierStatus = status;
}
QString Shortcut::toString() const
{
return QString(State::get().getShortcutManager().sequenceToString(mSequence).data());
return QString(State::get().getShortcutManager().sequenceToString(std::make_pair(mSequence, mModifier)).data());
}
}

@ -20,45 +20,83 @@ namespace CSMPrefs
public:
enum ActivationStatus
{
AS_Regular,
AS_Secondary,
AS_Inactive
};
enum SecondaryMode
{
SM_Replace, ///< The secondary signal replaces the regular signal when the modifier is active
SM_Detach, ///< The secondary signal is emitted independant of the regular signal, even if not active
SM_Ignore ///< The secondary signal will not ever be emitted
};
Shortcut(const std::string& name, QObject* parent);
Shortcut(const std::string& name, SecondaryMode secMode, QObject* parent);
~Shortcut();
bool isActive() const;
bool isEnabled() const;
const std::string& getName() const;
SecondaryMode getSecondaryMode() const;
const QKeySequence& getSequence() const;
int getModifier() const;
/// The position in the sequence
int getPosition() const;
/// The position in the sequence
int getLastPosition() const;
ActivationStatus getActivationStatus() const;
bool getModifierStatus() const;
void enable(bool state);
void setSequence(const QKeySequence& sequence);
void setModifier(int modifier);
/// The position in the sequence
void setPosition(int pos);
void activate(bool state);
void enable(bool state);
void setActivationStatus(ActivationStatus status);
void setModifierStatus(bool status);
QString toString() const;
private:
bool mEnabled;
std::string mName;
SecondaryMode mSecondaryMode;
QKeySequence mSequence;
int mModifier;
int mCurrentPos;
int mLastPos;
bool mActive;
bool mEnabled;
ActivationStatus mActivationStatus;
bool mModifierStatus;
signals:
/// Triggered when the shortcut is activated or deactived; can be determined from \p state
/// Triggered when the shortcut is activated or deactivated; can be determined from \p state
void activated(bool state);
/// Trigger when activated; convenience signal.
/// Convenience signal.
void activated();
/// Triggered depending on SecondaryMode
void secondary(bool state);
/// Convenience signal.
void secondary();
};
}

@ -41,10 +41,11 @@ namespace CSMPrefs
else if (event->type() == QEvent::KeyRelease)
{
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
unsigned int mod = (unsigned int) keyEvent->modifiers();
unsigned int key = (unsigned int) keyEvent->key();
if (!keyEvent->isAutoRepeat())
return deactivate(key);
return deactivate(mod, key);
}
else if (event->type() == QEvent::MouseButtonPress)
{
@ -57,9 +58,10 @@ namespace CSMPrefs
else if (event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
unsigned int mod = (unsigned int) mouseEvent->modifiers();
unsigned int button = (unsigned int) mouseEvent->button();
return deactivate(button);
return deactivate(mod, button);
}
else if (event->type() == QEvent::FocusOut)
{
@ -68,10 +70,18 @@ namespace CSMPrefs
{
Shortcut* shortcut = *it;
if (shortcut->isActive())
shortcut->setPosition(0);
shortcut->setModifierStatus(false);
if (shortcut->getActivationStatus() == Shortcut::AS_Regular)
{
shortcut->activate(false);
shortcut->setPosition(0);
shortcut->setActivationStatus(Shortcut::AS_Inactive);
emit shortcut->activated(false);
}
else if (shortcut->getActivationStatus() == Shortcut::AS_Secondary)
{
shortcut->setActivationStatus(Shortcut::AS_Inactive);
emit shortcut->secondary(false);
}
}
}
@ -88,39 +98,56 @@ namespace CSMPrefs
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;
int pos = shortcut->getPosition();
int lastPos = shortcut->getLastPosition();
MatchResult result = match(mod, button, shortcut->getSequence()[pos]);
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));
}
}
if (checkModifier(mod, button, shortcut, true))
used = true;
}
// 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);
Shortcut* shortcut = potentials.front().second;
if (shortcut->getModifierStatus() && shortcut->getSecondaryMode() == Shortcut::SM_Replace)
{
shortcut->setActivationStatus(Shortcut::AS_Secondary);
emit shortcut->secondary(true);
emit shortcut->secondary();
}
else
{
shortcut->setActivationStatus(Shortcut::AS_Regular);
emit shortcut->activated(true);
emit shortcut->activated();
}
used = true;
}
return used;
}
bool ShortcutEventHandler::deactivate(unsigned int button)
bool ShortcutEventHandler::deactivate(unsigned int mod, unsigned int button)
{
const int KeyMask = 0x01FFFFFF;
@ -129,16 +156,66 @@ namespace CSMPrefs
for (std::vector<Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
{
Shortcut* shortcut = *it;
if (checkModifier(mod, button, shortcut, false))
used = true;
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);
if (shortcut->getActivationStatus() == Shortcut::AS_Regular)
{
shortcut->setActivationStatus(Shortcut::AS_Inactive);
emit shortcut->activated(false);
used = true;
}
else if (shortcut->getActivationStatus() == Shortcut::AS_Secondary)
{
shortcut->setActivationStatus(Shortcut::AS_Inactive);
emit shortcut->secondary(false);
used = true;
}
}
}
return used;
}
bool ShortcutEventHandler::checkModifier(unsigned int mod, unsigned int button, Shortcut* shortcut, bool activate)
{
if (!shortcut->isEnabled() || !shortcut->getModifier() || shortcut->getSecondaryMode() == Shortcut::SM_Ignore)
return false;
MatchResult result = match(mod, button, shortcut->getModifier());
bool used = false;
if (result != Matches_Not)
{
shortcut->setModifierStatus(activate);
if (shortcut->getSecondaryMode() == Shortcut::SM_Detach)
{
if (activate)
{
emit shortcut->secondary(true);
emit shortcut->secondary();
}
else
{
emit shortcut->secondary(false);
}
used = true;
}
else if (!activate && shortcut->getActivationStatus() == Shortcut::AS_Secondary)
{
shortcut->setActivationStatus(Shortcut::AS_Inactive);
shortcut->setPosition(0);
emit shortcut->secondary(false);
used = true;
}
}

@ -39,7 +39,9 @@ namespace CSMPrefs
bool activate(unsigned int mod, unsigned int button);
bool deactivate(unsigned int button);
bool deactivate(unsigned int mod, unsigned int button);
bool checkModifier(unsigned int mod, unsigned int button, Shortcut* shortcut, bool activate);
MatchResult match(unsigned int mod, unsigned int button, unsigned int value);

@ -33,31 +33,31 @@ namespace CSMPrefs
}
}
QKeySequence ShortcutManager::getSequence(const std::string& name) const
ShortcutManager::SequenceData ShortcutManager::getSequence(const std::string& name) const
{
QKeySequence sequence;
SequenceData data;
SequenceMap::const_iterator item = mSequences.find(name);
if (item != mSequences.end())
{
sequence = item->second;
data = item->second;
}
return sequence;
return data;
}
void ShortcutManager::setSequence(const std::string& name, const QKeySequence& sequence)
void ShortcutManager::setSequence(const std::string& name, const SequenceData& data)
{
// Add to map/modify
SequenceMap::iterator item = mSequences.find(name);
if (item != mSequences.end())
{
item->second = sequence;
item->second = data;
}
else
{
mSequences.insert(std::make_pair(name, sequence));
mSequences.insert(std::make_pair(name, data));
}
// Change active shortcuts
@ -65,11 +65,12 @@ namespace CSMPrefs
for (ShortcutMap::iterator it = rangeS.first; it != rangeS.second; ++it)
{
it->second->setSequence(sequence);
it->second->setSequence(data.first);
it->second->setModifier(data.second);
}
}
std::string ShortcutManager::sequenceToString(const QKeySequence& seq)
std::string ShortcutManager::sequenceToString(const SequenceData& data)
{
const int MouseMask = 0x0000001F; // Conflicts with key
const int KeyMask = 0x01FFFFFF;
@ -80,27 +81,28 @@ namespace CSMPrefs
std::string output;
for (int i = 0; i < seq.count(); ++i)
// KeySequence
for (unsigned int i = 0; i < data.first.count(); ++i)
{
if (seq[i] & ModMask)
if (data.first[i] & ModMask)
{
// TODO separate out modifiers to allow more than 1
output.append(staticQtMetaObject.enumerator(ModEnumIndex).valueToKey(seq[i] & ModMask));
output.append(staticQtMetaObject.enumerator(ModEnumIndex).valueToKey(data.first[i] & ModMask));
output.append("+");
}
if (seq[i] & KeyMask & ~MouseMask)
if (data.first[i] & KeyMask & ~MouseMask)
{
// Is a key
output.append(staticQtMetaObject.enumerator(KeyEnumIndex).valueToKey(seq[i] & KeyMask));
output.append(staticQtMetaObject.enumerator(KeyEnumIndex).valueToKey(data.first[i] & KeyMask));
output.append(",");
}
else if (seq[i] & MouseMask)
else if (data.first[i] & MouseMask)
{
std::stringstream ss;
std::string num;
unsigned int value = (unsigned int)(seq[i] & MouseMask);
unsigned int value = (unsigned int)(data.first[i] & MouseMask);
// value will never be 0
int exponent = 1; // Offset by 1
@ -123,18 +125,56 @@ namespace CSMPrefs
output.resize(output.size() - 1);
}
// Add modifier if needed
if (data.second & ModMask)
{
output.append(";");
output.append(staticQtMetaObject.enumerator(ModEnumIndex).valueToKey(data.second & ModMask));
}
else if (data.second & KeyMask & ~MouseMask)
{
output.append(";");
output.append(staticQtMetaObject.enumerator(KeyEnumIndex).valueToKey(data.second & KeyMask));
}
else if (data.second & MouseMask)
{
std::stringstream ss;
std::string num;
unsigned int value = (unsigned int)(data.second & MouseMask);
// value will never be 0
int exponent = 1; // Offset by 1
while (value >>= 1)
++exponent;
ss << exponent;
ss >> num;
// Is a mouse button
output.append(";Mouse");
output.append(num);
}
return output;
}
QKeySequence ShortcutManager::stringToSequence(const std::string& input)
ShortcutManager::SequenceData ShortcutManager::stringToSequence(const std::string& input)
{
// TODO clean and standardize
const int KeyEnumIndex = staticQtMetaObject.indexOfEnumerator("Key");
const int ModEnumIndex = staticQtMetaObject.indexOfEnumerator("KeyboardModifiers");
int keys[4] = { 0, 0, 0, 0 };
int modifier = 0;
size_t middle = input.find(';');
std::string sequenceStr = input.substr(0, middle);
std::string modifierStr = input.substr((middle < input.size())? middle + 1 : input.size());
QRegExp splitRX("[, ]");
QStringList keyStrs = QString(input.c_str()).split(splitRX, QString::SkipEmptyParts);
QStringList keyStrs = QString(sequenceStr.c_str()).split(splitRX, QString::SkipEmptyParts);
for (int i = 0; i < keyStrs.size(); ++i)
{
@ -162,9 +202,29 @@ namespace CSMPrefs
}
}
if (!modifierStr.empty())
{
if (modifierStr.find("Mouse") != std::string::npos)
{
QString num = QString::fromUtf8(modifierStr.substr(5).data());
if (num > 0)
{
modifier = 1 << (num.toInt() - 1); // offset by 1
}
}
else if (staticQtMetaObject.enumerator(ModEnumIndex).keyToValue(modifierStr.data()) != -1)
{
modifier = staticQtMetaObject.enumerator(ModEnumIndex).keyToValue(modifierStr.data());
}
else if (staticQtMetaObject.enumerator(KeyEnumIndex).keyToValue(modifierStr.data()) != -1)
{
modifier = staticQtMetaObject.enumerator(KeyEnumIndex).keyToValue(modifierStr.data());
}
}
// TODO remove
std::cout << input << '.' << keys[0] << '.'<< keys[1] << '.'<< keys[2] << '.'<< keys[3] << std::endl;
std::cout << input << '.' << keys[0] << '.'<< keys[1] << '.'<< keys[2] << '.'<< keys[3] << '.' << modifier << std::endl;
return QKeySequence(keys[0], keys[1], keys[2], keys[3]);
return std::make_pair(QKeySequence(keys[0], keys[1], keys[2], keys[3]), modifier);
}
}

@ -17,23 +17,26 @@ namespace CSMPrefs
public:
/// Key Sequence, Modifier (for secondary signal)
typedef std::pair<QKeySequence, int> SequenceData;
/// The shortcut class will do this automatically
void addShortcut(Shortcut* shortcut);
/// The shortcut class will do this automatically
void removeShortcut(Shortcut* shortcut);
QKeySequence getSequence(const std::string& name) const;
void setSequence(const std::string& name, const QKeySequence& sequence);
SequenceData getSequence(const std::string& name) const;
void setSequence(const std::string& name, const SequenceData& sequence);
std::string sequenceToString(const QKeySequence& sequence);
QKeySequence stringToSequence(const std::string& str);
std::string sequenceToString(const SequenceData& sequence);
SequenceData stringToSequence(const std::string& str);
private:
// Need a multimap in case multiple shortcuts share the same name
typedef std::multimap<std::string, Shortcut*> ShortcutMap;
typedef std::map<std::string, QKeySequence> SequenceMap;
typedef std::map<std::string, SequenceData> SequenceMap;
ShortcutMap mShortcuts;
SequenceMap mSequences;

@ -10,7 +10,7 @@
namespace CSMPrefs
{
ShortcutSetting::ShortcutSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key,
const std::string& label, const QKeySequence& default_)
const std::string& label, const SequenceData& default_)
: Setting(parent, values, mutex, key, label)
, mDefault(default_)
{
@ -33,9 +33,9 @@ namespace CSMPrefs
QMutexLocker lock(getMutex());
getValues().setString(getKey(), getParent()->getKey(), text.toUtf8().data());
QKeySequence sequence = State::get().getShortcutManager().stringToSequence(text.toUtf8().data());
SequenceData data = State::get().getShortcutManager().stringToSequence(text.toUtf8().data());
State::get().getShortcutManager().setSequence(getKey(), sequence);
State::get().getShortcutManager().setSequence(getKey(), data);
}
getParent()->getState()->update(*this);

@ -11,16 +11,20 @@ namespace CSMPrefs
{
Q_OBJECT
QKeySequence mDefault;
public:
typedef std::pair<QKeySequence, int> SequenceData;
ShortcutSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key,
const std::string& label, const QKeySequence& default_);
const std::string& label, const SequenceData& default_);
// TODO replace with custom page
virtual std::pair<QWidget*, QWidget*> makeWidgets(QWidget* parent);
private:
SequenceData mDefault;
private slots:
void valueChanged(const QString& text);

@ -229,7 +229,7 @@ void CSMPrefs::State::declare()
addValues (insertOutsideVisibleCell);
declareCategory ("Key Bindings");
declareShortcut ("free-forward", "Free camera forward", QKeySequence(Qt::Key_W));
declareShortcut ("free-forward", "Free camera forward", QKeySequence(Qt::Key_W), Qt::Key_Shift);
declareShortcut ("free-backward", "Free camera backward", QKeySequence(Qt::Key_S));
declareShortcut ("free-left", "Free camera left", QKeySequence(Qt::Key_A));
declareShortcut ("free-right", "Free camera right", QKeySequence(Qt::Key_D));
@ -238,7 +238,7 @@ void CSMPrefs::State::declare()
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-up", "Orbit camera up", QKeySequence(Qt::Key_W), Qt::Key_Shift);
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));
@ -377,19 +377,19 @@ CSMPrefs::ColourSetting& CSMPrefs::State::declareColour (const std::string& key,
}
CSMPrefs::ShortcutSetting& CSMPrefs::State::declareShortcut (const std::string& key, const std::string& label,
const QKeySequence& default_)
const QKeySequence& default_, int modifier)
{
if (mCurrentCategory==mCategories.end())
throw std::logic_error ("no category for setting");
std::string seqStr = getShortcutManager().sequenceToString(default_);
std::string seqStr = getShortcutManager().sequenceToString(std::make_pair(default_, modifier));
setDefault (key, seqStr);
QKeySequence seq = getShortcutManager().stringToSequence(mSettings.getString(key,
ShortcutManager::SequenceData data = getShortcutManager().stringToSequence(mSettings.getString(key,
mCurrentCategory->second.getKey()));
CSMPrefs::ShortcutSetting *setting = new CSMPrefs::ShortcutSetting (&mCurrentCategory->second, &mSettings, &mMutex,
key, label, seq);
key, label, data);
mCurrentCategory->second.addSetting (setting);

@ -74,7 +74,8 @@ namespace CSMPrefs
ColourSetting& declareColour (const std::string& key, const std::string& label, QColor default_);
ShortcutSetting& declareShortcut (const std::string& key, const std::string& label, const QKeySequence& default_);
ShortcutSetting& declareShortcut (const std::string& key, const std::string& label,
const QKeySequence& default_, int modifier=0);
void declareSeparator();

@ -169,6 +169,7 @@ namespace CSVRender
, mLockUpright(false)
, mModified(false)
, mFast(false)
, mFastAlternate(false)
, mLeft(false)
, mRight(false)
, mForward(false)
@ -190,10 +191,12 @@ namespace CSVRender
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", CSMPrefs::Shortcut::SM_Detach,
this);
forwardShortcut->enable(false);
handler->addShortcut(forwardShortcut);
connect(forwardShortcut, SIGNAL(activated(bool)), this, SLOT(forward(bool)));
connect(forwardShortcut, SIGNAL(secondary(bool)), this, SLOT(alternateFast(bool)));
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("free-left", this);
leftShortcut->enable(false);
@ -294,7 +297,7 @@ namespace CSVRender
if (!isActive())
return;
translate(LocalForward * x * (mFast ? getWheelMovementMultiplier() : 1));
translate(LocalForward * x * ((mFast ^ mFastAlternate) ? getWheelMovementMultiplier() : 1));
}
void FreeCameraController::update(double dt)
@ -305,7 +308,7 @@ namespace CSVRender
double linDist = mLinSpeed * dt;
double rotDist = mRotSpeed * dt;
if (mFast)
if (mFast ^ mFastAlternate)
linDist *= mSpeedMult;
if (mLeft)
@ -423,6 +426,11 @@ namespace CSVRender
mRollRight = active;
}
void FreeCameraController::alternateFast(bool active)
{
mFastAlternate = active;
}
void FreeCameraController::swapSpeedMode()
{
mFast = !mFast;
@ -436,6 +444,7 @@ namespace CSVRender
: CameraController(parent)
, mInitialized(false)
, mFast(false)
, mFastAlternate(false)
, mLeft(false)
, mRight(false)
, mUp(false)
@ -458,10 +467,11 @@ namespace CSVRender
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", CSMPrefs::Shortcut::SM_Detach, this);
upShortcut->enable(false);
handler->addShortcut(upShortcut);
connect(upShortcut, SIGNAL(activated(bool)), this, SLOT(up(bool)));
connect(upShortcut, SIGNAL(secondary(bool)), this, SLOT(alternateFast(bool)));
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("orbit-left", this);
leftShortcut->enable(false);
@ -571,7 +581,7 @@ namespace CSVRender
if (!isActive())
return;
zoom(-x * (mFast ? getWheelMovementMultiplier() : 1));
zoom(-x * ((mFast ^ mFastAlternate) ? getWheelMovementMultiplier() : 1));
}
void OrbitCameraController::update(double dt)
@ -584,7 +594,7 @@ namespace CSVRender
double rotDist = mOrbitSpeed * dt;
if (mFast)
if (mFast ^ mFastAlternate)
rotDist *= mOrbitSpeedMult;
if (mLeft)
@ -737,6 +747,11 @@ namespace CSVRender
mRollRight = active;
}
void OrbitCameraController::alternateFast(bool active)
{
mFastAlternate = active;
}
void OrbitCameraController::swapSpeedMode()
{
mFast = !mFast;

@ -111,7 +111,8 @@ namespace CSVRender
bool mLockUpright, mModified;
bool mNaviPrimary, mNaviSecondary;
bool mFast, mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight;
bool mFast, mFastAlternate;
bool mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight;
osg::Vec3d mUp;
double mLinSpeed;
@ -128,6 +129,7 @@ namespace CSVRender
void right(bool active);
void rollLeft(bool active);
void rollRight(bool active);
void alternateFast(bool active);
void swapSpeedMode();
};
@ -168,7 +170,8 @@ namespace CSVRender
bool mInitialized;
bool mNaviPrimary, mNaviSecondary;
bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight;
bool mFast, mFastAlternate;
bool mLeft, mRight, mUp, mDown, mRollLeft, mRollRight;
unsigned int mPickingMask;
osg::Vec3d mCenter;
double mDistance;
@ -186,6 +189,7 @@ namespace CSVRender
void right(bool active);
void rollLeft(bool active);
void rollRight(bool active);
void alternateFast(bool active);
void swapSpeedMode();
};
}

Loading…
Cancel
Save