forked from mirror/openmw-tes3mp
Redesigned shortcut handler to be capable of dealing with child and
parent widgets. This should be the final design change. Also, some various bug fixes.
This commit is contained in:
parent
acdb636935
commit
f251c3867d
16 changed files with 285 additions and 161 deletions
|
@ -1,15 +1,15 @@
|
||||||
#include "shortcut.hpp"
|
#include "shortcut.hpp"
|
||||||
|
|
||||||
#include <QKeyEvent>
|
#include <cassert>
|
||||||
#include <QMouseEvent>
|
|
||||||
#include <QShortcut>
|
#include <QWidget>
|
||||||
|
|
||||||
#include "state.hpp"
|
#include "state.hpp"
|
||||||
#include "shortcutmanager.hpp"
|
#include "shortcutmanager.hpp"
|
||||||
|
|
||||||
namespace CSMPrefs
|
namespace CSMPrefs
|
||||||
{
|
{
|
||||||
Shortcut::Shortcut(const std::string& name, QObject* parent)
|
Shortcut::Shortcut(const std::string& name, QWidget* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, mEnabled(true)
|
, mEnabled(true)
|
||||||
, mName(name)
|
, mName(name)
|
||||||
|
@ -20,13 +20,15 @@ namespace CSMPrefs
|
||||||
, mActivationStatus(AS_Inactive)
|
, mActivationStatus(AS_Inactive)
|
||||||
, mModifierStatus(false)
|
, mModifierStatus(false)
|
||||||
{
|
{
|
||||||
|
assert (parent);
|
||||||
|
|
||||||
State::get().getShortcutManager().addShortcut(this);
|
State::get().getShortcutManager().addShortcut(this);
|
||||||
ShortcutManager::SequenceData data = State::get().getShortcutManager().getSequence(name);
|
ShortcutManager::SequenceData data = State::get().getShortcutManager().getSequence(name);
|
||||||
setSequence(data.first);
|
setSequence(data.first);
|
||||||
setModifier(data.second);
|
setModifier(data.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
Shortcut::Shortcut(const std::string& name, SecondaryMode secMode, QObject* parent)
|
Shortcut::Shortcut(const std::string& name, SecondaryMode secMode, QWidget* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, mEnabled(true)
|
, mEnabled(true)
|
||||||
, mName(name)
|
, mName(name)
|
||||||
|
@ -37,6 +39,8 @@ namespace CSMPrefs
|
||||||
, mActivationStatus(AS_Inactive)
|
, mActivationStatus(AS_Inactive)
|
||||||
, mModifierStatus(false)
|
, mModifierStatus(false)
|
||||||
{
|
{
|
||||||
|
assert (parent);
|
||||||
|
|
||||||
State::get().getShortcutManager().addShortcut(this);
|
State::get().getShortcutManager().addShortcut(this);
|
||||||
ShortcutManager::SequenceData data = State::get().getShortcutManager().getSequence(name);
|
ShortcutManager::SequenceData data = State::get().getShortcutManager().getSequence(name);
|
||||||
setSequence(data.first);
|
setSequence(data.first);
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
class QKeyEvent;
|
class QWidget;
|
||||||
class QMouseEvent;
|
|
||||||
class QShortcut;
|
|
||||||
|
|
||||||
namespace CSMPrefs
|
namespace CSMPrefs
|
||||||
{
|
{
|
||||||
|
@ -34,8 +32,8 @@ namespace CSMPrefs
|
||||||
SM_Ignore ///< The secondary signal will not ever be emitted
|
SM_Ignore ///< The secondary signal will not ever be emitted
|
||||||
};
|
};
|
||||||
|
|
||||||
Shortcut(const std::string& name, QObject* parent);
|
Shortcut(const std::string& name, QWidget* parent);
|
||||||
Shortcut(const std::string& name, SecondaryMode secMode, QObject* parent);
|
Shortcut(const std::string& name, SecondaryMode secMode, QWidget* parent);
|
||||||
|
|
||||||
~Shortcut();
|
~Shortcut();
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "shortcuteventhandler.hpp"
|
#include "shortcuteventhandler.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <cassert>
|
||||||
|
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
@ -19,54 +19,88 @@ namespace CSMPrefs
|
||||||
|
|
||||||
void ShortcutEventHandler::addShortcut(Shortcut* shortcut)
|
void ShortcutEventHandler::addShortcut(Shortcut* shortcut)
|
||||||
{
|
{
|
||||||
mShortcuts.push_back(shortcut);
|
// Enforced by shortcut class
|
||||||
|
QWidget* widget = static_cast<QWidget*>(shortcut->parent());
|
||||||
|
|
||||||
|
// Check if widget setup is needed
|
||||||
|
ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget);
|
||||||
|
if (shortcutListIt == mWidgetShortcuts.end())
|
||||||
|
{
|
||||||
|
// Create list
|
||||||
|
shortcutListIt = mWidgetShortcuts.insert(std::make_pair(widget, ShortcutList())).first;
|
||||||
|
|
||||||
|
// Check if widget has a parent with shortcuts, unfortunately it is not typically set yet
|
||||||
|
updateParent(widget);
|
||||||
|
|
||||||
|
// Intercept widget events
|
||||||
|
widget->installEventFilter(this);
|
||||||
|
connect(widget, SIGNAL(destroyed()), this, SLOT(widgetDestroyed()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to list
|
||||||
|
shortcutListIt->second.push_back(shortcut);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutEventHandler::removeShortcut(Shortcut* shortcut)
|
void ShortcutEventHandler::removeShortcut(Shortcut* shortcut)
|
||||||
{
|
{
|
||||||
std::remove(mShortcuts.begin(), mShortcuts.end(), shortcut);
|
// Enforced by shortcut class
|
||||||
|
QWidget* widget = static_cast<QWidget*>(shortcut->parent());
|
||||||
|
|
||||||
|
ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget);
|
||||||
|
if (shortcutListIt != mWidgetShortcuts.end())
|
||||||
|
{
|
||||||
|
std::remove(shortcutListIt->second.begin(), shortcutListIt->second.end(), shortcut);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShortcutEventHandler::eventFilter(QObject* watched, QEvent* event)
|
bool ShortcutEventHandler::eventFilter(QObject* watched, QEvent* event)
|
||||||
{
|
{
|
||||||
|
// Process event
|
||||||
if (event->type() == QEvent::KeyPress)
|
if (event->type() == QEvent::KeyPress)
|
||||||
{
|
{
|
||||||
|
QWidget* widget = static_cast<QWidget*>(watched);
|
||||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||||
unsigned int mod = (unsigned int) keyEvent->modifiers();
|
unsigned int mod = (unsigned int) keyEvent->modifiers();
|
||||||
unsigned int key = (unsigned int) keyEvent->key();
|
unsigned int key = (unsigned int) keyEvent->key();
|
||||||
|
|
||||||
if (!keyEvent->isAutoRepeat())
|
if (!keyEvent->isAutoRepeat())
|
||||||
return activate(mod, key);
|
return activate(widget, mod, key);
|
||||||
}
|
}
|
||||||
else if (event->type() == QEvent::KeyRelease)
|
else if (event->type() == QEvent::KeyRelease)
|
||||||
{
|
{
|
||||||
|
QWidget* widget = static_cast<QWidget*>(watched);
|
||||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||||
unsigned int mod = (unsigned int) keyEvent->modifiers();
|
unsigned int mod = (unsigned int) keyEvent->modifiers();
|
||||||
unsigned int key = (unsigned int) keyEvent->key();
|
unsigned int key = (unsigned int) keyEvent->key();
|
||||||
|
|
||||||
if (!keyEvent->isAutoRepeat())
|
if (!keyEvent->isAutoRepeat())
|
||||||
return deactivate(mod, key);
|
return deactivate(widget, mod, key);
|
||||||
}
|
}
|
||||||
else if (event->type() == QEvent::MouseButtonPress)
|
else if (event->type() == QEvent::MouseButtonPress)
|
||||||
{
|
{
|
||||||
|
QWidget* widget = static_cast<QWidget*>(watched);
|
||||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||||
unsigned int mod = (unsigned int) mouseEvent->modifiers();
|
unsigned int mod = (unsigned int) mouseEvent->modifiers();
|
||||||
unsigned int button = (unsigned int) mouseEvent->button();
|
unsigned int button = (unsigned int) mouseEvent->button();
|
||||||
|
|
||||||
return activate(mod, button);
|
return activate(widget, mod, button);
|
||||||
}
|
}
|
||||||
else if (event->type() == QEvent::MouseButtonRelease)
|
else if (event->type() == QEvent::MouseButtonRelease)
|
||||||
{
|
{
|
||||||
|
QWidget* widget = static_cast<QWidget*>(watched);
|
||||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||||
unsigned int mod = (unsigned int) mouseEvent->modifiers();
|
unsigned int mod = (unsigned int) mouseEvent->modifiers();
|
||||||
unsigned int button = (unsigned int) mouseEvent->button();
|
unsigned int button = (unsigned int) mouseEvent->button();
|
||||||
|
|
||||||
return deactivate(mod, button);
|
return deactivate(widget, mod, button);
|
||||||
}
|
}
|
||||||
else if (event->type() == QEvent::FocusOut)
|
else if (event->type() == QEvent::FocusOut)
|
||||||
{
|
{
|
||||||
|
QWidget* widget = static_cast<QWidget*>(watched);
|
||||||
|
ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget);
|
||||||
|
|
||||||
// Deactivate in case events are missed
|
// Deactivate in case events are missed
|
||||||
for (std::vector<Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
|
for (ShortcutList::iterator it = shortcutListIt->second.begin(); it != shortcutListIt->second.end(); ++it)
|
||||||
{
|
{
|
||||||
Shortcut* shortcut = *it;
|
Shortcut* shortcut = *it;
|
||||||
|
|
||||||
|
@ -85,41 +119,76 @@ namespace CSMPrefs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (event->type() == QEvent::FocusIn)
|
||||||
|
{
|
||||||
|
QWidget* widget = static_cast<QWidget*>(watched);
|
||||||
|
updateParent(widget);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShortcutEventHandler::activate(unsigned int mod, unsigned int button)
|
void ShortcutEventHandler::updateParent(QWidget* widget)
|
||||||
|
{
|
||||||
|
QWidget* parent = widget->parentWidget();
|
||||||
|
while (parent)
|
||||||
|
{
|
||||||
|
ShortcutMap::iterator parentIt = mWidgetShortcuts.find(parent);
|
||||||
|
if (parentIt != mWidgetShortcuts.end())
|
||||||
|
{
|
||||||
|
mChildParentRelations.insert(std::make_pair(widget, parent));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check next
|
||||||
|
parent = parent->parentWidget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShortcutEventHandler::activate(QWidget* widget, unsigned int mod, unsigned int button)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<MatchResult, Shortcut*> > potentials;
|
std::vector<std::pair<MatchResult, Shortcut*> > potentials;
|
||||||
bool used = false;
|
bool used = false;
|
||||||
|
|
||||||
// Find potential activations
|
while (widget)
|
||||||
for (std::vector<Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
|
|
||||||
{
|
{
|
||||||
Shortcut* shortcut = *it;
|
ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget);
|
||||||
|
assert(shortcutListIt != mWidgetShortcuts.end());
|
||||||
|
|
||||||
if (!shortcut->isEnabled())
|
// Find potential activations
|
||||||
continue;
|
for (ShortcutList::iterator it = shortcutListIt->second.begin(); it != shortcutListIt->second.end(); ++it)
|
||||||
|
|
||||||
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* shortcut = *it;
|
||||||
|
|
||||||
|
if (!shortcut->isEnabled())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (checkModifier(mod, button, shortcut, true))
|
||||||
|
used = true;
|
||||||
|
|
||||||
|
if (shortcut->getActivationStatus() != Shortcut::AS_Inactive)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int pos = shortcut->getPosition();
|
||||||
|
int lastPos = shortcut->getLastPosition();
|
||||||
|
MatchResult result = match(mod, button, shortcut->getSequence()[pos]);
|
||||||
|
|
||||||
|
if (result == Matches_WithMod || result == Matches_NoMod)
|
||||||
{
|
{
|
||||||
shortcut->setPosition(pos+1);
|
if (pos < lastPos && (result == Matches_WithMod || pos > 0))
|
||||||
}
|
{
|
||||||
else if (pos == lastPos)
|
shortcut->setPosition(pos+1);
|
||||||
{
|
}
|
||||||
potentials.push_back(std::make_pair(result, shortcut));
|
else if (pos == lastPos)
|
||||||
|
{
|
||||||
|
potentials.push_back(std::make_pair(result, shortcut));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkModifier(mod, button, shortcut, true))
|
// Move on to parent
|
||||||
used = true;
|
WidgetMap::iterator widgetIt = mChildParentRelations.find(widget);
|
||||||
|
widget = (widgetIt != mChildParentRelations.end()) ? widgetIt->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only activate the best match; in exact conflicts, this will favor the first shortcut added.
|
// Only activate the best match; in exact conflicts, this will favor the first shortcut added.
|
||||||
|
@ -147,39 +216,49 @@ namespace CSMPrefs
|
||||||
return used;
|
return used;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShortcutEventHandler::deactivate(unsigned int mod, unsigned int button)
|
bool ShortcutEventHandler::deactivate(QWidget* widget, unsigned int mod, unsigned int button)
|
||||||
{
|
{
|
||||||
const int KeyMask = 0x01FFFFFF;
|
const int KeyMask = 0x01FFFFFF;
|
||||||
|
|
||||||
bool used = false;
|
bool used = false;
|
||||||
|
|
||||||
for (std::vector<Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
|
while (widget)
|
||||||
{
|
{
|
||||||
Shortcut* shortcut = *it;
|
ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget);
|
||||||
|
assert(shortcutListIt != mWidgetShortcuts.end());
|
||||||
|
|
||||||
if (checkModifier(mod, button, shortcut, false))
|
for (ShortcutList::iterator it = shortcutListIt->second.begin(); it != shortcutListIt->second.end(); ++it)
|
||||||
used = true;
|
|
||||||
|
|
||||||
int pos = shortcut->getPosition();
|
|
||||||
MatchResult result = match(0, button, shortcut->getSequence()[pos] & KeyMask);
|
|
||||||
|
|
||||||
if (result != Matches_Not)
|
|
||||||
{
|
{
|
||||||
shortcut->setPosition(0);
|
Shortcut* shortcut = *it;
|
||||||
|
|
||||||
if (shortcut->getActivationStatus() == Shortcut::AS_Regular)
|
if (checkModifier(mod, button, shortcut, false))
|
||||||
{
|
|
||||||
shortcut->setActivationStatus(Shortcut::AS_Inactive);
|
|
||||||
shortcut->signalActivated(false);
|
|
||||||
used = true;
|
used = true;
|
||||||
}
|
|
||||||
else if (shortcut->getActivationStatus() == Shortcut::AS_Secondary)
|
int pos = shortcut->getPosition();
|
||||||
|
MatchResult result = match(0, button, shortcut->getSequence()[pos] & KeyMask);
|
||||||
|
|
||||||
|
if (result != Matches_Not)
|
||||||
{
|
{
|
||||||
shortcut->setActivationStatus(Shortcut::AS_Inactive);
|
shortcut->setPosition(0);
|
||||||
shortcut->signalSecondary(false);
|
|
||||||
used = true;
|
if (shortcut->getActivationStatus() == Shortcut::AS_Regular)
|
||||||
|
{
|
||||||
|
shortcut->setActivationStatus(Shortcut::AS_Inactive);
|
||||||
|
shortcut->signalActivated(false);
|
||||||
|
used = true;
|
||||||
|
}
|
||||||
|
else if (shortcut->getActivationStatus() == Shortcut::AS_Secondary)
|
||||||
|
{
|
||||||
|
shortcut->setActivationStatus(Shortcut::AS_Inactive);
|
||||||
|
shortcut->signalSecondary(false);
|
||||||
|
used = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move on to parent
|
||||||
|
WidgetMap::iterator widgetIt = mChildParentRelations.find(widget);
|
||||||
|
widget = (widgetIt != mChildParentRelations.end()) ? widgetIt->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return used;
|
return used;
|
||||||
|
@ -187,7 +266,8 @@ namespace CSMPrefs
|
||||||
|
|
||||||
bool ShortcutEventHandler::checkModifier(unsigned int mod, unsigned int button, Shortcut* shortcut, bool activate)
|
bool ShortcutEventHandler::checkModifier(unsigned int mod, unsigned int button, Shortcut* shortcut, bool activate)
|
||||||
{
|
{
|
||||||
if (!shortcut->isEnabled() || !shortcut->getModifier() || shortcut->getSecondaryMode() == Shortcut::SM_Ignore)
|
if (!shortcut->isEnabled() || !shortcut->getModifier() || shortcut->getSecondaryMode() == Shortcut::SM_Ignore ||
|
||||||
|
shortcut->getModifierStatus() == activate)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MatchResult result = match(mod, button, shortcut->getModifier());
|
MatchResult result = match(mod, button, shortcut->getModifier());
|
||||||
|
@ -208,8 +288,6 @@ namespace CSMPrefs
|
||||||
{
|
{
|
||||||
shortcut->signalSecondary(false);
|
shortcut->signalSecondary(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
used = true;
|
|
||||||
}
|
}
|
||||||
else if (!activate && shortcut->getActivationStatus() == Shortcut::AS_Secondary)
|
else if (!activate && shortcut->getActivationStatus() == Shortcut::AS_Secondary)
|
||||||
{
|
{
|
||||||
|
@ -243,9 +321,17 @@ namespace CSMPrefs
|
||||||
bool ShortcutEventHandler::sort(const std::pair<MatchResult, Shortcut*>& left,
|
bool ShortcutEventHandler::sort(const std::pair<MatchResult, Shortcut*>& left,
|
||||||
const std::pair<MatchResult, Shortcut*>& right)
|
const std::pair<MatchResult, Shortcut*>& right)
|
||||||
{
|
{
|
||||||
if (left.first == Matches_WithMod && left.first != right.first)
|
if (left.first == Matches_WithMod && right.first == Matches_NoMod)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return left.second->getPosition() >= right.second->getPosition();
|
return left.second->getPosition() >= right.second->getPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShortcutEventHandler::widgetDestroyed()
|
||||||
|
{
|
||||||
|
QWidget* widget = static_cast<QWidget*>(sender());
|
||||||
|
|
||||||
|
mWidgetShortcuts.erase(widget);
|
||||||
|
mChildParentRelations.erase(widget);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef CSM_PREFS_SHORTCUT_EVENT_HANDLER_H
|
#ifndef CSM_PREFS_SHORTCUT_EVENT_HANDLER_H
|
||||||
#define CSM_PREFS_SHORTCUT_EVENT_HANDLER_H
|
#define CSM_PREFS_SHORTCUT_EVENT_HANDLER_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
@ -19,7 +20,7 @@ namespace CSMPrefs
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ShortcutEventHandler(QObject* parent=0);
|
ShortcutEventHandler(QObject* parent);
|
||||||
|
|
||||||
void addShortcut(Shortcut* shortcut);
|
void addShortcut(Shortcut* shortcut);
|
||||||
void removeShortcut(Shortcut* shortcut);
|
void removeShortcut(Shortcut* shortcut);
|
||||||
|
@ -30,6 +31,11 @@ namespace CSMPrefs
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
typedef std::vector<Shortcut*> ShortcutList;
|
||||||
|
// Child, Parent
|
||||||
|
typedef std::map<QWidget*, QWidget*> WidgetMap;
|
||||||
|
typedef std::map<QWidget*, ShortcutList> ShortcutMap;
|
||||||
|
|
||||||
enum MatchResult
|
enum MatchResult
|
||||||
{
|
{
|
||||||
Matches_WithMod,
|
Matches_WithMod,
|
||||||
|
@ -37,9 +43,11 @@ namespace CSMPrefs
|
||||||
Matches_Not
|
Matches_Not
|
||||||
};
|
};
|
||||||
|
|
||||||
bool activate(unsigned int mod, unsigned int button);
|
void updateParent(QWidget* widget);
|
||||||
|
|
||||||
bool deactivate(unsigned int mod, unsigned int button);
|
bool activate(QWidget* widget, unsigned int mod, unsigned int button);
|
||||||
|
|
||||||
|
bool deactivate(QWidget* widget, unsigned int mod, unsigned int button);
|
||||||
|
|
||||||
bool checkModifier(unsigned int mod, unsigned int button, Shortcut* shortcut, bool activate);
|
bool checkModifier(unsigned int mod, unsigned int button, Shortcut* shortcut, bool activate);
|
||||||
|
|
||||||
|
@ -49,7 +57,12 @@ namespace CSMPrefs
|
||||||
static bool sort(const std::pair<MatchResult, Shortcut*>& left,
|
static bool sort(const std::pair<MatchResult, Shortcut*>& left,
|
||||||
const std::pair<MatchResult, Shortcut*>& right);
|
const std::pair<MatchResult, Shortcut*>& right);
|
||||||
|
|
||||||
std::vector<Shortcut*> mShortcuts;
|
WidgetMap mChildParentRelations;
|
||||||
|
ShortcutMap mWidgetShortcuts;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void widgetDestroyed();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,25 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
#include "shortcut.hpp"
|
#include "shortcut.hpp"
|
||||||
|
#include "shortcuteventhandler.hpp"
|
||||||
|
|
||||||
namespace CSMPrefs
|
namespace CSMPrefs
|
||||||
{
|
{
|
||||||
|
ShortcutManager::ShortcutManager()
|
||||||
|
{
|
||||||
|
mEventHandler = new ShortcutEventHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
void ShortcutManager::addShortcut(Shortcut* shortcut)
|
void ShortcutManager::addShortcut(Shortcut* shortcut)
|
||||||
{
|
{
|
||||||
mShortcuts.insert(std::make_pair(shortcut->getName(), shortcut));
|
mShortcuts.insert(std::make_pair(shortcut->getName(), shortcut));
|
||||||
|
mEventHandler->addShortcut(shortcut);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortcutManager::removeShortcut(Shortcut* shortcut)
|
void ShortcutManager::removeShortcut(Shortcut* shortcut)
|
||||||
|
@ -31,6 +39,8 @@ namespace CSMPrefs
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mEventHandler->removeShortcut(shortcut);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShortcutManager::SequenceData ShortcutManager::getSequence(const std::string& name) const
|
ShortcutManager::SequenceData ShortcutManager::getSequence(const std::string& name) const
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
namespace CSMPrefs
|
namespace CSMPrefs
|
||||||
{
|
{
|
||||||
class Shortcut;
|
class Shortcut;
|
||||||
|
class ShortcutEventHandler;
|
||||||
|
|
||||||
/// Class used to track and update shortcuts/sequences
|
/// Class used to track and update shortcuts/sequences
|
||||||
class ShortcutManager : public QObject
|
class ShortcutManager : public QObject
|
||||||
|
@ -20,6 +21,9 @@ namespace CSMPrefs
|
||||||
/// Key Sequence, Modifier (for secondary signal)
|
/// Key Sequence, Modifier (for secondary signal)
|
||||||
typedef std::pair<QKeySequence, int> SequenceData;
|
typedef std::pair<QKeySequence, int> SequenceData;
|
||||||
|
|
||||||
|
|
||||||
|
ShortcutManager();
|
||||||
|
|
||||||
/// The shortcut class will do this automatically
|
/// The shortcut class will do this automatically
|
||||||
void addShortcut(Shortcut* shortcut);
|
void addShortcut(Shortcut* shortcut);
|
||||||
|
|
||||||
|
@ -40,6 +44,8 @@ namespace CSMPrefs
|
||||||
|
|
||||||
ShortcutMap mShortcuts;
|
ShortcutMap mShortcuts;
|
||||||
SequenceMap mSequences;
|
SequenceMap mSequences;
|
||||||
|
|
||||||
|
ShortcutEventHandler* mEventHandler;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -229,6 +229,10 @@ void CSMPrefs::State::declare()
|
||||||
addValues (insertOutsideVisibleCell);
|
addValues (insertOutsideVisibleCell);
|
||||||
|
|
||||||
declareCategory ("Key Bindings");
|
declareCategory ("Key Bindings");
|
||||||
|
|
||||||
|
declareShortcut ("document-save", "Save", QKeySequence(Qt::ControlModifier | Qt::Key_S));
|
||||||
|
|
||||||
|
declareSeparator ();
|
||||||
declareShortcut ("free-forward", "Free camera forward", QKeySequence(Qt::Key_W), Qt::Key_Shift);
|
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-backward", "Free camera backward", QKeySequence(Qt::Key_S));
|
||||||
declareShortcut ("free-left", "Free camera left", QKeySequence(Qt::Key_A));
|
declareShortcut ("free-left", "Free camera left", QKeySequence(Qt::Key_A));
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "../../model/doc/document.hpp"
|
#include "../../model/doc/document.hpp"
|
||||||
#include "../../model/prefs/state.hpp"
|
#include "../../model/prefs/state.hpp"
|
||||||
|
#include "../../model/prefs/shortcut.hpp"
|
||||||
|
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
|
@ -62,6 +63,9 @@ void CSVDoc::View::setupFileMenu()
|
||||||
connect (mSave, SIGNAL (triggered()), this, SLOT (save()));
|
connect (mSave, SIGNAL (triggered()), this, SLOT (save()));
|
||||||
file->addAction (mSave);
|
file->addAction (mSave);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* saveShortcut = new CSMPrefs::Shortcut("document-save", this);
|
||||||
|
connect (saveShortcut, SIGNAL(activated()), this, SLOT(save()));
|
||||||
|
|
||||||
mVerify = new QAction (tr ("&Verify"), this);
|
mVerify = new QAction (tr ("&Verify"), this);
|
||||||
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
|
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
|
||||||
file->addAction (mVerify);
|
file->addAction (mVerify);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include <QKeyEvent>
|
#include <QWidget>
|
||||||
|
|
||||||
#include <osg/BoundingBox>
|
#include <osg/BoundingBox>
|
||||||
#include <osg/Camera>
|
#include <osg/Camera>
|
||||||
|
@ -15,7 +15,6 @@
|
||||||
#include <osgUtil/LineSegmentIntersector>
|
#include <osgUtil/LineSegmentIntersector>
|
||||||
|
|
||||||
#include "../../model/prefs/shortcut.hpp"
|
#include "../../model/prefs/shortcut.hpp"
|
||||||
#include "../../model/prefs/shortcuteventhandler.hpp"
|
|
||||||
|
|
||||||
#include "scenewidget.hpp"
|
#include "scenewidget.hpp"
|
||||||
|
|
||||||
|
@ -79,27 +78,17 @@ namespace CSVRender
|
||||||
|
|
||||||
void CameraController::setCamera(osg::Camera* camera)
|
void CameraController::setCamera(osg::Camera* camera)
|
||||||
{
|
{
|
||||||
|
bool wasActive = mActive;
|
||||||
|
|
||||||
mCamera = camera;
|
mCamera = camera;
|
||||||
mActive = (mCamera != NULL);
|
mActive = (mCamera != NULL);
|
||||||
|
|
||||||
if (mActive)
|
if (mActive != wasActive)
|
||||||
{
|
{
|
||||||
onActivate();
|
for (std::vector<CSMPrefs::Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
|
||||||
|
|
||||||
QList<CSMPrefs::Shortcut*> shortcuts = findChildren<CSMPrefs::Shortcut*>();
|
|
||||||
|
|
||||||
for (QList<CSMPrefs::Shortcut*>::iterator it = shortcuts.begin(); it != shortcuts.end(); ++it)
|
|
||||||
{
|
{
|
||||||
(*it)->enable(true);
|
CSMPrefs::Shortcut* shortcut = *it;
|
||||||
}
|
shortcut->enable(mActive);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QList<CSMPrefs::Shortcut*> shortcuts = findChildren<CSMPrefs::Shortcut*>();
|
|
||||||
|
|
||||||
for (QList<CSMPrefs::Shortcut*>::iterator it = shortcuts.begin(); it != shortcuts.end(); ++it)
|
|
||||||
{
|
|
||||||
(*it)->enable(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,14 +149,21 @@ namespace CSVRender
|
||||||
getCamera()->setViewMatrixAsLookAt(eye, center, up);
|
getCamera()->setViewMatrixAsLookAt(eye, center, up);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CameraController::addShortcut(CSMPrefs::Shortcut* shortcut)
|
||||||
|
{
|
||||||
|
mShortcuts.push_back(shortcut);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Free Camera Controller
|
Free Camera Controller
|
||||||
*/
|
*/
|
||||||
|
|
||||||
FreeCameraController::FreeCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent)
|
FreeCameraController::FreeCameraController(QWidget* widget)
|
||||||
: CameraController(parent)
|
: CameraController(widget)
|
||||||
, mLockUpright(false)
|
, mLockUpright(false)
|
||||||
, mModified(false)
|
, mModified(false)
|
||||||
|
, mNaviPrimary(false)
|
||||||
|
, mNaviSecondary(false)
|
||||||
, mFast(false)
|
, mFast(false)
|
||||||
, mFastAlternate(false)
|
, mFastAlternate(false)
|
||||||
, mLeft(false)
|
, mLeft(false)
|
||||||
|
@ -181,52 +177,61 @@ namespace CSVRender
|
||||||
, mRotSpeed(osg::PI / 2)
|
, mRotSpeed(osg::PI / 2)
|
||||||
, mSpeedMult(8)
|
, mSpeedMult(8)
|
||||||
{
|
{
|
||||||
CSMPrefs::Shortcut* naviPrimaryShortcut = new CSMPrefs::Shortcut("scene-navi-primary", this);
|
CSMPrefs::Shortcut* naviPrimaryShortcut = new CSMPrefs::Shortcut("scene-navi-primary", widget);
|
||||||
naviPrimaryShortcut->enable(false);
|
naviPrimaryShortcut->enable(false);
|
||||||
handler->addShortcut(naviPrimaryShortcut);
|
|
||||||
connect(naviPrimaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviPrimary(bool)));
|
connect(naviPrimaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviPrimary(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* naviSecondaryShortcut = new CSMPrefs::Shortcut("scene-navi-secondary", this);
|
addShortcut(naviPrimaryShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* naviSecondaryShortcut = new CSMPrefs::Shortcut("scene-navi-secondary", widget);
|
||||||
naviSecondaryShortcut->enable(false);
|
naviSecondaryShortcut->enable(false);
|
||||||
handler->addShortcut(naviSecondaryShortcut);
|
|
||||||
connect(naviSecondaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviSecondary(bool)));
|
connect(naviSecondaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviSecondary(bool)));
|
||||||
|
|
||||||
|
addShortcut(naviSecondaryShortcut);
|
||||||
|
|
||||||
CSMPrefs::Shortcut* forwardShortcut = new CSMPrefs::Shortcut("free-forward", CSMPrefs::Shortcut::SM_Detach,
|
CSMPrefs::Shortcut* forwardShortcut = new CSMPrefs::Shortcut("free-forward", CSMPrefs::Shortcut::SM_Detach,
|
||||||
this);
|
widget);
|
||||||
forwardShortcut->enable(false);
|
forwardShortcut->enable(false);
|
||||||
handler->addShortcut(forwardShortcut);
|
|
||||||
connect(forwardShortcut, SIGNAL(activated(bool)), this, SLOT(forward(bool)));
|
connect(forwardShortcut, SIGNAL(activated(bool)), this, SLOT(forward(bool)));
|
||||||
connect(forwardShortcut, SIGNAL(secondary(bool)), this, SLOT(alternateFast(bool)));
|
connect(forwardShortcut, SIGNAL(secondary(bool)), this, SLOT(alternateFast(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("free-left", this);
|
addShortcut(forwardShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("free-left", widget);
|
||||||
leftShortcut->enable(false);
|
leftShortcut->enable(false);
|
||||||
handler->addShortcut(leftShortcut);
|
|
||||||
connect(leftShortcut, SIGNAL(activated(bool)), this, SLOT(left(bool)));
|
connect(leftShortcut, SIGNAL(activated(bool)), this, SLOT(left(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* backShortcut = new CSMPrefs::Shortcut("free-backward", this);
|
addShortcut(leftShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* backShortcut = new CSMPrefs::Shortcut("free-backward", widget);
|
||||||
backShortcut->enable(false);
|
backShortcut->enable(false);
|
||||||
handler->addShortcut(backShortcut);
|
|
||||||
connect(backShortcut, SIGNAL(activated(bool)), this, SLOT(backward(bool)));
|
connect(backShortcut, SIGNAL(activated(bool)), this, SLOT(backward(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* rightShortcut = new CSMPrefs::Shortcut("free-right", this);
|
addShortcut(backShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* rightShortcut = new CSMPrefs::Shortcut("free-right", widget);
|
||||||
rightShortcut->enable(false);
|
rightShortcut->enable(false);
|
||||||
handler->addShortcut(rightShortcut);
|
|
||||||
connect(rightShortcut, SIGNAL(activated(bool)), this, SLOT(right(bool)));
|
connect(rightShortcut, SIGNAL(activated(bool)), this, SLOT(right(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* rollLeftShortcut = new CSMPrefs::Shortcut("free-roll-left", this);
|
addShortcut(rightShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* rollLeftShortcut = new CSMPrefs::Shortcut("free-roll-left", widget);
|
||||||
rollLeftShortcut->enable(false);
|
rollLeftShortcut->enable(false);
|
||||||
handler->addShortcut(rollLeftShortcut);
|
|
||||||
connect(rollLeftShortcut, SIGNAL(activated(bool)), this, SLOT(rollLeft(bool)));
|
connect(rollLeftShortcut, SIGNAL(activated(bool)), this, SLOT(rollLeft(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* rollRightShortcut = new CSMPrefs::Shortcut("free-roll-right", this);
|
addShortcut(rollLeftShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* rollRightShortcut = new CSMPrefs::Shortcut("free-roll-right", widget);
|
||||||
rollRightShortcut->enable(false);
|
rollRightShortcut->enable(false);
|
||||||
handler->addShortcut(rollRightShortcut);
|
|
||||||
connect(rollRightShortcut, SIGNAL(activated(bool)), this, SLOT(rollRight(bool)));
|
connect(rollRightShortcut, SIGNAL(activated(bool)), this, SLOT(rollRight(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("free-speed-mode", this);
|
addShortcut(rollRightShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("free-speed-mode", widget);
|
||||||
speedModeShortcut->enable(false);
|
speedModeShortcut->enable(false);
|
||||||
handler->addShortcut(speedModeShortcut);
|
|
||||||
connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
|
connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
|
||||||
|
|
||||||
|
addShortcut(speedModeShortcut);
|
||||||
}
|
}
|
||||||
|
|
||||||
double FreeCameraController::getLinearSpeed() const
|
double FreeCameraController::getLinearSpeed() const
|
||||||
|
@ -440,9 +445,11 @@ namespace CSVRender
|
||||||
Orbit Camera Controller
|
Orbit Camera Controller
|
||||||
*/
|
*/
|
||||||
|
|
||||||
OrbitCameraController::OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent)
|
OrbitCameraController::OrbitCameraController(QWidget* widget)
|
||||||
: CameraController(parent)
|
: CameraController(widget)
|
||||||
, mInitialized(false)
|
, mInitialized(false)
|
||||||
|
, mNaviPrimary(false)
|
||||||
|
, mNaviSecondary(false)
|
||||||
, mFast(false)
|
, mFast(false)
|
||||||
, mFastAlternate(false)
|
, mFastAlternate(false)
|
||||||
, mLeft(false)
|
, mLeft(false)
|
||||||
|
@ -457,51 +464,60 @@ namespace CSVRender
|
||||||
, mOrbitSpeed(osg::PI / 4)
|
, mOrbitSpeed(osg::PI / 4)
|
||||||
, mOrbitSpeedMult(4)
|
, mOrbitSpeedMult(4)
|
||||||
{
|
{
|
||||||
CSMPrefs::Shortcut* naviPrimaryShortcut = new CSMPrefs::Shortcut("scene-navi-primary", this);
|
CSMPrefs::Shortcut* naviPrimaryShortcut = new CSMPrefs::Shortcut("scene-navi-primary", widget);
|
||||||
naviPrimaryShortcut->enable(false);
|
naviPrimaryShortcut->enable(false);
|
||||||
handler->addShortcut(naviPrimaryShortcut);
|
|
||||||
connect(naviPrimaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviPrimary(bool)));
|
connect(naviPrimaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviPrimary(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* naviSecondaryShortcut = new CSMPrefs::Shortcut("scene-navi-secondary", this);
|
addShortcut(naviPrimaryShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* naviSecondaryShortcut = new CSMPrefs::Shortcut("scene-navi-secondary", widget);
|
||||||
naviSecondaryShortcut->enable(false);
|
naviSecondaryShortcut->enable(false);
|
||||||
handler->addShortcut(naviSecondaryShortcut);
|
|
||||||
connect(naviSecondaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviSecondary(bool)));
|
connect(naviSecondaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviSecondary(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* upShortcut = new CSMPrefs::Shortcut("orbit-up", CSMPrefs::Shortcut::SM_Detach, this);
|
addShortcut(naviSecondaryShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* upShortcut = new CSMPrefs::Shortcut("orbit-up", CSMPrefs::Shortcut::SM_Detach, widget);
|
||||||
upShortcut->enable(false);
|
upShortcut->enable(false);
|
||||||
handler->addShortcut(upShortcut);
|
|
||||||
connect(upShortcut, SIGNAL(activated(bool)), this, SLOT(up(bool)));
|
connect(upShortcut, SIGNAL(activated(bool)), this, SLOT(up(bool)));
|
||||||
connect(upShortcut, SIGNAL(secondary(bool)), this, SLOT(alternateFast(bool)));
|
connect(upShortcut, SIGNAL(secondary(bool)), this, SLOT(alternateFast(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("orbit-left", this);
|
addShortcut(upShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("orbit-left", widget);
|
||||||
leftShortcut->enable(false);
|
leftShortcut->enable(false);
|
||||||
handler->addShortcut(leftShortcut);
|
|
||||||
connect(leftShortcut, SIGNAL(activated(bool)), this, SLOT(left(bool)));
|
connect(leftShortcut, SIGNAL(activated(bool)), this, SLOT(left(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* downShortcut = new CSMPrefs::Shortcut("orbit-down", this);
|
addShortcut(leftShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* downShortcut = new CSMPrefs::Shortcut("orbit-down", widget);
|
||||||
downShortcut->enable(false);
|
downShortcut->enable(false);
|
||||||
handler->addShortcut(downShortcut);
|
|
||||||
connect(downShortcut, SIGNAL(activated(bool)), this, SLOT(down(bool)));
|
connect(downShortcut, SIGNAL(activated(bool)), this, SLOT(down(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* rightShortcut = new CSMPrefs::Shortcut("orbit-right", this);
|
addShortcut(downShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* rightShortcut = new CSMPrefs::Shortcut("orbit-right", widget);
|
||||||
rightShortcut->enable(false);
|
rightShortcut->enable(false);
|
||||||
handler->addShortcut(rightShortcut);
|
|
||||||
connect(rightShortcut, SIGNAL(activated(bool)), this, SLOT(right(bool)));
|
connect(rightShortcut, SIGNAL(activated(bool)), this, SLOT(right(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* rollLeftShortcut = new CSMPrefs::Shortcut("orbit-roll-left", this);
|
addShortcut(rightShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* rollLeftShortcut = new CSMPrefs::Shortcut("orbit-roll-left", widget);
|
||||||
rollLeftShortcut->enable(false);
|
rollLeftShortcut->enable(false);
|
||||||
handler->addShortcut(rollLeftShortcut);
|
|
||||||
connect(rollLeftShortcut, SIGNAL(activated(bool)), this, SLOT(rollLeft(bool)));
|
connect(rollLeftShortcut, SIGNAL(activated(bool)), this, SLOT(rollLeft(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* rollRightShortcut = new CSMPrefs::Shortcut("orbit-roll-right", this);
|
addShortcut(rollLeftShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* rollRightShortcut = new CSMPrefs::Shortcut("orbit-roll-right", widget);
|
||||||
rollRightShortcut->enable(false);
|
rollRightShortcut->enable(false);
|
||||||
handler->addShortcut(rollRightShortcut);
|
|
||||||
connect(rollRightShortcut, SIGNAL(activated(bool)), this, SLOT(rollRight(bool)));
|
connect(rollRightShortcut, SIGNAL(activated(bool)), this, SLOT(rollRight(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("orbit-speed-mode", this);
|
addShortcut(rollRightShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("orbit-speed-mode", widget);
|
||||||
speedModeShortcut->enable(false);
|
speedModeShortcut->enable(false);
|
||||||
handler->addShortcut(speedModeShortcut);
|
|
||||||
connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
|
connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
|
||||||
|
|
||||||
|
addShortcut(speedModeShortcut);
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3d OrbitCameraController::getCenter() const
|
osg::Vec3d OrbitCameraController::getCenter() const
|
||||||
|
|
|
@ -2,14 +2,13 @@
|
||||||
#define OPENCS_VIEW_CAMERACONTROLLER_H
|
#define OPENCS_VIEW_CAMERACONTROLLER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
#include <osg/Vec3d>
|
#include <osg/Vec3d>
|
||||||
|
|
||||||
class QKeyEvent;
|
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
class Camera;
|
class Camera;
|
||||||
|
@ -18,7 +17,7 @@ namespace osg
|
||||||
|
|
||||||
namespace CSMPrefs
|
namespace CSMPrefs
|
||||||
{
|
{
|
||||||
class ShortcutEventHandler;
|
class Shortcut;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
|
@ -66,6 +65,8 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual void onActivate(){}
|
virtual void onActivate(){}
|
||||||
|
|
||||||
|
void addShortcut(CSMPrefs::Shortcut* shortcut);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool mActive, mInverted;
|
bool mActive, mInverted;
|
||||||
|
@ -74,6 +75,8 @@ namespace CSVRender
|
||||||
double mWheelMoveMult;
|
double mWheelMoveMult;
|
||||||
|
|
||||||
osg::Camera* mCamera;
|
osg::Camera* mCamera;
|
||||||
|
|
||||||
|
std::vector<CSMPrefs::Shortcut*> mShortcuts;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FreeCameraController : public CameraController
|
class FreeCameraController : public CameraController
|
||||||
|
@ -82,7 +85,7 @@ namespace CSVRender
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FreeCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent=0);
|
FreeCameraController(QWidget* parent);
|
||||||
|
|
||||||
double getLinearSpeed() const;
|
double getLinearSpeed() const;
|
||||||
double getRotationalSpeed() const;
|
double getRotationalSpeed() const;
|
||||||
|
@ -139,7 +142,7 @@ namespace CSVRender
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent=0);
|
OrbitCameraController(QWidget* parent);
|
||||||
|
|
||||||
osg::Vec3d getCenter() const;
|
osg::Vec3d getCenter() const;
|
||||||
double getOrbitSpeed() const;
|
double getOrbitSpeed() const;
|
||||||
|
|
|
@ -9,22 +9,19 @@
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
{
|
{
|
||||||
OrbitCameraMode::OrbitCameraMode(WorldspaceWidget* worldspaceWidget, CSMPrefs::ShortcutEventHandler* handler,
|
OrbitCameraMode::OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip,
|
||||||
const QIcon& icon, const QString& tooltip, QWidget* parent)
|
QWidget* parent)
|
||||||
: ModeButton(icon, tooltip, parent)
|
: ModeButton(icon, tooltip, parent)
|
||||||
, mWorldspaceWidget(worldspaceWidget)
|
, mWorldspaceWidget(worldspaceWidget)
|
||||||
, mShortcutHandler(handler)
|
|
||||||
, mCenterOnSelection(0)
|
, mCenterOnSelection(0)
|
||||||
{
|
{
|
||||||
mCenterShortcut = new CSMPrefs::Shortcut("orbit-center-selection", this);
|
mCenterShortcut.reset(new CSMPrefs::Shortcut("orbit-center-selection", worldspaceWidget));
|
||||||
mCenterShortcut->enable(false);
|
mCenterShortcut->enable(false);
|
||||||
mShortcutHandler->addShortcut(mCenterShortcut);
|
connect(mCenterShortcut.get(), SIGNAL(activated()), this, SLOT(centerSelection()));
|
||||||
connect(mCenterShortcut, SIGNAL(activated()), this, SLOT(centerSelection()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OrbitCameraMode::~OrbitCameraMode()
|
OrbitCameraMode::~OrbitCameraMode()
|
||||||
{
|
{
|
||||||
mShortcutHandler->removeShortcut(mCenterShortcut);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OrbitCameraMode::activate(CSVWidget::SceneToolbar* toolbar)
|
void OrbitCameraMode::activate(CSVWidget::SceneToolbar* toolbar)
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#ifndef CSV_RENDER_ORBITCAMERAPICKMODE_H
|
#ifndef CSV_RENDER_ORBITCAMERAPICKMODE_H
|
||||||
#define CSV_RENDER_ORBITCAMERAPICKMODE_H
|
#define CSV_RENDER_ORBITCAMERAPICKMODE_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "../widget/modebutton.hpp"
|
#include "../widget/modebutton.hpp"
|
||||||
|
|
||||||
namespace CSMPrefs
|
namespace CSMPrefs
|
||||||
{
|
{
|
||||||
class Shortcut;
|
class Shortcut;
|
||||||
class ShortcutEventHandler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
|
@ -19,8 +20,8 @@ namespace CSVRender
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
OrbitCameraMode(WorldspaceWidget* worldspaceWidget, CSMPrefs::ShortcutEventHandler* shortcutHandler,
|
OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip = "",
|
||||||
const QIcon& icon, const QString& tooltip = "", QWidget* parent = 0);
|
QWidget* parent = 0);
|
||||||
~OrbitCameraMode();
|
~OrbitCameraMode();
|
||||||
|
|
||||||
virtual void activate(CSVWidget::SceneToolbar* toolbar);
|
virtual void activate(CSVWidget::SceneToolbar* toolbar);
|
||||||
|
@ -30,9 +31,8 @@ namespace CSVRender
|
||||||
private:
|
private:
|
||||||
|
|
||||||
WorldspaceWidget* mWorldspaceWidget;
|
WorldspaceWidget* mWorldspaceWidget;
|
||||||
CSMPrefs::ShortcutEventHandler* mShortcutHandler;
|
|
||||||
QAction* mCenterOnSelection;
|
QAction* mCenterOnSelection;
|
||||||
CSMPrefs::Shortcut* mCenterShortcut;
|
std::auto_ptr<CSMPrefs::Shortcut> mCenterShortcut;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
|
|
@ -171,11 +171,8 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
|
||||||
, mPrevMouseY(0)
|
, mPrevMouseY(0)
|
||||||
, mCamPositionSet(false)
|
, mCamPositionSet(false)
|
||||||
{
|
{
|
||||||
mShortcutHandler = new CSMPrefs::ShortcutEventHandler(this);
|
mFreeCamControl = new FreeCameraController(this);
|
||||||
installEventFilter(mShortcutHandler);
|
mOrbitCamControl = new OrbitCameraController(this);
|
||||||
|
|
||||||
mFreeCamControl = new FreeCameraController(mShortcutHandler, this);
|
|
||||||
mOrbitCamControl = new OrbitCameraController(mShortcutHandler, this);
|
|
||||||
mCurrentCamControl = mFreeCamControl;
|
mCurrentCamControl = mFreeCamControl;
|
||||||
|
|
||||||
mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain);
|
mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain);
|
||||||
|
@ -205,18 +202,14 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
|
||||||
|
|
||||||
// Shortcuts
|
// Shortcuts
|
||||||
CSMPrefs::Shortcut* focusToolbarShortcut = new CSMPrefs::Shortcut("scene-focus-toolbar", this);
|
CSMPrefs::Shortcut* focusToolbarShortcut = new CSMPrefs::Shortcut("scene-focus-toolbar", this);
|
||||||
mShortcutHandler->addShortcut(focusToolbarShortcut);
|
|
||||||
connect(focusToolbarShortcut, SIGNAL(activated()), this, SIGNAL(focusToolbarRequest()));
|
connect(focusToolbarShortcut, SIGNAL(activated()), this, SIGNAL(focusToolbarRequest()));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* renderStatsShortcut = new CSMPrefs::Shortcut("scene-render-stats", this);
|
CSMPrefs::Shortcut* renderStatsShortcut = new CSMPrefs::Shortcut("scene-render-stats", this);
|
||||||
mShortcutHandler->addShortcut(renderStatsShortcut);
|
|
||||||
connect(renderStatsShortcut, SIGNAL(activated()), this, SLOT(toggleRenderStats()));
|
connect(renderStatsShortcut, SIGNAL(activated()), this, SLOT(toggleRenderStats()));
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneWidget::~SceneWidget()
|
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
|
// 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());
|
mResourceSystem->getSceneManager()->releaseGLObjects(mView->getCamera()->getGraphicsContext()->getState());
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,6 @@ namespace CSVWidget
|
||||||
namespace CSMPrefs
|
namespace CSMPrefs
|
||||||
{
|
{
|
||||||
class Setting;
|
class Setting;
|
||||||
class Shortcut;
|
|
||||||
class ShortcutEventHandler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
|
@ -116,8 +114,6 @@ namespace CSVRender
|
||||||
OrbitCameraController* mOrbitCamControl;
|
OrbitCameraController* mOrbitCamControl;
|
||||||
CameraController* mCurrentCamControl;
|
CameraController* mCurrentCamControl;
|
||||||
|
|
||||||
CSMPrefs::ShortcutEventHandler *mShortcutHandler;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mCamPositionSet;
|
bool mCamPositionSet;
|
||||||
|
|
||||||
|
|
|
@ -98,23 +98,18 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg
|
||||||
|
|
||||||
// Shortcuts
|
// Shortcuts
|
||||||
CSMPrefs::Shortcut* primaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-primary", this);
|
CSMPrefs::Shortcut* primaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-primary", this);
|
||||||
mShortcutHandler->addShortcut(primaryEditShortcut);
|
|
||||||
connect(primaryEditShortcut, SIGNAL(activated(bool)), this, SLOT(primaryEdit(bool)));
|
connect(primaryEditShortcut, SIGNAL(activated(bool)), this, SLOT(primaryEdit(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* secondaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-secondary", this);
|
CSMPrefs::Shortcut* secondaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-secondary", this);
|
||||||
mShortcutHandler->addShortcut(secondaryEditShortcut);
|
|
||||||
connect(secondaryEditShortcut, SIGNAL(activated(bool)), this, SLOT(secondaryEdit(bool)));
|
connect(secondaryEditShortcut, SIGNAL(activated(bool)), this, SLOT(secondaryEdit(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* primarySelectShortcut = new CSMPrefs::Shortcut("scene-select-primary", this);
|
CSMPrefs::Shortcut* primarySelectShortcut = new CSMPrefs::Shortcut("scene-select-primary", this);
|
||||||
mShortcutHandler->addShortcut(primarySelectShortcut);
|
|
||||||
connect(primarySelectShortcut, SIGNAL(activated(bool)), this, SLOT(primarySelect(bool)));
|
connect(primarySelectShortcut, SIGNAL(activated(bool)), this, SLOT(primarySelect(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* secondarySelectShortcut = new CSMPrefs::Shortcut("scene-select-secondary", this);
|
CSMPrefs::Shortcut* secondarySelectShortcut = new CSMPrefs::Shortcut("scene-select-secondary", this);
|
||||||
mShortcutHandler->addShortcut(secondarySelectShortcut);
|
|
||||||
connect(secondarySelectShortcut, SIGNAL(activated(bool)), this, SLOT(secondarySelect(bool)));
|
connect(secondarySelectShortcut, SIGNAL(activated(bool)), this, SLOT(secondarySelect(bool)));
|
||||||
|
|
||||||
CSMPrefs::Shortcut* abortShortcut = new CSMPrefs::Shortcut("scene-edit-abort", this);
|
CSMPrefs::Shortcut* abortShortcut = new CSMPrefs::Shortcut("scene-edit-abort", this);
|
||||||
mShortcutHandler->addShortcut(abortShortcut);
|
|
||||||
connect(abortShortcut, SIGNAL(activated()), this, SLOT(abortDrag()));
|
connect(abortShortcut, SIGNAL(activated()), this, SLOT(abortDrag()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +179,7 @@ CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector (
|
||||||
"<li>Hold shift to speed up movement</li>"
|
"<li>Hold shift to speed up movement</li>"
|
||||||
"</ul>");
|
"</ul>");
|
||||||
tool->addButton(
|
tool->addButton(
|
||||||
new CSVRender::OrbitCameraMode(this, mShortcutHandler, QIcon(":scenetoolbar/orbiting-camera"),
|
new CSVRender::OrbitCameraMode(this, QIcon(":scenetoolbar/orbiting-camera"),
|
||||||
"Orbiting Camera"
|
"Orbiting Camera"
|
||||||
"<ul><li>Always facing the centre point</li>"
|
"<ul><li>Always facing the centre point</li>"
|
||||||
"<li>Rotate around the centre point via WASD or by moving the mouse while holding the left button</li>"
|
"<li>Rotate around the centre point via WASD or by moving the mouse while holding the left button</li>"
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
namespace CSMPrefs
|
namespace CSMPrefs
|
||||||
{
|
{
|
||||||
class Setting;
|
class Setting;
|
||||||
class Shortcut;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
|
|
Loading…
Reference in a new issue