mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 08:23:53 +00:00
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 <QKeyEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QShortcut>
|
||||
#include <cassert>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "state.hpp"
|
||||
#include "shortcutmanager.hpp"
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
Shortcut::Shortcut(const std::string& name, QObject* parent)
|
||||
Shortcut::Shortcut(const std::string& name, QWidget* parent)
|
||||
: QObject(parent)
|
||||
, mEnabled(true)
|
||||
, mName(name)
|
||||
|
@ -20,13 +20,15 @@ namespace CSMPrefs
|
|||
, mActivationStatus(AS_Inactive)
|
||||
, mModifierStatus(false)
|
||||
{
|
||||
assert (parent);
|
||||
|
||||
State::get().getShortcutManager().addShortcut(this);
|
||||
ShortcutManager::SequenceData data = State::get().getShortcutManager().getSequence(name);
|
||||
setSequence(data.first);
|
||||
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)
|
||||
, mEnabled(true)
|
||||
, mName(name)
|
||||
|
@ -37,6 +39,8 @@ namespace CSMPrefs
|
|||
, mActivationStatus(AS_Inactive)
|
||||
, mModifierStatus(false)
|
||||
{
|
||||
assert (parent);
|
||||
|
||||
State::get().getShortcutManager().addShortcut(this);
|
||||
ShortcutManager::SequenceData data = State::get().getShortcutManager().getSequence(name);
|
||||
setSequence(data.first);
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class QKeyEvent;
|
||||
class QMouseEvent;
|
||||
class QShortcut;
|
||||
class QWidget;
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
|
@ -34,8 +32,8 @@ namespace CSMPrefs
|
|||
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(const std::string& name, QWidget* parent);
|
||||
Shortcut(const std::string& name, SecondaryMode secMode, QWidget* parent);
|
||||
|
||||
~Shortcut();
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "shortcuteventhandler.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
#include <QEvent>
|
||||
#include <QKeyEvent>
|
||||
|
@ -19,54 +19,88 @@ namespace CSMPrefs
|
|||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// Process event
|
||||
if (event->type() == QEvent::KeyPress)
|
||||
{
|
||||
QWidget* widget = static_cast<QWidget*>(watched);
|
||||
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);
|
||||
return activate(widget, mod, key);
|
||||
}
|
||||
else if (event->type() == QEvent::KeyRelease)
|
||||
{
|
||||
QWidget* widget = static_cast<QWidget*>(watched);
|
||||
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(mod, key);
|
||||
return deactivate(widget, mod, key);
|
||||
}
|
||||
else if (event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
QWidget* widget = static_cast<QWidget*>(watched);
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
unsigned int mod = (unsigned int) mouseEvent->modifiers();
|
||||
unsigned int button = (unsigned int) mouseEvent->button();
|
||||
|
||||
return activate(mod, button);
|
||||
return activate(widget, mod, button);
|
||||
}
|
||||
else if (event->type() == QEvent::MouseButtonRelease)
|
||||
{
|
||||
QWidget* widget = static_cast<QWidget*>(watched);
|
||||
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
unsigned int mod = (unsigned int) mouseEvent->modifiers();
|
||||
unsigned int button = (unsigned int) mouseEvent->button();
|
||||
|
||||
return deactivate(mod, button);
|
||||
return deactivate(widget, mod, button);
|
||||
}
|
||||
else if (event->type() == QEvent::FocusOut)
|
||||
{
|
||||
QWidget* widget = static_cast<QWidget*>(watched);
|
||||
ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget);
|
||||
|
||||
// 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;
|
||||
|
||||
|
@ -85,23 +119,56 @@ namespace CSMPrefs
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (event->type() == QEvent::FocusIn)
|
||||
{
|
||||
QWidget* widget = static_cast<QWidget*>(watched);
|
||||
updateParent(widget);
|
||||
}
|
||||
|
||||
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;
|
||||
bool used = false;
|
||||
|
||||
while (widget)
|
||||
{
|
||||
ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget);
|
||||
assert(shortcutListIt != mWidgetShortcuts.end());
|
||||
|
||||
// Find potential activations
|
||||
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;
|
||||
|
||||
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]);
|
||||
|
@ -117,9 +184,11 @@ namespace CSMPrefs
|
|||
potentials.push_back(std::make_pair(result, shortcut));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (checkModifier(mod, button, shortcut, true))
|
||||
used = true;
|
||||
// Move on to parent
|
||||
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.
|
||||
|
@ -147,13 +216,18 @@ namespace CSMPrefs
|
|||
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;
|
||||
|
||||
bool used = false;
|
||||
|
||||
for (std::vector<Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.end(); ++it)
|
||||
while (widget)
|
||||
{
|
||||
ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget);
|
||||
assert(shortcutListIt != mWidgetShortcuts.end());
|
||||
|
||||
for (ShortcutList::iterator it = shortcutListIt->second.begin(); it != shortcutListIt->second.end(); ++it)
|
||||
{
|
||||
Shortcut* shortcut = *it;
|
||||
|
||||
|
@ -182,12 +256,18 @@ namespace CSMPrefs
|
|||
}
|
||||
}
|
||||
|
||||
// Move on to parent
|
||||
WidgetMap::iterator widgetIt = mChildParentRelations.find(widget);
|
||||
widget = (widgetIt != mChildParentRelations.end()) ? widgetIt->second : 0;
|
||||
}
|
||||
|
||||
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)
|
||||
if (!shortcut->isEnabled() || !shortcut->getModifier() || shortcut->getSecondaryMode() == Shortcut::SM_Ignore ||
|
||||
shortcut->getModifierStatus() == activate)
|
||||
return false;
|
||||
|
||||
MatchResult result = match(mod, button, shortcut->getModifier());
|
||||
|
@ -208,8 +288,6 @@ namespace CSMPrefs
|
|||
{
|
||||
shortcut->signalSecondary(false);
|
||||
}
|
||||
|
||||
used = true;
|
||||
}
|
||||
else if (!activate && shortcut->getActivationStatus() == Shortcut::AS_Secondary)
|
||||
{
|
||||
|
@ -243,9 +321,17 @@ namespace CSMPrefs
|
|||
bool ShortcutEventHandler::sort(const std::pair<MatchResult, Shortcut*>& left,
|
||||
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;
|
||||
else
|
||||
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
|
||||
#define CSM_PREFS_SHORTCUT_EVENT_HANDLER_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <QObject>
|
||||
|
@ -19,7 +20,7 @@ namespace CSMPrefs
|
|||
|
||||
public:
|
||||
|
||||
ShortcutEventHandler(QObject* parent=0);
|
||||
ShortcutEventHandler(QObject* parent);
|
||||
|
||||
void addShortcut(Shortcut* shortcut);
|
||||
void removeShortcut(Shortcut* shortcut);
|
||||
|
@ -30,6 +31,11 @@ namespace CSMPrefs
|
|||
|
||||
private:
|
||||
|
||||
typedef std::vector<Shortcut*> ShortcutList;
|
||||
// Child, Parent
|
||||
typedef std::map<QWidget*, QWidget*> WidgetMap;
|
||||
typedef std::map<QWidget*, ShortcutList> ShortcutMap;
|
||||
|
||||
enum MatchResult
|
||||
{
|
||||
Matches_WithMod,
|
||||
|
@ -37,9 +43,11 @@ namespace CSMPrefs
|
|||
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);
|
||||
|
||||
|
@ -49,7 +57,12 @@ namespace CSMPrefs
|
|||
static bool sort(const std::pair<MatchResult, Shortcut*>& left,
|
||||
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 <iostream>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMetaEnum>
|
||||
#include <QRegExp>
|
||||
#include <QStringList>
|
||||
|
||||
#include "shortcut.hpp"
|
||||
#include "shortcuteventhandler.hpp"
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
ShortcutManager::ShortcutManager()
|
||||
{
|
||||
mEventHandler = new ShortcutEventHandler(this);
|
||||
}
|
||||
|
||||
void ShortcutManager::addShortcut(Shortcut* shortcut)
|
||||
{
|
||||
mShortcuts.insert(std::make_pair(shortcut->getName(), shortcut));
|
||||
mEventHandler->addShortcut(shortcut);
|
||||
}
|
||||
|
||||
void ShortcutManager::removeShortcut(Shortcut* shortcut)
|
||||
|
@ -31,6 +39,8 @@ namespace CSMPrefs
|
|||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
mEventHandler->removeShortcut(shortcut);
|
||||
}
|
||||
|
||||
ShortcutManager::SequenceData ShortcutManager::getSequence(const std::string& name) const
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
namespace CSMPrefs
|
||||
{
|
||||
class Shortcut;
|
||||
class ShortcutEventHandler;
|
||||
|
||||
/// Class used to track and update shortcuts/sequences
|
||||
class ShortcutManager : public QObject
|
||||
|
@ -20,6 +21,9 @@ namespace CSMPrefs
|
|||
/// Key Sequence, Modifier (for secondary signal)
|
||||
typedef std::pair<QKeySequence, int> SequenceData;
|
||||
|
||||
|
||||
ShortcutManager();
|
||||
|
||||
/// The shortcut class will do this automatically
|
||||
void addShortcut(Shortcut* shortcut);
|
||||
|
||||
|
@ -40,6 +44,8 @@ namespace CSMPrefs
|
|||
|
||||
ShortcutMap mShortcuts;
|
||||
SequenceMap mSequences;
|
||||
|
||||
ShortcutEventHandler* mEventHandler;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -229,6 +229,10 @@ void CSMPrefs::State::declare()
|
|||
addValues (insertOutsideVisibleCell);
|
||||
|
||||
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-backward", "Free camera backward", QKeySequence(Qt::Key_S));
|
||||
declareShortcut ("free-left", "Free camera left", QKeySequence(Qt::Key_A));
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "../../model/doc/document.hpp"
|
||||
#include "../../model/prefs/state.hpp"
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
|
||||
#include "../../model/world/idtable.hpp"
|
||||
|
||||
|
@ -62,6 +63,9 @@ void CSVDoc::View::setupFileMenu()
|
|||
connect (mSave, SIGNAL (triggered()), this, SLOT (save()));
|
||||
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);
|
||||
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
|
||||
file->addAction (mVerify);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <cmath>
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QWidget>
|
||||
|
||||
#include <osg/BoundingBox>
|
||||
#include <osg/Camera>
|
||||
|
@ -15,7 +15,6 @@
|
|||
#include <osgUtil/LineSegmentIntersector>
|
||||
|
||||
#include "../../model/prefs/shortcut.hpp"
|
||||
#include "../../model/prefs/shortcuteventhandler.hpp"
|
||||
|
||||
#include "scenewidget.hpp"
|
||||
|
||||
|
@ -79,27 +78,17 @@ namespace CSVRender
|
|||
|
||||
void CameraController::setCamera(osg::Camera* camera)
|
||||
{
|
||||
bool wasActive = mActive;
|
||||
|
||||
mCamera = camera;
|
||||
mActive = (mCamera != NULL);
|
||||
|
||||
if (mActive)
|
||||
if (mActive != wasActive)
|
||||
{
|
||||
onActivate();
|
||||
|
||||
QList<CSMPrefs::Shortcut*> shortcuts = findChildren<CSMPrefs::Shortcut*>();
|
||||
|
||||
for (QList<CSMPrefs::Shortcut*>::iterator it = shortcuts.begin(); it != shortcuts.end(); ++it)
|
||||
for (std::vector<CSMPrefs::Shortcut*>::iterator it = mShortcuts.begin(); it != mShortcuts.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);
|
||||
CSMPrefs::Shortcut* shortcut = *it;
|
||||
shortcut->enable(mActive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -160,14 +149,21 @@ namespace CSVRender
|
|||
getCamera()->setViewMatrixAsLookAt(eye, center, up);
|
||||
}
|
||||
|
||||
void CameraController::addShortcut(CSMPrefs::Shortcut* shortcut)
|
||||
{
|
||||
mShortcuts.push_back(shortcut);
|
||||
}
|
||||
|
||||
/*
|
||||
Free Camera Controller
|
||||
*/
|
||||
|
||||
FreeCameraController::FreeCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent)
|
||||
: CameraController(parent)
|
||||
FreeCameraController::FreeCameraController(QWidget* widget)
|
||||
: CameraController(widget)
|
||||
, mLockUpright(false)
|
||||
, mModified(false)
|
||||
, mNaviPrimary(false)
|
||||
, mNaviSecondary(false)
|
||||
, mFast(false)
|
||||
, mFastAlternate(false)
|
||||
, mLeft(false)
|
||||
|
@ -181,52 +177,61 @@ namespace CSVRender
|
|||
, mRotSpeed(osg::PI / 2)
|
||||
, 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);
|
||||
handler->addShortcut(naviPrimaryShortcut);
|
||||
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);
|
||||
handler->addShortcut(naviSecondaryShortcut);
|
||||
connect(naviSecondaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviSecondary(bool)));
|
||||
|
||||
addShortcut(naviSecondaryShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* forwardShortcut = new CSMPrefs::Shortcut("free-forward", CSMPrefs::Shortcut::SM_Detach,
|
||||
this);
|
||||
widget);
|
||||
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);
|
||||
addShortcut(forwardShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("free-left", widget);
|
||||
leftShortcut->enable(false);
|
||||
handler->addShortcut(leftShortcut);
|
||||
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);
|
||||
handler->addShortcut(backShortcut);
|
||||
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);
|
||||
handler->addShortcut(rightShortcut);
|
||||
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);
|
||||
handler->addShortcut(rollLeftShortcut);
|
||||
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);
|
||||
handler->addShortcut(rollRightShortcut);
|
||||
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);
|
||||
handler->addShortcut(speedModeShortcut);
|
||||
connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
|
||||
|
||||
addShortcut(speedModeShortcut);
|
||||
}
|
||||
|
||||
double FreeCameraController::getLinearSpeed() const
|
||||
|
@ -440,9 +445,11 @@ namespace CSVRender
|
|||
Orbit Camera Controller
|
||||
*/
|
||||
|
||||
OrbitCameraController::OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent)
|
||||
: CameraController(parent)
|
||||
OrbitCameraController::OrbitCameraController(QWidget* widget)
|
||||
: CameraController(widget)
|
||||
, mInitialized(false)
|
||||
, mNaviPrimary(false)
|
||||
, mNaviSecondary(false)
|
||||
, mFast(false)
|
||||
, mFastAlternate(false)
|
||||
, mLeft(false)
|
||||
|
@ -457,51 +464,60 @@ namespace CSVRender
|
|||
, mOrbitSpeed(osg::PI / 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);
|
||||
handler->addShortcut(naviPrimaryShortcut);
|
||||
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);
|
||||
handler->addShortcut(naviSecondaryShortcut);
|
||||
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);
|
||||
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);
|
||||
addShortcut(upShortcut);
|
||||
|
||||
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("orbit-left", widget);
|
||||
leftShortcut->enable(false);
|
||||
handler->addShortcut(leftShortcut);
|
||||
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);
|
||||
handler->addShortcut(downShortcut);
|
||||
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);
|
||||
handler->addShortcut(rightShortcut);
|
||||
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);
|
||||
handler->addShortcut(rollLeftShortcut);
|
||||
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);
|
||||
handler->addShortcut(rollRightShortcut);
|
||||
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);
|
||||
handler->addShortcut(speedModeShortcut);
|
||||
connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
|
||||
|
||||
addShortcut(speedModeShortcut);
|
||||
}
|
||||
|
||||
osg::Vec3d OrbitCameraController::getCenter() const
|
||||
|
|
|
@ -2,14 +2,13 @@
|
|||
#define OPENCS_VIEW_CAMERACONTROLLER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Vec3d>
|
||||
|
||||
class QKeyEvent;
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class Camera;
|
||||
|
@ -18,7 +17,7 @@ namespace osg
|
|||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class ShortcutEventHandler;
|
||||
class Shortcut;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
|
@ -66,6 +65,8 @@ namespace CSVRender
|
|||
|
||||
virtual void onActivate(){}
|
||||
|
||||
void addShortcut(CSMPrefs::Shortcut* shortcut);
|
||||
|
||||
private:
|
||||
|
||||
bool mActive, mInverted;
|
||||
|
@ -74,6 +75,8 @@ namespace CSVRender
|
|||
double mWheelMoveMult;
|
||||
|
||||
osg::Camera* mCamera;
|
||||
|
||||
std::vector<CSMPrefs::Shortcut*> mShortcuts;
|
||||
};
|
||||
|
||||
class FreeCameraController : public CameraController
|
||||
|
@ -82,7 +85,7 @@ namespace CSVRender
|
|||
|
||||
public:
|
||||
|
||||
FreeCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent=0);
|
||||
FreeCameraController(QWidget* parent);
|
||||
|
||||
double getLinearSpeed() const;
|
||||
double getRotationalSpeed() const;
|
||||
|
@ -139,7 +142,7 @@ namespace CSVRender
|
|||
|
||||
public:
|
||||
|
||||
OrbitCameraController(CSMPrefs::ShortcutEventHandler* handler, QObject* parent=0);
|
||||
OrbitCameraController(QWidget* parent);
|
||||
|
||||
osg::Vec3d getCenter() const;
|
||||
double getOrbitSpeed() const;
|
||||
|
|
|
@ -9,22 +9,19 @@
|
|||
|
||||
namespace CSVRender
|
||||
{
|
||||
OrbitCameraMode::OrbitCameraMode(WorldspaceWidget* worldspaceWidget, CSMPrefs::ShortcutEventHandler* handler,
|
||||
const QIcon& icon, const QString& tooltip, QWidget* parent)
|
||||
OrbitCameraMode::OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip,
|
||||
QWidget* parent)
|
||||
: ModeButton(icon, tooltip, parent)
|
||||
, mWorldspaceWidget(worldspaceWidget)
|
||||
, mShortcutHandler(handler)
|
||||
, mCenterOnSelection(0)
|
||||
{
|
||||
mCenterShortcut = new CSMPrefs::Shortcut("orbit-center-selection", this);
|
||||
mCenterShortcut.reset(new CSMPrefs::Shortcut("orbit-center-selection", worldspaceWidget));
|
||||
mCenterShortcut->enable(false);
|
||||
mShortcutHandler->addShortcut(mCenterShortcut);
|
||||
connect(mCenterShortcut, SIGNAL(activated()), this, SLOT(centerSelection()));
|
||||
connect(mCenterShortcut.get(), SIGNAL(activated()), this, SLOT(centerSelection()));
|
||||
}
|
||||
|
||||
OrbitCameraMode::~OrbitCameraMode()
|
||||
{
|
||||
mShortcutHandler->removeShortcut(mCenterShortcut);
|
||||
}
|
||||
|
||||
void OrbitCameraMode::activate(CSVWidget::SceneToolbar* toolbar)
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
#ifndef CSV_RENDER_ORBITCAMERAPICKMODE_H
|
||||
#define CSV_RENDER_ORBITCAMERAPICKMODE_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "../widget/modebutton.hpp"
|
||||
|
||||
namespace CSMPrefs
|
||||
{
|
||||
class Shortcut;
|
||||
class ShortcutEventHandler;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
|
@ -19,8 +20,8 @@ namespace CSVRender
|
|||
|
||||
public:
|
||||
|
||||
OrbitCameraMode(WorldspaceWidget* worldspaceWidget, CSMPrefs::ShortcutEventHandler* shortcutHandler,
|
||||
const QIcon& icon, const QString& tooltip = "", QWidget* parent = 0);
|
||||
OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip = "",
|
||||
QWidget* parent = 0);
|
||||
~OrbitCameraMode();
|
||||
|
||||
virtual void activate(CSVWidget::SceneToolbar* toolbar);
|
||||
|
@ -30,9 +31,8 @@ namespace CSVRender
|
|||
private:
|
||||
|
||||
WorldspaceWidget* mWorldspaceWidget;
|
||||
CSMPrefs::ShortcutEventHandler* mShortcutHandler;
|
||||
QAction* mCenterOnSelection;
|
||||
CSMPrefs::Shortcut* mCenterShortcut;
|
||||
std::auto_ptr<CSMPrefs::Shortcut> mCenterShortcut;
|
||||
|
||||
private slots:
|
||||
|
||||
|
|
|
@ -171,11 +171,8 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
|
|||
, mPrevMouseY(0)
|
||||
, mCamPositionSet(false)
|
||||
{
|
||||
mShortcutHandler = new CSMPrefs::ShortcutEventHandler(this);
|
||||
installEventFilter(mShortcutHandler);
|
||||
|
||||
mFreeCamControl = new FreeCameraController(mShortcutHandler, this);
|
||||
mOrbitCamControl = new OrbitCameraController(mShortcutHandler, this);
|
||||
mFreeCamControl = new FreeCameraController(this);
|
||||
mOrbitCamControl = new OrbitCameraController(this);
|
||||
mCurrentCamControl = mFreeCamControl;
|
||||
|
||||
mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain);
|
||||
|
@ -205,18 +202,14 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
|
|||
|
||||
// Shortcuts
|
||||
CSMPrefs::Shortcut* focusToolbarShortcut = new CSMPrefs::Shortcut("scene-focus-toolbar", this);
|
||||
mShortcutHandler->addShortcut(focusToolbarShortcut);
|
||||
connect(focusToolbarShortcut, SIGNAL(activated()), this, SIGNAL(focusToolbarRequest()));
|
||||
|
||||
CSMPrefs::Shortcut* renderStatsShortcut = new CSMPrefs::Shortcut("scene-render-stats", this);
|
||||
mShortcutHandler->addShortcut(renderStatsShortcut);
|
||||
connect(renderStatsShortcut, SIGNAL(activated()), this, SLOT(toggleRenderStats()));
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -37,8 +37,6 @@ namespace CSVWidget
|
|||
namespace CSMPrefs
|
||||
{
|
||||
class Setting;
|
||||
class Shortcut;
|
||||
class ShortcutEventHandler;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
|
@ -116,8 +114,6 @@ namespace CSVRender
|
|||
OrbitCameraController* mOrbitCamControl;
|
||||
CameraController* mCurrentCamControl;
|
||||
|
||||
CSMPrefs::ShortcutEventHandler *mShortcutHandler;
|
||||
|
||||
private:
|
||||
bool mCamPositionSet;
|
||||
|
||||
|
|
|
@ -98,23 +98,18 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg
|
|||
|
||||
// Shortcuts
|
||||
CSMPrefs::Shortcut* primaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-primary", this);
|
||||
mShortcutHandler->addShortcut(primaryEditShortcut);
|
||||
connect(primaryEditShortcut, SIGNAL(activated(bool)), this, SLOT(primaryEdit(bool)));
|
||||
|
||||
CSMPrefs::Shortcut* secondaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-secondary", this);
|
||||
mShortcutHandler->addShortcut(secondaryEditShortcut);
|
||||
connect(secondaryEditShortcut, SIGNAL(activated(bool)), this, SLOT(secondaryEdit(bool)));
|
||||
|
||||
CSMPrefs::Shortcut* primarySelectShortcut = new CSMPrefs::Shortcut("scene-select-primary", this);
|
||||
mShortcutHandler->addShortcut(primarySelectShortcut);
|
||||
connect(primarySelectShortcut, SIGNAL(activated(bool)), this, SLOT(primarySelect(bool)));
|
||||
|
||||
CSMPrefs::Shortcut* secondarySelectShortcut = new CSMPrefs::Shortcut("scene-select-secondary", this);
|
||||
mShortcutHandler->addShortcut(secondarySelectShortcut);
|
||||
connect(secondarySelectShortcut, SIGNAL(activated(bool)), this, SLOT(secondarySelect(bool)));
|
||||
|
||||
CSMPrefs::Shortcut* abortShortcut = new CSMPrefs::Shortcut("scene-edit-abort", this);
|
||||
mShortcutHandler->addShortcut(abortShortcut);
|
||||
connect(abortShortcut, SIGNAL(activated()), this, SLOT(abortDrag()));
|
||||
}
|
||||
|
||||
|
@ -184,7 +179,7 @@ CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector (
|
|||
"<li>Hold shift to speed up movement</li>"
|
||||
"</ul>");
|
||||
tool->addButton(
|
||||
new CSVRender::OrbitCameraMode(this, mShortcutHandler, QIcon(":scenetoolbar/orbiting-camera"),
|
||||
new CSVRender::OrbitCameraMode(this, QIcon(":scenetoolbar/orbiting-camera"),
|
||||
"Orbiting Camera"
|
||||
"<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>"
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
namespace CSMPrefs
|
||||
{
|
||||
class Setting;
|
||||
class Shortcut;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
|
|
Loading…
Reference in a new issue