forked from mirror/openmw-tes3mp
Merge remote-tracking branch 'aesylwinn/KeyConfigAndShortcuts'
This commit is contained in:
commit
f32d0121fc
42 changed files with 3263 additions and 542 deletions
|
@ -86,12 +86,12 @@ opencs_units (view/widget
|
||||||
opencs_units (view/render
|
opencs_units (view/render
|
||||||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||||
previewwidget editmode instancemode instanceselectionmode instancemovemode
|
previewwidget editmode instancemode instanceselectionmode instancemovemode
|
||||||
orbitcameramode pathgridmode selectionmode pathgridselectionmode
|
orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/render
|
opencs_units_noqt (view/render
|
||||||
lighting lightingday lightingnight lightingbright object cell terrainstorage tagbase
|
lighting lightingday lightingnight lightingbright object cell terrainstorage tagbase
|
||||||
cellarrow cellmarker cellborder cameracontroller pathgrid
|
cellarrow cellmarker cellborder pathgrid
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (view/render
|
opencs_hdrs_noqt (view/render
|
||||||
|
@ -108,11 +108,12 @@ opencs_units_noqt (view/tools
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units (view/prefs
|
opencs_units (view/prefs
|
||||||
dialogue pagebase page
|
dialogue pagebase page keybindingpage
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units (model/prefs
|
opencs_units (model/prefs
|
||||||
state setting intsetting doublesetting boolsetting enumsetting coloursetting
|
state setting intsetting doublesetting boolsetting enumsetting coloursetting shortcut
|
||||||
|
shortcuteventhandler shortcutmanager shortcutsetting modifiersetting
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (model/prefs
|
opencs_units_noqt (model/prefs
|
||||||
|
|
146
apps/opencs/model/prefs/modifiersetting.cpp
Normal file
146
apps/opencs/model/prefs/modifiersetting.cpp
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
#include "modifiersetting.hpp"
|
||||||
|
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "state.hpp"
|
||||||
|
#include "shortcutmanager.hpp"
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
ModifierSetting::ModifierSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key,
|
||||||
|
const std::string& label)
|
||||||
|
: Setting(parent, values, mutex, key, label)
|
||||||
|
, mEditorActive(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QWidget*, QWidget*> ModifierSetting::makeWidgets(QWidget* parent)
|
||||||
|
{
|
||||||
|
int modifier = 0;
|
||||||
|
State::get().getShortcutManager().getModifier(getKey(), modifier);
|
||||||
|
|
||||||
|
QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(modifier).c_str());
|
||||||
|
|
||||||
|
QLabel* label = new QLabel(QString::fromUtf8(getLabel().c_str()), parent);
|
||||||
|
QPushButton* widget = new QPushButton(text, parent);
|
||||||
|
|
||||||
|
widget->setCheckable(true);
|
||||||
|
widget->installEventFilter(this);
|
||||||
|
mButton = widget;
|
||||||
|
|
||||||
|
connect(widget, SIGNAL(toggled(bool)), this, SLOT(buttonToggled(bool)));
|
||||||
|
|
||||||
|
return std::make_pair(label, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModifierSetting::eventFilter(QObject* target, QEvent* event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::KeyPress)
|
||||||
|
{
|
||||||
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||||
|
if (keyEvent->isAutoRepeat())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
int mod = keyEvent->modifiers();
|
||||||
|
int key = keyEvent->key();
|
||||||
|
|
||||||
|
return handleEvent(target, mod, key);
|
||||||
|
}
|
||||||
|
else if (event->type() == QEvent::MouseButtonPress)
|
||||||
|
{
|
||||||
|
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||||
|
int mod = mouseEvent->modifiers();
|
||||||
|
int button = mouseEvent->button();
|
||||||
|
|
||||||
|
return handleEvent(target, mod, button);
|
||||||
|
}
|
||||||
|
else if (event->type() == QEvent::FocusOut)
|
||||||
|
{
|
||||||
|
resetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModifierSetting::handleEvent(QObject* target, int mod, int value)
|
||||||
|
{
|
||||||
|
// For potential future exceptions
|
||||||
|
const int Blacklist[] =
|
||||||
|
{
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t BlacklistSize = sizeof(Blacklist) / sizeof(int);
|
||||||
|
|
||||||
|
if (!mEditorActive)
|
||||||
|
{
|
||||||
|
if (value == Qt::RightButton)
|
||||||
|
{
|
||||||
|
// Clear modifier
|
||||||
|
int modifier = 0;
|
||||||
|
storeValue(modifier);
|
||||||
|
|
||||||
|
resetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle blacklist
|
||||||
|
for (size_t i = 0; i < BlacklistSize; ++i)
|
||||||
|
{
|
||||||
|
if (value == Blacklist[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update modifier
|
||||||
|
int modifier = value;
|
||||||
|
storeValue(modifier);
|
||||||
|
|
||||||
|
resetState();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModifierSetting::storeValue(int modifier)
|
||||||
|
{
|
||||||
|
State::get().getShortcutManager().setModifier(getKey(), modifier);
|
||||||
|
|
||||||
|
// Convert to string and assign
|
||||||
|
std::string value = State::get().getShortcutManager().convertToString(modifier);
|
||||||
|
|
||||||
|
{
|
||||||
|
QMutexLocker lock(getMutex());
|
||||||
|
getValues().setString(getKey(), getParent()->getKey(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
getParent()->getState()->update(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModifierSetting::resetState()
|
||||||
|
{
|
||||||
|
mButton->setChecked(false);
|
||||||
|
mEditorActive = false;
|
||||||
|
|
||||||
|
// Button text
|
||||||
|
int modifier = 0;
|
||||||
|
State::get().getShortcutManager().getModifier(getKey(), modifier);
|
||||||
|
|
||||||
|
QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(modifier).c_str());
|
||||||
|
mButton->setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModifierSetting::buttonToggled(bool checked)
|
||||||
|
{
|
||||||
|
if (checked)
|
||||||
|
mButton->setText("Press keys or click here...");
|
||||||
|
|
||||||
|
mEditorActive = checked;
|
||||||
|
}
|
||||||
|
}
|
44
apps/opencs/model/prefs/modifiersetting.hpp
Normal file
44
apps/opencs/model/prefs/modifiersetting.hpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef CSM_PREFS_MODIFIERSETTING_H
|
||||||
|
#define CSM_PREFS_MODIFIERSETTING_H
|
||||||
|
|
||||||
|
#include <QKeySequence>
|
||||||
|
|
||||||
|
#include "setting.hpp"
|
||||||
|
|
||||||
|
class QEvent;
|
||||||
|
class QPushButton;
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class ModifierSetting : public Setting
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ModifierSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key,
|
||||||
|
const std::string& label);
|
||||||
|
|
||||||
|
virtual std::pair<QWidget*, QWidget*> makeWidgets(QWidget* parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool eventFilter(QObject* target, QEvent* event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool handleEvent(QObject* target, int mod, int value);
|
||||||
|
|
||||||
|
void storeValue(int modifier);
|
||||||
|
void resetState();
|
||||||
|
|
||||||
|
QPushButton* mButton;
|
||||||
|
bool mEditorActive;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void buttonToggled(bool checked);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
214
apps/opencs/model/prefs/shortcut.cpp
Normal file
214
apps/opencs/model/prefs/shortcut.cpp
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
#include "shortcut.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "state.hpp"
|
||||||
|
#include "shortcutmanager.hpp"
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
Shortcut::Shortcut(const std::string& name, QWidget* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, mEnabled(true)
|
||||||
|
, mName(name)
|
||||||
|
, mModName("")
|
||||||
|
, mSecondaryMode(SM_Ignore)
|
||||||
|
, mModifier(0)
|
||||||
|
, mCurrentPos(0)
|
||||||
|
, mLastPos(0)
|
||||||
|
, mActivationStatus(AS_Inactive)
|
||||||
|
, mModifierStatus(false)
|
||||||
|
, mAction(0)
|
||||||
|
{
|
||||||
|
assert (parent);
|
||||||
|
|
||||||
|
State::get().getShortcutManager().addShortcut(this);
|
||||||
|
State::get().getShortcutManager().getSequence(name, mSequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shortcut::Shortcut(const std::string& name, const std::string& modName, QWidget* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, mEnabled(true)
|
||||||
|
, mName(name)
|
||||||
|
, mModName(modName)
|
||||||
|
, mSecondaryMode(SM_Ignore)
|
||||||
|
, mModifier(0)
|
||||||
|
, mCurrentPos(0)
|
||||||
|
, mLastPos(0)
|
||||||
|
, mActivationStatus(AS_Inactive)
|
||||||
|
, mModifierStatus(false)
|
||||||
|
, mAction(0)
|
||||||
|
{
|
||||||
|
assert (parent);
|
||||||
|
|
||||||
|
State::get().getShortcutManager().addShortcut(this);
|
||||||
|
State::get().getShortcutManager().getSequence(name, mSequence);
|
||||||
|
State::get().getShortcutManager().getModifier(modName, mModifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shortcut::Shortcut(const std::string& name, const std::string& modName, SecondaryMode secMode, QWidget* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, mEnabled(true)
|
||||||
|
, mName(name)
|
||||||
|
, mModName(modName)
|
||||||
|
, mSecondaryMode(secMode)
|
||||||
|
, mModifier(0)
|
||||||
|
, mCurrentPos(0)
|
||||||
|
, mLastPos(0)
|
||||||
|
, mActivationStatus(AS_Inactive)
|
||||||
|
, mModifierStatus(false)
|
||||||
|
, mAction(0)
|
||||||
|
{
|
||||||
|
assert (parent);
|
||||||
|
|
||||||
|
State::get().getShortcutManager().addShortcut(this);
|
||||||
|
State::get().getShortcutManager().getSequence(name, mSequence);
|
||||||
|
State::get().getShortcutManager().getModifier(modName, mModifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shortcut::~Shortcut()
|
||||||
|
{
|
||||||
|
State::get().getShortcutManager().removeShortcut(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Shortcut::isEnabled() const
|
||||||
|
{
|
||||||
|
return mEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& Shortcut::getName() const
|
||||||
|
{
|
||||||
|
return mName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& Shortcut::getModifierName() const
|
||||||
|
{
|
||||||
|
return mModName;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Shortcut::getLastPosition() const
|
||||||
|
{
|
||||||
|
return mLastPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shortcut::ActivationStatus Shortcut::getActivationStatus() const
|
||||||
|
{
|
||||||
|
return mActivationStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Shortcut::getModifierStatus() const
|
||||||
|
{
|
||||||
|
return mModifierStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shortcut::enable(bool state)
|
||||||
|
{
|
||||||
|
mEnabled = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shortcut::setSequence(const QKeySequence& sequence)
|
||||||
|
{
|
||||||
|
mSequence = sequence;
|
||||||
|
mCurrentPos = 0;
|
||||||
|
mLastPos = sequence.count() - 1;
|
||||||
|
|
||||||
|
if (mAction)
|
||||||
|
{
|
||||||
|
mAction->setText(mActionText + "\t" + State::get().getShortcutManager().convertToString(mSequence).data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shortcut::setModifier(int modifier)
|
||||||
|
{
|
||||||
|
mModifier = modifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shortcut::setPosition(int pos)
|
||||||
|
{
|
||||||
|
mCurrentPos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shortcut::setActivationStatus(ActivationStatus status)
|
||||||
|
{
|
||||||
|
mActivationStatus = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shortcut::setModifierStatus(bool status)
|
||||||
|
{
|
||||||
|
mModifierStatus = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shortcut::associateAction(QAction* action)
|
||||||
|
{
|
||||||
|
if (mAction)
|
||||||
|
{
|
||||||
|
mAction->setText(mActionText);
|
||||||
|
|
||||||
|
disconnect(this, SIGNAL(activated()), mAction, SLOT(trigger()));
|
||||||
|
disconnect(mAction, SIGNAL(destroyed()), this, SLOT(actionDeleted()));
|
||||||
|
}
|
||||||
|
|
||||||
|
mAction = action;
|
||||||
|
|
||||||
|
if (mAction)
|
||||||
|
{
|
||||||
|
mActionText = mAction->text();
|
||||||
|
mAction->setText(mActionText + "\t" + State::get().getShortcutManager().convertToString(mSequence).data());
|
||||||
|
|
||||||
|
connect(this, SIGNAL(activated()), mAction, SLOT(trigger()));
|
||||||
|
connect(mAction, SIGNAL(destroyed()), this, SLOT(actionDeleted()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shortcut::signalActivated(bool state)
|
||||||
|
{
|
||||||
|
emit activated(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shortcut::signalActivated()
|
||||||
|
{
|
||||||
|
emit activated();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shortcut::signalSecondary(bool state)
|
||||||
|
{
|
||||||
|
emit secondary(state);
|
||||||
|
}
|
||||||
|
void Shortcut::signalSecondary()
|
||||||
|
{
|
||||||
|
emit secondary();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Shortcut::toString() const
|
||||||
|
{
|
||||||
|
return QString(State::get().getShortcutManager().convertToString(mSequence, mModifier).data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shortcut::actionDeleted()
|
||||||
|
{
|
||||||
|
mAction = 0;
|
||||||
|
}
|
||||||
|
}
|
122
apps/opencs/model/prefs/shortcut.hpp
Normal file
122
apps/opencs/model/prefs/shortcut.hpp
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
#ifndef CSM_PREFS_SHORTCUT_H
|
||||||
|
#define CSM_PREFS_SHORTCUT_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <QKeySequence>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class QAction;
|
||||||
|
class QWidget;
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
/// A class similar in purpose to QShortcut, but with the ability to use mouse buttons
|
||||||
|
class Shortcut : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
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, QWidget* parent);
|
||||||
|
Shortcut(const std::string& name, const std::string& modName, QWidget* parent);
|
||||||
|
Shortcut(const std::string& name, const std::string& modName, SecondaryMode secMode, QWidget* parent);
|
||||||
|
|
||||||
|
~Shortcut();
|
||||||
|
|
||||||
|
bool isEnabled() const;
|
||||||
|
|
||||||
|
const std::string& getName() const;
|
||||||
|
const std::string& getModifierName() 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 setActivationStatus(ActivationStatus status);
|
||||||
|
void setModifierStatus(bool status);
|
||||||
|
|
||||||
|
/// Appends the sequence to the QAction text, also keeps it up to date
|
||||||
|
void associateAction(QAction* action);
|
||||||
|
|
||||||
|
// Workaround for Qt4 signals being "protected"
|
||||||
|
void signalActivated(bool state);
|
||||||
|
void signalActivated();
|
||||||
|
|
||||||
|
void signalSecondary(bool state);
|
||||||
|
void signalSecondary();
|
||||||
|
|
||||||
|
QString toString() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool mEnabled;
|
||||||
|
|
||||||
|
std::string mName;
|
||||||
|
std::string mModName;
|
||||||
|
SecondaryMode mSecondaryMode;
|
||||||
|
QKeySequence mSequence;
|
||||||
|
int mModifier;
|
||||||
|
|
||||||
|
int mCurrentPos;
|
||||||
|
int mLastPos;
|
||||||
|
|
||||||
|
ActivationStatus mActivationStatus;
|
||||||
|
bool mModifierStatus;
|
||||||
|
|
||||||
|
QAction* mAction;
|
||||||
|
QString mActionText;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void actionDeleted();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
/// Triggered when the shortcut is activated or deactivated; can be determined from \p state
|
||||||
|
void activated(bool state);
|
||||||
|
|
||||||
|
/// Convenience signal.
|
||||||
|
void activated();
|
||||||
|
|
||||||
|
/// Triggered depending on SecondaryMode
|
||||||
|
void secondary(bool state);
|
||||||
|
|
||||||
|
/// Convenience signal.
|
||||||
|
void secondary();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
338
apps/opencs/model/prefs/shortcuteventhandler.cpp
Normal file
338
apps/opencs/model/prefs/shortcuteventhandler.cpp
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
#include "shortcuteventhandler.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "shortcut.hpp"
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
ShortcutEventHandler::ShortcutEventHandler(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutEventHandler::addShortcut(Shortcut* 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)
|
||||||
|
{
|
||||||
|
// 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(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(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(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(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 (ShortcutList::iterator it = shortcutListIt->second.begin(); it != shortcutListIt->second.end(); ++it)
|
||||||
|
{
|
||||||
|
Shortcut* shortcut = *it;
|
||||||
|
|
||||||
|
shortcut->setPosition(0);
|
||||||
|
shortcut->setModifierStatus(false);
|
||||||
|
|
||||||
|
if (shortcut->getActivationStatus() == Shortcut::AS_Regular)
|
||||||
|
{
|
||||||
|
shortcut->setActivationStatus(Shortcut::AS_Inactive);
|
||||||
|
shortcut->signalActivated(false);
|
||||||
|
}
|
||||||
|
else if (shortcut->getActivationStatus() == Shortcut::AS_Secondary)
|
||||||
|
{
|
||||||
|
shortcut->setActivationStatus(Shortcut::AS_Inactive);
|
||||||
|
shortcut->signalSecondary(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event->type() == QEvent::FocusIn)
|
||||||
|
{
|
||||||
|
QWidget* widget = static_cast<QWidget*>(watched);
|
||||||
|
updateParent(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
updateParent(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 (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]);
|
||||||
|
|
||||||
|
if (result == Matches_WithMod || result == Matches_NoMod)
|
||||||
|
{
|
||||||
|
if (pos < lastPos && (result == Matches_WithMod || pos > 0))
|
||||||
|
{
|
||||||
|
shortcut->setPosition(pos+1);
|
||||||
|
}
|
||||||
|
else if (pos == lastPos)
|
||||||
|
{
|
||||||
|
potentials.push_back(std::make_pair(result, shortcut));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
if (!potentials.empty())
|
||||||
|
{
|
||||||
|
std::sort(potentials.begin(), potentials.end(), ShortcutEventHandler::sort);
|
||||||
|
Shortcut* shortcut = potentials.front().second;
|
||||||
|
|
||||||
|
if (shortcut->getModifierStatus() && shortcut->getSecondaryMode() == Shortcut::SM_Replace)
|
||||||
|
{
|
||||||
|
shortcut->setActivationStatus(Shortcut::AS_Secondary);
|
||||||
|
shortcut->signalSecondary(true);
|
||||||
|
shortcut->signalSecondary();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shortcut->setActivationStatus(Shortcut::AS_Regular);
|
||||||
|
shortcut->signalActivated(true);
|
||||||
|
shortcut->signalActivated();
|
||||||
|
}
|
||||||
|
|
||||||
|
used = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return used;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShortcutEventHandler::deactivate(QWidget* widget, unsigned int mod, unsigned int button)
|
||||||
|
{
|
||||||
|
const int KeyMask = 0x01FFFFFF;
|
||||||
|
|
||||||
|
bool used = false;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
shortcut->setPosition(0);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShortcutEventHandler::checkModifier(unsigned int mod, unsigned int button, Shortcut* shortcut, bool activate)
|
||||||
|
{
|
||||||
|
if (!shortcut->isEnabled() || !shortcut->getModifier() || shortcut->getSecondaryMode() == Shortcut::SM_Ignore ||
|
||||||
|
shortcut->getModifierStatus() == activate)
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
shortcut->signalSecondary(true);
|
||||||
|
shortcut->signalSecondary();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shortcut->signalSecondary(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!activate && shortcut->getActivationStatus() == Shortcut::AS_Secondary)
|
||||||
|
{
|
||||||
|
shortcut->setActivationStatus(Shortcut::AS_Inactive);
|
||||||
|
shortcut->setPosition(0);
|
||||||
|
shortcut->signalSecondary(false);
|
||||||
|
used = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return used;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShortcutEventHandler::MatchResult ShortcutEventHandler::match(unsigned int mod, unsigned int button,
|
||||||
|
unsigned int value)
|
||||||
|
{
|
||||||
|
if ((mod | button) == value)
|
||||||
|
{
|
||||||
|
return Matches_WithMod;
|
||||||
|
}
|
||||||
|
else if (button == value)
|
||||||
|
{
|
||||||
|
return Matches_NoMod;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Matches_Not;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShortcutEventHandler::sort(const std::pair<MatchResult, Shortcut*>& left,
|
||||||
|
const std::pair<MatchResult, Shortcut*>& right)
|
||||||
|
{
|
||||||
|
if (left.first == Matches_WithMod && 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);
|
||||||
|
}
|
||||||
|
}
|
69
apps/opencs/model/prefs/shortcuteventhandler.hpp
Normal file
69
apps/opencs/model/prefs/shortcuteventhandler.hpp
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#ifndef CSM_PREFS_SHORTCUT_EVENT_HANDLER_H
|
||||||
|
#define CSM_PREFS_SHORTCUT_EVENT_HANDLER_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class QEvent;
|
||||||
|
class QWidget;
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class Shortcut;
|
||||||
|
|
||||||
|
/// Users of this class should install it as an event handler
|
||||||
|
class ShortcutEventHandler : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ShortcutEventHandler(QObject* parent);
|
||||||
|
|
||||||
|
void addShortcut(Shortcut* shortcut);
|
||||||
|
void removeShortcut(Shortcut* shortcut);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool eventFilter(QObject* watched, QEvent* event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
typedef std::vector<Shortcut*> ShortcutList;
|
||||||
|
// Child, Parent
|
||||||
|
typedef std::map<QWidget*, QWidget*> WidgetMap;
|
||||||
|
typedef std::map<QWidget*, ShortcutList> ShortcutMap;
|
||||||
|
|
||||||
|
enum MatchResult
|
||||||
|
{
|
||||||
|
Matches_WithMod,
|
||||||
|
Matches_NoMod,
|
||||||
|
Matches_Not
|
||||||
|
};
|
||||||
|
|
||||||
|
void updateParent(QWidget* widget);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
MatchResult match(unsigned int mod, unsigned int button, unsigned int value);
|
||||||
|
|
||||||
|
// Prefers Matches_WithMod and a larger number of buttons
|
||||||
|
static bool sort(const std::pair<MatchResult, Shortcut*>& left,
|
||||||
|
const std::pair<MatchResult, Shortcut*>& right);
|
||||||
|
|
||||||
|
WidgetMap mChildParentRelations;
|
||||||
|
ShortcutMap mWidgetShortcuts;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void widgetDestroyed();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
791
apps/opencs/model/prefs/shortcutmanager.cpp
Normal file
791
apps/opencs/model/prefs/shortcutmanager.cpp
Normal file
|
@ -0,0 +1,791 @@
|
||||||
|
#include "shortcutmanager.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
#include "shortcut.hpp"
|
||||||
|
#include "shortcuteventhandler.hpp"
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
ShortcutManager::ShortcutManager()
|
||||||
|
{
|
||||||
|
createLookupTables();
|
||||||
|
mEventHandler = new ShortcutEventHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutManager::addShortcut(Shortcut* shortcut)
|
||||||
|
{
|
||||||
|
mShortcuts.insert(std::make_pair(shortcut->getName(), shortcut));
|
||||||
|
mShortcuts.insert(std::make_pair(shortcut->getModifierName(), shortcut));
|
||||||
|
mEventHandler->addShortcut(shortcut);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutManager::removeShortcut(Shortcut* shortcut)
|
||||||
|
{
|
||||||
|
std::pair<ShortcutMap::iterator, ShortcutMap::iterator> range = mShortcuts.equal_range(shortcut->getName());
|
||||||
|
|
||||||
|
for (ShortcutMap::iterator it = range.first; it != range.second;)
|
||||||
|
{
|
||||||
|
if (it->second == shortcut)
|
||||||
|
{
|
||||||
|
mShortcuts.erase(it++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mEventHandler->removeShortcut(shortcut);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShortcutManager::getSequence(const std::string& name, QKeySequence& sequence) const
|
||||||
|
{
|
||||||
|
SequenceMap::const_iterator item = mSequences.find(name);
|
||||||
|
if (item != mSequences.end())
|
||||||
|
{
|
||||||
|
sequence = item->second;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutManager::setSequence(const std::string& name, const QKeySequence& sequence)
|
||||||
|
{
|
||||||
|
// Add to map/modify
|
||||||
|
SequenceMap::iterator item = mSequences.find(name);
|
||||||
|
if (item != mSequences.end())
|
||||||
|
{
|
||||||
|
item->second = sequence;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mSequences.insert(std::make_pair(name, sequence));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change active shortcuts
|
||||||
|
std::pair<ShortcutMap::iterator, ShortcutMap::iterator> rangeS = mShortcuts.equal_range(name);
|
||||||
|
|
||||||
|
for (ShortcutMap::iterator it = rangeS.first; it != rangeS.second; ++it)
|
||||||
|
{
|
||||||
|
it->second->setSequence(sequence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShortcutManager::getModifier(const std::string& name, int& modifier) const
|
||||||
|
{
|
||||||
|
ModifierMap::const_iterator item = mModifiers.find(name);
|
||||||
|
if (item != mModifiers.end())
|
||||||
|
{
|
||||||
|
modifier = item->second;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutManager::setModifier(const std::string& name, int modifier)
|
||||||
|
{
|
||||||
|
// Add to map/modify
|
||||||
|
ModifierMap::iterator item = mModifiers.find(name);
|
||||||
|
if (item != mModifiers.end())
|
||||||
|
{
|
||||||
|
item->second = modifier;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mModifiers.insert(std::make_pair(name, modifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change active shortcuts
|
||||||
|
std::pair<ShortcutMap::iterator, ShortcutMap::iterator> rangeS = mShortcuts.equal_range(name);
|
||||||
|
|
||||||
|
for (ShortcutMap::iterator it = rangeS.first; it != rangeS.second; ++it)
|
||||||
|
{
|
||||||
|
it->second->setModifier(modifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ShortcutManager::convertToString(const QKeySequence& sequence) const
|
||||||
|
{
|
||||||
|
const int MouseKeyMask = 0x01FFFFFF;
|
||||||
|
const int ModMask = 0x7E000000;
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)sequence.count(); ++i)
|
||||||
|
{
|
||||||
|
int mods = sequence[i] & ModMask;
|
||||||
|
int key = sequence[i] & MouseKeyMask;
|
||||||
|
|
||||||
|
if (key)
|
||||||
|
{
|
||||||
|
NameMap::const_iterator searchResult = mNames.find(key);
|
||||||
|
if (searchResult != mNames.end())
|
||||||
|
{
|
||||||
|
if (mods && i == 0)
|
||||||
|
{
|
||||||
|
if (mods & Qt::ControlModifier)
|
||||||
|
result.append("Ctl+");
|
||||||
|
if (mods & Qt::ShiftModifier)
|
||||||
|
result.append("Shift+");
|
||||||
|
if (mods & Qt::AltModifier)
|
||||||
|
result.append("Alt+");
|
||||||
|
if (mods & Qt::MetaModifier)
|
||||||
|
result.append("Meta+");
|
||||||
|
if (mods & Qt::KeypadModifier)
|
||||||
|
result.append("Keypad+");
|
||||||
|
if (mods & Qt::GroupSwitchModifier)
|
||||||
|
result.append("GroupSwitch+");
|
||||||
|
}
|
||||||
|
else if (i > 0)
|
||||||
|
{
|
||||||
|
result.append("+");
|
||||||
|
}
|
||||||
|
|
||||||
|
result.append(searchResult->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ShortcutManager::convertToString(int modifier) const
|
||||||
|
{
|
||||||
|
NameMap::const_iterator searchResult = mNames.find(modifier);
|
||||||
|
if (searchResult != mNames.end())
|
||||||
|
{
|
||||||
|
return searchResult->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ShortcutManager::convertToString(const QKeySequence& sequence, int modifier) const
|
||||||
|
{
|
||||||
|
std::string concat = convertToString(sequence) + ";" + convertToString(modifier);
|
||||||
|
return concat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutManager::convertFromString(const std::string& data, QKeySequence& sequence) const
|
||||||
|
{
|
||||||
|
const int MaxKeys = 4; // A limitation of QKeySequence
|
||||||
|
|
||||||
|
size_t end = data.find(";");
|
||||||
|
size_t size = std::min(end, data.size());
|
||||||
|
|
||||||
|
std::string value = data.substr(0, size);
|
||||||
|
size_t start = 0;
|
||||||
|
|
||||||
|
int keyPos = 0;
|
||||||
|
int mods = 0;
|
||||||
|
|
||||||
|
int keys[MaxKeys] = {};
|
||||||
|
|
||||||
|
while (start < value.size())
|
||||||
|
{
|
||||||
|
end = data.find("+", start);
|
||||||
|
end = std::min(end, value.size());
|
||||||
|
|
||||||
|
std::string name = value.substr(start, end - start);
|
||||||
|
|
||||||
|
if (name == "Ctl")
|
||||||
|
{
|
||||||
|
mods |= Qt::ControlModifier;
|
||||||
|
}
|
||||||
|
else if (name == "Shift")
|
||||||
|
{
|
||||||
|
mods |= Qt::ShiftModifier;
|
||||||
|
}
|
||||||
|
else if (name == "Alt")
|
||||||
|
{
|
||||||
|
mods |= Qt::AltModifier;
|
||||||
|
}
|
||||||
|
else if (name == "Meta")
|
||||||
|
{
|
||||||
|
mods |= Qt::MetaModifier;
|
||||||
|
}
|
||||||
|
else if (name == "Keypad")
|
||||||
|
{
|
||||||
|
mods |= Qt::KeypadModifier;
|
||||||
|
}
|
||||||
|
else if (name == "GroupSwitch")
|
||||||
|
{
|
||||||
|
mods |= Qt::GroupSwitchModifier;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KeyMap::const_iterator searchResult = mKeys.find(name);
|
||||||
|
if (searchResult != mKeys.end())
|
||||||
|
{
|
||||||
|
keys[keyPos] = mods | searchResult->second;
|
||||||
|
|
||||||
|
mods = 0;
|
||||||
|
keyPos += 1;
|
||||||
|
|
||||||
|
if (keyPos >= MaxKeys)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start = end + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sequence = QKeySequence(keys[0], keys[1], keys[2], keys[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutManager::convertFromString(const std::string& data, int& modifier) const
|
||||||
|
{
|
||||||
|
size_t start = data.find(";") + 1;
|
||||||
|
start = std::min(start, data.size());
|
||||||
|
|
||||||
|
std::string name = data.substr(start);
|
||||||
|
KeyMap::const_iterator searchResult = mKeys.find(name);
|
||||||
|
if (searchResult != mKeys.end())
|
||||||
|
{
|
||||||
|
modifier = searchResult->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
modifier = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutManager::convertFromString(const std::string& data, QKeySequence& sequence, int& modifier) const
|
||||||
|
{
|
||||||
|
convertFromString(data, sequence);
|
||||||
|
convertFromString(data, modifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutManager::createLookupTables()
|
||||||
|
{
|
||||||
|
// Mouse buttons
|
||||||
|
mNames.insert(std::make_pair(Qt::LeftButton, "LMB"));
|
||||||
|
mNames.insert(std::make_pair(Qt::RightButton, "RMB"));
|
||||||
|
mNames.insert(std::make_pair(Qt::MiddleButton, "MMB"));
|
||||||
|
mNames.insert(std::make_pair(Qt::XButton1, "Mouse4"));
|
||||||
|
mNames.insert(std::make_pair(Qt::XButton2, "Mouse5"));
|
||||||
|
|
||||||
|
// Keyboard buttons
|
||||||
|
for (size_t i = 0; QtKeys[i].first != 0; ++i)
|
||||||
|
{
|
||||||
|
mNames.insert(QtKeys[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate inverse map
|
||||||
|
for (NameMap::const_iterator it = mNames.begin(); it != mNames.end(); ++it)
|
||||||
|
{
|
||||||
|
mKeys.insert(std::make_pair(it->second, it->first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ShortcutManager::processToolTip(const QString& toolTip) const
|
||||||
|
{
|
||||||
|
const QChar SequenceStart = '{';
|
||||||
|
const QChar SequenceEnd = '}';
|
||||||
|
|
||||||
|
QStringList substrings;
|
||||||
|
|
||||||
|
int prevIndex = 0;
|
||||||
|
int startIndex = toolTip.indexOf(SequenceStart);
|
||||||
|
int endIndex = (startIndex != -1) ? toolTip.indexOf(SequenceEnd, startIndex) : -1;
|
||||||
|
|
||||||
|
// Process every valid shortcut escape sequence
|
||||||
|
while (startIndex != -1 && endIndex != -1)
|
||||||
|
{
|
||||||
|
int count = startIndex - prevIndex;
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
substrings.push_back(toolTip.mid(prevIndex, count));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find sequence name
|
||||||
|
startIndex += 1; // '{' character
|
||||||
|
count = endIndex - startIndex;
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
QString settingName = toolTip.mid(startIndex, count);
|
||||||
|
|
||||||
|
QKeySequence sequence;
|
||||||
|
int modifier;
|
||||||
|
|
||||||
|
if (getSequence(settingName.toUtf8().data(), sequence))
|
||||||
|
{
|
||||||
|
QString value = QString::fromUtf8(convertToString(sequence).c_str());
|
||||||
|
substrings.push_back(value);
|
||||||
|
}
|
||||||
|
else if (getModifier(settingName.toUtf8().data(), modifier))
|
||||||
|
{
|
||||||
|
QString value = QString::fromUtf8(convertToString(modifier).c_str());
|
||||||
|
substrings.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
prevIndex = endIndex + 1; // '}' character
|
||||||
|
}
|
||||||
|
|
||||||
|
startIndex = toolTip.indexOf(SequenceStart, endIndex);
|
||||||
|
endIndex = (startIndex != -1) ? toolTip.indexOf(SequenceEnd, startIndex) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevIndex < toolTip.size())
|
||||||
|
{
|
||||||
|
substrings.push_back(toolTip.mid(prevIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
return substrings.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::pair<int, const char*> ShortcutManager::QtKeys[] =
|
||||||
|
{
|
||||||
|
std::make_pair((int)Qt::Key_Space , "Space"),
|
||||||
|
std::make_pair((int)Qt::Key_Exclam , "Exclam"),
|
||||||
|
std::make_pair((int)Qt::Key_QuoteDbl , "QuoteDbl"),
|
||||||
|
std::make_pair((int)Qt::Key_NumberSign , "NumberSign"),
|
||||||
|
std::make_pair((int)Qt::Key_Dollar , "Dollar"),
|
||||||
|
std::make_pair((int)Qt::Key_Percent , "Percent"),
|
||||||
|
std::make_pair((int)Qt::Key_Ampersand , "Ampersand"),
|
||||||
|
std::make_pair((int)Qt::Key_Apostrophe , "Apostrophe"),
|
||||||
|
std::make_pair((int)Qt::Key_ParenLeft , "ParenLeft"),
|
||||||
|
std::make_pair((int)Qt::Key_ParenRight , "ParenRight"),
|
||||||
|
std::make_pair((int)Qt::Key_Asterisk , "Asterisk"),
|
||||||
|
std::make_pair((int)Qt::Key_Plus , "Plus"),
|
||||||
|
std::make_pair((int)Qt::Key_Comma , "Comma"),
|
||||||
|
std::make_pair((int)Qt::Key_Minus , "Minus"),
|
||||||
|
std::make_pair((int)Qt::Key_Period , "Period"),
|
||||||
|
std::make_pair((int)Qt::Key_Slash , "Slash"),
|
||||||
|
std::make_pair((int)Qt::Key_0 , "0"),
|
||||||
|
std::make_pair((int)Qt::Key_1 , "1"),
|
||||||
|
std::make_pair((int)Qt::Key_2 , "2"),
|
||||||
|
std::make_pair((int)Qt::Key_3 , "3"),
|
||||||
|
std::make_pair((int)Qt::Key_4 , "4"),
|
||||||
|
std::make_pair((int)Qt::Key_5 , "5"),
|
||||||
|
std::make_pair((int)Qt::Key_6 , "6"),
|
||||||
|
std::make_pair((int)Qt::Key_7 , "7"),
|
||||||
|
std::make_pair((int)Qt::Key_8 , "8"),
|
||||||
|
std::make_pair((int)Qt::Key_9 , "9"),
|
||||||
|
std::make_pair((int)Qt::Key_Colon , "Colon"),
|
||||||
|
std::make_pair((int)Qt::Key_Semicolon , "Semicolon"),
|
||||||
|
std::make_pair((int)Qt::Key_Less , "Less"),
|
||||||
|
std::make_pair((int)Qt::Key_Equal , "Equal"),
|
||||||
|
std::make_pair((int)Qt::Key_Greater , "Greater"),
|
||||||
|
std::make_pair((int)Qt::Key_Question , "Question"),
|
||||||
|
std::make_pair((int)Qt::Key_At , "At"),
|
||||||
|
std::make_pair((int)Qt::Key_A , "A"),
|
||||||
|
std::make_pair((int)Qt::Key_B , "B"),
|
||||||
|
std::make_pair((int)Qt::Key_C , "C"),
|
||||||
|
std::make_pair((int)Qt::Key_D , "D"),
|
||||||
|
std::make_pair((int)Qt::Key_E , "E"),
|
||||||
|
std::make_pair((int)Qt::Key_F , "F"),
|
||||||
|
std::make_pair((int)Qt::Key_G , "G"),
|
||||||
|
std::make_pair((int)Qt::Key_H , "H"),
|
||||||
|
std::make_pair((int)Qt::Key_I , "I"),
|
||||||
|
std::make_pair((int)Qt::Key_J , "J"),
|
||||||
|
std::make_pair((int)Qt::Key_K , "K"),
|
||||||
|
std::make_pair((int)Qt::Key_L , "L"),
|
||||||
|
std::make_pair((int)Qt::Key_M , "M"),
|
||||||
|
std::make_pair((int)Qt::Key_N , "N"),
|
||||||
|
std::make_pair((int)Qt::Key_O , "O"),
|
||||||
|
std::make_pair((int)Qt::Key_P , "P"),
|
||||||
|
std::make_pair((int)Qt::Key_Q , "Q"),
|
||||||
|
std::make_pair((int)Qt::Key_R , "R"),
|
||||||
|
std::make_pair((int)Qt::Key_S , "S"),
|
||||||
|
std::make_pair((int)Qt::Key_T , "T"),
|
||||||
|
std::make_pair((int)Qt::Key_U , "U"),
|
||||||
|
std::make_pair((int)Qt::Key_V , "V"),
|
||||||
|
std::make_pair((int)Qt::Key_W , "W"),
|
||||||
|
std::make_pair((int)Qt::Key_X , "X"),
|
||||||
|
std::make_pair((int)Qt::Key_Y , "Y"),
|
||||||
|
std::make_pair((int)Qt::Key_Z , "Z"),
|
||||||
|
std::make_pair((int)Qt::Key_BracketLeft , "BracketLeft"),
|
||||||
|
std::make_pair((int)Qt::Key_Backslash , "Backslash"),
|
||||||
|
std::make_pair((int)Qt::Key_BracketRight , "BracketRight"),
|
||||||
|
std::make_pair((int)Qt::Key_AsciiCircum , "AsciiCircum"),
|
||||||
|
std::make_pair((int)Qt::Key_Underscore , "Underscore"),
|
||||||
|
std::make_pair((int)Qt::Key_QuoteLeft , "QuoteLeft"),
|
||||||
|
std::make_pair((int)Qt::Key_BraceLeft , "BraceLeft"),
|
||||||
|
std::make_pair((int)Qt::Key_Bar , "Bar"),
|
||||||
|
std::make_pair((int)Qt::Key_BraceRight , "BraceRight"),
|
||||||
|
std::make_pair((int)Qt::Key_AsciiTilde , "AsciiTilde"),
|
||||||
|
std::make_pair((int)Qt::Key_nobreakspace , "nobreakspace"),
|
||||||
|
std::make_pair((int)Qt::Key_exclamdown , "exclamdown"),
|
||||||
|
std::make_pair((int)Qt::Key_cent , "cent"),
|
||||||
|
std::make_pair((int)Qt::Key_sterling , "sterling"),
|
||||||
|
std::make_pair((int)Qt::Key_currency , "currency"),
|
||||||
|
std::make_pair((int)Qt::Key_yen , "yen"),
|
||||||
|
std::make_pair((int)Qt::Key_brokenbar , "brokenbar"),
|
||||||
|
std::make_pair((int)Qt::Key_section , "section"),
|
||||||
|
std::make_pair((int)Qt::Key_diaeresis , "diaeresis"),
|
||||||
|
std::make_pair((int)Qt::Key_copyright , "copyright"),
|
||||||
|
std::make_pair((int)Qt::Key_ordfeminine , "ordfeminine"),
|
||||||
|
std::make_pair((int)Qt::Key_guillemotleft , "guillemotleft"),
|
||||||
|
std::make_pair((int)Qt::Key_notsign , "notsign"),
|
||||||
|
std::make_pair((int)Qt::Key_hyphen , "hyphen"),
|
||||||
|
std::make_pair((int)Qt::Key_registered , "registered"),
|
||||||
|
std::make_pair((int)Qt::Key_macron , "macron"),
|
||||||
|
std::make_pair((int)Qt::Key_degree , "degree"),
|
||||||
|
std::make_pair((int)Qt::Key_plusminus , "plusminus"),
|
||||||
|
std::make_pair((int)Qt::Key_twosuperior , "twosuperior"),
|
||||||
|
std::make_pair((int)Qt::Key_threesuperior , "threesuperior"),
|
||||||
|
std::make_pair((int)Qt::Key_acute , "acute"),
|
||||||
|
std::make_pair((int)Qt::Key_mu , "mu"),
|
||||||
|
std::make_pair((int)Qt::Key_paragraph , "paragraph"),
|
||||||
|
std::make_pair((int)Qt::Key_periodcentered , "periodcentered"),
|
||||||
|
std::make_pair((int)Qt::Key_cedilla , "cedilla"),
|
||||||
|
std::make_pair((int)Qt::Key_onesuperior , "onesuperior"),
|
||||||
|
std::make_pair((int)Qt::Key_masculine , "masculine"),
|
||||||
|
std::make_pair((int)Qt::Key_guillemotright , "guillemotright"),
|
||||||
|
std::make_pair((int)Qt::Key_onequarter , "onequarter"),
|
||||||
|
std::make_pair((int)Qt::Key_onehalf , "onehalf"),
|
||||||
|
std::make_pair((int)Qt::Key_threequarters , "threequarters"),
|
||||||
|
std::make_pair((int)Qt::Key_questiondown , "questiondown"),
|
||||||
|
std::make_pair((int)Qt::Key_Agrave , "Agrave"),
|
||||||
|
std::make_pair((int)Qt::Key_Aacute , "Aacute"),
|
||||||
|
std::make_pair((int)Qt::Key_Acircumflex , "Acircumflex"),
|
||||||
|
std::make_pair((int)Qt::Key_Atilde , "Atilde"),
|
||||||
|
std::make_pair((int)Qt::Key_Adiaeresis , "Adiaeresis"),
|
||||||
|
std::make_pair((int)Qt::Key_Aring , "Aring"),
|
||||||
|
std::make_pair((int)Qt::Key_AE , "AE"),
|
||||||
|
std::make_pair((int)Qt::Key_Ccedilla , "Ccedilla"),
|
||||||
|
std::make_pair((int)Qt::Key_Egrave , "Egrave"),
|
||||||
|
std::make_pair((int)Qt::Key_Eacute , "Eacute"),
|
||||||
|
std::make_pair((int)Qt::Key_Ecircumflex , "Ecircumflex"),
|
||||||
|
std::make_pair((int)Qt::Key_Ediaeresis , "Ediaeresis"),
|
||||||
|
std::make_pair((int)Qt::Key_Igrave , "Igrave"),
|
||||||
|
std::make_pair((int)Qt::Key_Iacute , "Iacute"),
|
||||||
|
std::make_pair((int)Qt::Key_Icircumflex , "Icircumflex"),
|
||||||
|
std::make_pair((int)Qt::Key_Idiaeresis , "Idiaeresis"),
|
||||||
|
std::make_pair((int)Qt::Key_ETH , "ETH"),
|
||||||
|
std::make_pair((int)Qt::Key_Ntilde , "Ntilde"),
|
||||||
|
std::make_pair((int)Qt::Key_Ograve , "Ograve"),
|
||||||
|
std::make_pair((int)Qt::Key_Oacute , "Oacute"),
|
||||||
|
std::make_pair((int)Qt::Key_Ocircumflex , "Ocircumflex"),
|
||||||
|
std::make_pair((int)Qt::Key_Otilde , "Otilde"),
|
||||||
|
std::make_pair((int)Qt::Key_Odiaeresis , "Odiaeresis"),
|
||||||
|
std::make_pair((int)Qt::Key_multiply , "multiply"),
|
||||||
|
std::make_pair((int)Qt::Key_Ooblique , "Ooblique"),
|
||||||
|
std::make_pair((int)Qt::Key_Ugrave , "Ugrave"),
|
||||||
|
std::make_pair((int)Qt::Key_Uacute , "Uacute"),
|
||||||
|
std::make_pair((int)Qt::Key_Ucircumflex , "Ucircumflex"),
|
||||||
|
std::make_pair((int)Qt::Key_Udiaeresis , "Udiaeresis"),
|
||||||
|
std::make_pair((int)Qt::Key_Yacute , "Yacute"),
|
||||||
|
std::make_pair((int)Qt::Key_THORN , "THORN"),
|
||||||
|
std::make_pair((int)Qt::Key_ssharp , "ssharp"),
|
||||||
|
std::make_pair((int)Qt::Key_division , "division"),
|
||||||
|
std::make_pair((int)Qt::Key_ydiaeresis , "ydiaeresis"),
|
||||||
|
std::make_pair((int)Qt::Key_Escape , "Escape"),
|
||||||
|
std::make_pair((int)Qt::Key_Tab , "Tab"),
|
||||||
|
std::make_pair((int)Qt::Key_Backtab , "Backtab"),
|
||||||
|
std::make_pair((int)Qt::Key_Backspace , "Backspace"),
|
||||||
|
std::make_pair((int)Qt::Key_Return , "Return"),
|
||||||
|
std::make_pair((int)Qt::Key_Enter , "Enter"),
|
||||||
|
std::make_pair((int)Qt::Key_Insert , "Insert"),
|
||||||
|
std::make_pair((int)Qt::Key_Delete , "Delete"),
|
||||||
|
std::make_pair((int)Qt::Key_Pause , "Pause"),
|
||||||
|
std::make_pair((int)Qt::Key_Print , "Print"),
|
||||||
|
std::make_pair((int)Qt::Key_SysReq , "SysReq"),
|
||||||
|
std::make_pair((int)Qt::Key_Clear , "Clear"),
|
||||||
|
std::make_pair((int)Qt::Key_Home , "Home"),
|
||||||
|
std::make_pair((int)Qt::Key_End , "End"),
|
||||||
|
std::make_pair((int)Qt::Key_Left , "Left"),
|
||||||
|
std::make_pair((int)Qt::Key_Up , "Up"),
|
||||||
|
std::make_pair((int)Qt::Key_Right , "Right"),
|
||||||
|
std::make_pair((int)Qt::Key_Down , "Down"),
|
||||||
|
std::make_pair((int)Qt::Key_PageUp , "PageUp"),
|
||||||
|
std::make_pair((int)Qt::Key_PageDown , "PageDown"),
|
||||||
|
std::make_pair((int)Qt::Key_Shift , "Shift"),
|
||||||
|
std::make_pair((int)Qt::Key_Control , "Control"),
|
||||||
|
std::make_pair((int)Qt::Key_Meta , "Meta"),
|
||||||
|
std::make_pair((int)Qt::Key_Alt , "Alt"),
|
||||||
|
std::make_pair((int)Qt::Key_CapsLock , "CapsLock"),
|
||||||
|
std::make_pair((int)Qt::Key_NumLock , "NumLock"),
|
||||||
|
std::make_pair((int)Qt::Key_ScrollLock , "ScrollLock"),
|
||||||
|
std::make_pair((int)Qt::Key_F1 , "F1"),
|
||||||
|
std::make_pair((int)Qt::Key_F2 , "F2"),
|
||||||
|
std::make_pair((int)Qt::Key_F3 , "F3"),
|
||||||
|
std::make_pair((int)Qt::Key_F4 , "F4"),
|
||||||
|
std::make_pair((int)Qt::Key_F5 , "F5"),
|
||||||
|
std::make_pair((int)Qt::Key_F6 , "F6"),
|
||||||
|
std::make_pair((int)Qt::Key_F7 , "F7"),
|
||||||
|
std::make_pair((int)Qt::Key_F8 , "F8"),
|
||||||
|
std::make_pair((int)Qt::Key_F9 , "F9"),
|
||||||
|
std::make_pair((int)Qt::Key_F10 , "F10"),
|
||||||
|
std::make_pair((int)Qt::Key_F11 , "F11"),
|
||||||
|
std::make_pair((int)Qt::Key_F12 , "F12"),
|
||||||
|
std::make_pair((int)Qt::Key_F13 , "F13"),
|
||||||
|
std::make_pair((int)Qt::Key_F14 , "F14"),
|
||||||
|
std::make_pair((int)Qt::Key_F15 , "F15"),
|
||||||
|
std::make_pair((int)Qt::Key_F16 , "F16"),
|
||||||
|
std::make_pair((int)Qt::Key_F17 , "F17"),
|
||||||
|
std::make_pair((int)Qt::Key_F18 , "F18"),
|
||||||
|
std::make_pair((int)Qt::Key_F19 , "F19"),
|
||||||
|
std::make_pair((int)Qt::Key_F20 , "F20"),
|
||||||
|
std::make_pair((int)Qt::Key_F21 , "F21"),
|
||||||
|
std::make_pair((int)Qt::Key_F22 , "F22"),
|
||||||
|
std::make_pair((int)Qt::Key_F23 , "F23"),
|
||||||
|
std::make_pair((int)Qt::Key_F24 , "F24"),
|
||||||
|
std::make_pair((int)Qt::Key_F25 , "F25"),
|
||||||
|
std::make_pair((int)Qt::Key_F26 , "F26"),
|
||||||
|
std::make_pair((int)Qt::Key_F27 , "F27"),
|
||||||
|
std::make_pair((int)Qt::Key_F28 , "F28"),
|
||||||
|
std::make_pair((int)Qt::Key_F29 , "F29"),
|
||||||
|
std::make_pair((int)Qt::Key_F30 , "F30"),
|
||||||
|
std::make_pair((int)Qt::Key_F31 , "F31"),
|
||||||
|
std::make_pair((int)Qt::Key_F32 , "F32"),
|
||||||
|
std::make_pair((int)Qt::Key_F33 , "F33"),
|
||||||
|
std::make_pair((int)Qt::Key_F34 , "F34"),
|
||||||
|
std::make_pair((int)Qt::Key_F35 , "F35"),
|
||||||
|
std::make_pair((int)Qt::Key_Super_L , "Super_L"),
|
||||||
|
std::make_pair((int)Qt::Key_Super_R , "Super_R"),
|
||||||
|
std::make_pair((int)Qt::Key_Menu , "Menu"),
|
||||||
|
std::make_pair((int)Qt::Key_Hyper_L , "Hyper_L"),
|
||||||
|
std::make_pair((int)Qt::Key_Hyper_R , "Hyper_R"),
|
||||||
|
std::make_pair((int)Qt::Key_Help , "Help"),
|
||||||
|
std::make_pair((int)Qt::Key_Direction_L , "Direction_L"),
|
||||||
|
std::make_pair((int)Qt::Key_Direction_R , "Direction_R"),
|
||||||
|
std::make_pair((int)Qt::Key_Back , "Back"),
|
||||||
|
std::make_pair((int)Qt::Key_Forward , "Forward"),
|
||||||
|
std::make_pair((int)Qt::Key_Stop , "Stop"),
|
||||||
|
std::make_pair((int)Qt::Key_Refresh , "Refresh"),
|
||||||
|
std::make_pair((int)Qt::Key_VolumeDown , "VolumeDown"),
|
||||||
|
std::make_pair((int)Qt::Key_VolumeMute , "VolumeMute"),
|
||||||
|
std::make_pair((int)Qt::Key_VolumeUp , "VolumeUp"),
|
||||||
|
std::make_pair((int)Qt::Key_BassBoost , "BassBoost"),
|
||||||
|
std::make_pair((int)Qt::Key_BassUp , "BassUp"),
|
||||||
|
std::make_pair((int)Qt::Key_BassDown , "BassDown"),
|
||||||
|
std::make_pair((int)Qt::Key_TrebleUp , "TrebleUp"),
|
||||||
|
std::make_pair((int)Qt::Key_TrebleDown , "TrebleDown"),
|
||||||
|
std::make_pair((int)Qt::Key_MediaPlay , "MediaPlay"),
|
||||||
|
std::make_pair((int)Qt::Key_MediaStop , "MediaStop"),
|
||||||
|
std::make_pair((int)Qt::Key_MediaPrevious , "MediaPrevious"),
|
||||||
|
std::make_pair((int)Qt::Key_MediaNext , "MediaNext"),
|
||||||
|
std::make_pair((int)Qt::Key_MediaRecord , "MediaRecord"),
|
||||||
|
std::make_pair((int)Qt::Key_MediaPause , "MediaPause"),
|
||||||
|
std::make_pair((int)Qt::Key_MediaTogglePlayPause , "MediaTogglePlayPause"),
|
||||||
|
std::make_pair((int)Qt::Key_HomePage , "HomePage"),
|
||||||
|
std::make_pair((int)Qt::Key_Favorites , "Favorites"),
|
||||||
|
std::make_pair((int)Qt::Key_Search , "Search"),
|
||||||
|
std::make_pair((int)Qt::Key_Standby , "Standby"),
|
||||||
|
std::make_pair((int)Qt::Key_OpenUrl , "OpenUrl"),
|
||||||
|
std::make_pair((int)Qt::Key_LaunchMail , "LaunchMail"),
|
||||||
|
std::make_pair((int)Qt::Key_LaunchMedia , "LaunchMedia"),
|
||||||
|
std::make_pair((int)Qt::Key_Launch0 , "Launch0"),
|
||||||
|
std::make_pair((int)Qt::Key_Launch1 , "Launch1"),
|
||||||
|
std::make_pair((int)Qt::Key_Launch2 , "Launch2"),
|
||||||
|
std::make_pair((int)Qt::Key_Launch3 , "Launch3"),
|
||||||
|
std::make_pair((int)Qt::Key_Launch4 , "Launch4"),
|
||||||
|
std::make_pair((int)Qt::Key_Launch5 , "Launch5"),
|
||||||
|
std::make_pair((int)Qt::Key_Launch6 , "Launch6"),
|
||||||
|
std::make_pair((int)Qt::Key_Launch7 , "Launch7"),
|
||||||
|
std::make_pair((int)Qt::Key_Launch8 , "Launch8"),
|
||||||
|
std::make_pair((int)Qt::Key_Launch9 , "Launch9"),
|
||||||
|
std::make_pair((int)Qt::Key_LaunchA , "LaunchA"),
|
||||||
|
std::make_pair((int)Qt::Key_LaunchB , "LaunchB"),
|
||||||
|
std::make_pair((int)Qt::Key_LaunchC , "LaunchC"),
|
||||||
|
std::make_pair((int)Qt::Key_LaunchD , "LaunchD"),
|
||||||
|
std::make_pair((int)Qt::Key_LaunchE , "LaunchE"),
|
||||||
|
std::make_pair((int)Qt::Key_LaunchF , "LaunchF"),
|
||||||
|
std::make_pair((int)Qt::Key_MonBrightnessUp , "MonBrightnessUp"),
|
||||||
|
std::make_pair((int)Qt::Key_MonBrightnessDown , "MonBrightnessDown"),
|
||||||
|
std::make_pair((int)Qt::Key_KeyboardLightOnOff , "KeyboardLightOnOff"),
|
||||||
|
std::make_pair((int)Qt::Key_KeyboardBrightnessUp , "KeyboardBrightnessUp"),
|
||||||
|
std::make_pair((int)Qt::Key_KeyboardBrightnessDown , "KeyboardBrightnessDown"),
|
||||||
|
std::make_pair((int)Qt::Key_PowerOff , "PowerOff"),
|
||||||
|
std::make_pair((int)Qt::Key_WakeUp , "WakeUp"),
|
||||||
|
std::make_pair((int)Qt::Key_Eject , "Eject"),
|
||||||
|
std::make_pair((int)Qt::Key_ScreenSaver , "ScreenSaver"),
|
||||||
|
std::make_pair((int)Qt::Key_WWW , "WWW"),
|
||||||
|
std::make_pair((int)Qt::Key_Memo , "Memo"),
|
||||||
|
std::make_pair((int)Qt::Key_LightBulb , "LightBulb"),
|
||||||
|
std::make_pair((int)Qt::Key_Shop , "Shop"),
|
||||||
|
std::make_pair((int)Qt::Key_History , "History"),
|
||||||
|
std::make_pair((int)Qt::Key_AddFavorite , "AddFavorite"),
|
||||||
|
std::make_pair((int)Qt::Key_HotLinks , "HotLinks"),
|
||||||
|
std::make_pair((int)Qt::Key_BrightnessAdjust , "BrightnessAdjust"),
|
||||||
|
std::make_pair((int)Qt::Key_Finance , "Finance"),
|
||||||
|
std::make_pair((int)Qt::Key_Community , "Community"),
|
||||||
|
std::make_pair((int)Qt::Key_AudioRewind , "AudioRewind"),
|
||||||
|
std::make_pair((int)Qt::Key_BackForward , "BackForward"),
|
||||||
|
std::make_pair((int)Qt::Key_ApplicationLeft , "ApplicationLeft"),
|
||||||
|
std::make_pair((int)Qt::Key_ApplicationRight , "ApplicationRight"),
|
||||||
|
std::make_pair((int)Qt::Key_Book , "Book"),
|
||||||
|
std::make_pair((int)Qt::Key_CD , "CD"),
|
||||||
|
std::make_pair((int)Qt::Key_Calculator , "Calculator"),
|
||||||
|
std::make_pair((int)Qt::Key_ToDoList , "ToDoList"),
|
||||||
|
std::make_pair((int)Qt::Key_ClearGrab , "ClearGrab"),
|
||||||
|
std::make_pair((int)Qt::Key_Close , "Close"),
|
||||||
|
std::make_pair((int)Qt::Key_Copy , "Copy"),
|
||||||
|
std::make_pair((int)Qt::Key_Cut , "Cut"),
|
||||||
|
std::make_pair((int)Qt::Key_Display , "Display"),
|
||||||
|
std::make_pair((int)Qt::Key_DOS , "DOS"),
|
||||||
|
std::make_pair((int)Qt::Key_Documents , "Documents"),
|
||||||
|
std::make_pair((int)Qt::Key_Excel , "Excel"),
|
||||||
|
std::make_pair((int)Qt::Key_Explorer , "Explorer"),
|
||||||
|
std::make_pair((int)Qt::Key_Game , "Game"),
|
||||||
|
std::make_pair((int)Qt::Key_Go , "Go"),
|
||||||
|
std::make_pair((int)Qt::Key_iTouch , "iTouch"),
|
||||||
|
std::make_pair((int)Qt::Key_LogOff , "LogOff"),
|
||||||
|
std::make_pair((int)Qt::Key_Market , "Market"),
|
||||||
|
std::make_pair((int)Qt::Key_Meeting , "Meeting"),
|
||||||
|
std::make_pair((int)Qt::Key_MenuKB , "MenuKB"),
|
||||||
|
std::make_pair((int)Qt::Key_MenuPB , "MenuPB"),
|
||||||
|
std::make_pair((int)Qt::Key_MySites , "MySites"),
|
||||||
|
std::make_pair((int)Qt::Key_News , "News"),
|
||||||
|
std::make_pair((int)Qt::Key_OfficeHome , "OfficeHome"),
|
||||||
|
std::make_pair((int)Qt::Key_Option , "Option"),
|
||||||
|
std::make_pair((int)Qt::Key_Paste , "Paste"),
|
||||||
|
std::make_pair((int)Qt::Key_Phone , "Phone"),
|
||||||
|
std::make_pair((int)Qt::Key_Calendar , "Calendar"),
|
||||||
|
std::make_pair((int)Qt::Key_Reply , "Reply"),
|
||||||
|
std::make_pair((int)Qt::Key_Reload , "Reload"),
|
||||||
|
std::make_pair((int)Qt::Key_RotateWindows , "RotateWindows"),
|
||||||
|
std::make_pair((int)Qt::Key_RotationPB , "RotationPB"),
|
||||||
|
std::make_pair((int)Qt::Key_RotationKB , "RotationKB"),
|
||||||
|
std::make_pair((int)Qt::Key_Save , "Save"),
|
||||||
|
std::make_pair((int)Qt::Key_Send , "Send"),
|
||||||
|
std::make_pair((int)Qt::Key_Spell , "Spell"),
|
||||||
|
std::make_pair((int)Qt::Key_SplitScreen , "SplitScreen"),
|
||||||
|
std::make_pair((int)Qt::Key_Support , "Support"),
|
||||||
|
std::make_pair((int)Qt::Key_TaskPane , "TaskPane"),
|
||||||
|
std::make_pair((int)Qt::Key_Terminal , "Terminal"),
|
||||||
|
std::make_pair((int)Qt::Key_Tools , "Tools"),
|
||||||
|
std::make_pair((int)Qt::Key_Travel , "Travel"),
|
||||||
|
std::make_pair((int)Qt::Key_Video , "Video"),
|
||||||
|
std::make_pair((int)Qt::Key_Word , "Word"),
|
||||||
|
std::make_pair((int)Qt::Key_Xfer , "Xfer"),
|
||||||
|
std::make_pair((int)Qt::Key_ZoomIn , "ZoomIn"),
|
||||||
|
std::make_pair((int)Qt::Key_ZoomOut , "ZoomOut"),
|
||||||
|
std::make_pair((int)Qt::Key_Away , "Away"),
|
||||||
|
std::make_pair((int)Qt::Key_Messenger , "Messenger"),
|
||||||
|
std::make_pair((int)Qt::Key_WebCam , "WebCam"),
|
||||||
|
std::make_pair((int)Qt::Key_MailForward , "MailForward"),
|
||||||
|
std::make_pair((int)Qt::Key_Pictures , "Pictures"),
|
||||||
|
std::make_pair((int)Qt::Key_Music , "Music"),
|
||||||
|
std::make_pair((int)Qt::Key_Battery , "Battery"),
|
||||||
|
std::make_pair((int)Qt::Key_Bluetooth , "Bluetooth"),
|
||||||
|
std::make_pair((int)Qt::Key_WLAN , "WLAN"),
|
||||||
|
std::make_pair((int)Qt::Key_UWB , "UWB"),
|
||||||
|
std::make_pair((int)Qt::Key_AudioForward , "AudioForward"),
|
||||||
|
std::make_pair((int)Qt::Key_AudioRepeat , "AudioRepeat"),
|
||||||
|
std::make_pair((int)Qt::Key_AudioRandomPlay , "AudioRandomPlay"),
|
||||||
|
std::make_pair((int)Qt::Key_Subtitle , "Subtitle"),
|
||||||
|
std::make_pair((int)Qt::Key_AudioCycleTrack , "AudioCycleTrack"),
|
||||||
|
std::make_pair((int)Qt::Key_Time , "Time"),
|
||||||
|
std::make_pair((int)Qt::Key_Hibernate , "Hibernate"),
|
||||||
|
std::make_pair((int)Qt::Key_View , "View"),
|
||||||
|
std::make_pair((int)Qt::Key_TopMenu , "TopMenu"),
|
||||||
|
std::make_pair((int)Qt::Key_PowerDown , "PowerDown"),
|
||||||
|
std::make_pair((int)Qt::Key_Suspend , "Suspend"),
|
||||||
|
std::make_pair((int)Qt::Key_ContrastAdjust , "ContrastAdjust"),
|
||||||
|
std::make_pair((int)Qt::Key_LaunchG , "LaunchG"),
|
||||||
|
std::make_pair((int)Qt::Key_LaunchH , "LaunchH"),
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5,7,0)
|
||||||
|
std::make_pair((int)Qt::Key_TouchpadToggle , "TouchpadToggle"),
|
||||||
|
std::make_pair((int)Qt::Key_TouchpadOn , "TouchpadOn"),
|
||||||
|
std::make_pair((int)Qt::Key_TouchpadOff , "TouchpadOff"),
|
||||||
|
std::make_pair((int)Qt::Key_MicMute , "MicMute"),
|
||||||
|
std::make_pair((int)Qt::Key_Red , "Red"),
|
||||||
|
std::make_pair((int)Qt::Key_Green , "Green"),
|
||||||
|
std::make_pair((int)Qt::Key_Yellow , "Yellow"),
|
||||||
|
std::make_pair((int)Qt::Key_Blue , "Blue"),
|
||||||
|
std::make_pair((int)Qt::Key_ChannelUp , "ChannelUp"),
|
||||||
|
std::make_pair((int)Qt::Key_ChannelDown , "ChannelDown"),
|
||||||
|
std::make_pair((int)Qt::Key_Guide , "Guide"),
|
||||||
|
std::make_pair((int)Qt::Key_Info , "Info"),
|
||||||
|
std::make_pair((int)Qt::Key_Settings , "Settings"),
|
||||||
|
std::make_pair((int)Qt::Key_MicVolumeUp , "MicVolumeUp"),
|
||||||
|
std::make_pair((int)Qt::Key_MicVolumeDown , "MicVolumeDown"),
|
||||||
|
std::make_pair((int)Qt::Key_New , "New"),
|
||||||
|
std::make_pair((int)Qt::Key_Open , "Open"),
|
||||||
|
std::make_pair((int)Qt::Key_Find , "Find"),
|
||||||
|
std::make_pair((int)Qt::Key_Undo , "Undo"),
|
||||||
|
std::make_pair((int)Qt::Key_Redo , "Redo"),
|
||||||
|
#endif
|
||||||
|
std::make_pair((int)Qt::Key_AltGr , "AltGr"),
|
||||||
|
std::make_pair((int)Qt::Key_Multi_key , "Multi_key"),
|
||||||
|
std::make_pair((int)Qt::Key_Kanji , "Kanji"),
|
||||||
|
std::make_pair((int)Qt::Key_Muhenkan , "Muhenkan"),
|
||||||
|
std::make_pair((int)Qt::Key_Henkan , "Henkan"),
|
||||||
|
std::make_pair((int)Qt::Key_Romaji , "Romaji"),
|
||||||
|
std::make_pair((int)Qt::Key_Hiragana , "Hiragana"),
|
||||||
|
std::make_pair((int)Qt::Key_Katakana , "Katakana"),
|
||||||
|
std::make_pair((int)Qt::Key_Hiragana_Katakana , "Hiragana_Katakana"),
|
||||||
|
std::make_pair((int)Qt::Key_Zenkaku , "Zenkaku"),
|
||||||
|
std::make_pair((int)Qt::Key_Hankaku , "Hankaku"),
|
||||||
|
std::make_pair((int)Qt::Key_Zenkaku_Hankaku , "Zenkaku_Hankaku"),
|
||||||
|
std::make_pair((int)Qt::Key_Touroku , "Touroku"),
|
||||||
|
std::make_pair((int)Qt::Key_Massyo , "Massyo"),
|
||||||
|
std::make_pair((int)Qt::Key_Kana_Lock , "Kana_Lock"),
|
||||||
|
std::make_pair((int)Qt::Key_Kana_Shift , "Kana_Shift"),
|
||||||
|
std::make_pair((int)Qt::Key_Eisu_Shift , "Eisu_Shift"),
|
||||||
|
std::make_pair((int)Qt::Key_Eisu_toggle , "Eisu_toggle"),
|
||||||
|
std::make_pair((int)Qt::Key_Hangul , "Hangul"),
|
||||||
|
std::make_pair((int)Qt::Key_Hangul_Start , "Hangul_Start"),
|
||||||
|
std::make_pair((int)Qt::Key_Hangul_End , "Hangul_End"),
|
||||||
|
std::make_pair((int)Qt::Key_Hangul_Hanja , "Hangul_Hanja"),
|
||||||
|
std::make_pair((int)Qt::Key_Hangul_Jamo , "Hangul_Jamo"),
|
||||||
|
std::make_pair((int)Qt::Key_Hangul_Romaja , "Hangul_Romaja"),
|
||||||
|
std::make_pair((int)Qt::Key_Codeinput , "Codeinput"),
|
||||||
|
std::make_pair((int)Qt::Key_Hangul_Jeonja , "Hangul_Jeonja"),
|
||||||
|
std::make_pair((int)Qt::Key_Hangul_Banja , "Hangul_Banja"),
|
||||||
|
std::make_pair((int)Qt::Key_Hangul_PreHanja , "Hangul_PreHanja"),
|
||||||
|
std::make_pair((int)Qt::Key_Hangul_PostHanja , "Hangul_PostHanja"),
|
||||||
|
std::make_pair((int)Qt::Key_SingleCandidate , "SingleCandidate"),
|
||||||
|
std::make_pair((int)Qt::Key_MultipleCandidate , "MultipleCandidate"),
|
||||||
|
std::make_pair((int)Qt::Key_PreviousCandidate , "PreviousCandidate"),
|
||||||
|
std::make_pair((int)Qt::Key_Hangul_Special , "Hangul_Special"),
|
||||||
|
std::make_pair((int)Qt::Key_Mode_switch , "Mode_switch"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Grave , "Dead_Grave"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Acute , "Dead_Acute"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Circumflex , "Dead_Circumflex"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Tilde , "Dead_Tilde"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Macron , "Dead_Macron"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Breve , "Dead_Breve"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Abovedot , "Dead_Abovedot"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Diaeresis , "Dead_Diaeresis"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Abovering , "Dead_Abovering"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Doubleacute , "Dead_Doubleacute"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Caron , "Dead_Caron"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Cedilla , "Dead_Cedilla"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Ogonek , "Dead_Ogonek"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Iota , "Dead_Iota"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Voiced_Sound , "Dead_Voiced_Sound"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Semivoiced_Sound , "Dead_Semivoiced_Sound"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Belowdot , "Dead_Belowdot"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Hook , "Dead_Hook"),
|
||||||
|
std::make_pair((int)Qt::Key_Dead_Horn , "Dead_Horn"),
|
||||||
|
std::make_pair((int)Qt::Key_MediaLast , "MediaLast"),
|
||||||
|
std::make_pair((int)Qt::Key_Select , "Select"),
|
||||||
|
std::make_pair((int)Qt::Key_Yes , "Yes"),
|
||||||
|
std::make_pair((int)Qt::Key_No , "No"),
|
||||||
|
std::make_pair((int)Qt::Key_Cancel , "Cancel"),
|
||||||
|
std::make_pair((int)Qt::Key_Printer , "Printer"),
|
||||||
|
std::make_pair((int)Qt::Key_Execute , "Execute"),
|
||||||
|
std::make_pair((int)Qt::Key_Sleep , "Sleep"),
|
||||||
|
std::make_pair((int)Qt::Key_Play , "Play"),
|
||||||
|
std::make_pair((int)Qt::Key_Zoom , "Zoom"),
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5,7,0)
|
||||||
|
std::make_pair((int)Qt::Key_Exit , "Exit"),
|
||||||
|
#endif
|
||||||
|
std::make_pair((int)Qt::Key_Context1 , "Context1"),
|
||||||
|
std::make_pair((int)Qt::Key_Context2 , "Context2"),
|
||||||
|
std::make_pair((int)Qt::Key_Context3 , "Context3"),
|
||||||
|
std::make_pair((int)Qt::Key_Context4 , "Context4"),
|
||||||
|
std::make_pair((int)Qt::Key_Call , "Call"),
|
||||||
|
std::make_pair((int)Qt::Key_Hangup , "Hangup"),
|
||||||
|
std::make_pair((int)Qt::Key_Flip , "Flip"),
|
||||||
|
std::make_pair((int)Qt::Key_ToggleCallHangup , "ToggleCallHangup"),
|
||||||
|
std::make_pair((int)Qt::Key_VoiceDial , "VoiceDial"),
|
||||||
|
std::make_pair((int)Qt::Key_LastNumberRedial , "LastNumberRedial"),
|
||||||
|
std::make_pair((int)Qt::Key_Camera , "Camera"),
|
||||||
|
std::make_pair((int)Qt::Key_CameraFocus , "CameraFocus"),
|
||||||
|
std::make_pair(0 , (const char*) 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
73
apps/opencs/model/prefs/shortcutmanager.hpp
Normal file
73
apps/opencs/model/prefs/shortcutmanager.hpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#ifndef CSM_PREFS_SHORTCUTMANAGER_H
|
||||||
|
#define CSM_PREFS_SHORTCUTMANAGER_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <QKeySequence>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class Shortcut;
|
||||||
|
class ShortcutEventHandler;
|
||||||
|
|
||||||
|
/// Class used to track and update shortcuts/sequences
|
||||||
|
class ShortcutManager : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ShortcutManager();
|
||||||
|
|
||||||
|
/// The shortcut class will do this automatically
|
||||||
|
void addShortcut(Shortcut* shortcut);
|
||||||
|
|
||||||
|
/// The shortcut class will do this automatically
|
||||||
|
void removeShortcut(Shortcut* shortcut);
|
||||||
|
|
||||||
|
bool getSequence(const std::string& name, QKeySequence& sequence) const;
|
||||||
|
void setSequence(const std::string& name, const QKeySequence& sequence);
|
||||||
|
|
||||||
|
bool getModifier(const std::string& name, int& modifier) const;
|
||||||
|
void setModifier(const std::string& name, int modifier);
|
||||||
|
|
||||||
|
std::string convertToString(const QKeySequence& sequence) const;
|
||||||
|
std::string convertToString(int modifier) const;
|
||||||
|
|
||||||
|
std::string convertToString(const QKeySequence& sequence, int modifier) const;
|
||||||
|
|
||||||
|
void convertFromString(const std::string& data, QKeySequence& sequence) const;
|
||||||
|
void convertFromString(const std::string& data, int& modifier) const;
|
||||||
|
|
||||||
|
void convertFromString(const std::string& data, QKeySequence& sequence, int& modifier) const;
|
||||||
|
|
||||||
|
/// Replaces "{sequence-name}" or "{modifier-name}" with the appropriate text
|
||||||
|
QString processToolTip(const QString& toolTip) const;
|
||||||
|
|
||||||
|
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, int> ModifierMap;
|
||||||
|
typedef std::map<int, std::string> NameMap;
|
||||||
|
typedef std::map<std::string, int> KeyMap;
|
||||||
|
|
||||||
|
ShortcutMap mShortcuts;
|
||||||
|
SequenceMap mSequences;
|
||||||
|
ModifierMap mModifiers;
|
||||||
|
|
||||||
|
NameMap mNames;
|
||||||
|
KeyMap mKeys;
|
||||||
|
|
||||||
|
ShortcutEventHandler* mEventHandler;
|
||||||
|
|
||||||
|
void createLookupTables();
|
||||||
|
|
||||||
|
static const std::pair<int, const char*> QtKeys[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
196
apps/opencs/model/prefs/shortcutsetting.cpp
Normal file
196
apps/opencs/model/prefs/shortcutsetting.cpp
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
#include "shortcutsetting.hpp"
|
||||||
|
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "state.hpp"
|
||||||
|
#include "shortcutmanager.hpp"
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
const int ShortcutSetting::MaxKeys;
|
||||||
|
|
||||||
|
ShortcutSetting::ShortcutSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key,
|
||||||
|
const std::string& label)
|
||||||
|
: Setting(parent, values, mutex, key, label)
|
||||||
|
, mEditorActive(false)
|
||||||
|
, mEditorPos(0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MaxKeys; ++i)
|
||||||
|
{
|
||||||
|
mEditorKeys[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QWidget*, QWidget*> ShortcutSetting::makeWidgets(QWidget* parent)
|
||||||
|
{
|
||||||
|
QKeySequence sequence;
|
||||||
|
State::get().getShortcutManager().getSequence(getKey(), sequence);
|
||||||
|
|
||||||
|
QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(sequence).c_str());
|
||||||
|
|
||||||
|
QLabel* label = new QLabel(QString::fromUtf8(getLabel().c_str()), parent);
|
||||||
|
QPushButton* widget = new QPushButton(text, parent);
|
||||||
|
|
||||||
|
widget->setCheckable(true);
|
||||||
|
widget->installEventFilter(this);
|
||||||
|
mButton = widget;
|
||||||
|
|
||||||
|
connect(widget, SIGNAL(toggled(bool)), this, SLOT(buttonToggled(bool)));
|
||||||
|
|
||||||
|
return std::make_pair(label, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShortcutSetting::eventFilter(QObject* target, QEvent* event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::KeyPress)
|
||||||
|
{
|
||||||
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||||
|
if (keyEvent->isAutoRepeat())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
int mod = keyEvent->modifiers();
|
||||||
|
int key = keyEvent->key();
|
||||||
|
|
||||||
|
return handleEvent(target, mod, key, true);
|
||||||
|
}
|
||||||
|
else if (event->type() == QEvent::KeyRelease)
|
||||||
|
{
|
||||||
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||||
|
if (keyEvent->isAutoRepeat())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
int mod = keyEvent->modifiers();
|
||||||
|
int key = keyEvent->key();
|
||||||
|
|
||||||
|
return handleEvent(target, mod, key, false);
|
||||||
|
}
|
||||||
|
else if (event->type() == QEvent::MouseButtonPress)
|
||||||
|
{
|
||||||
|
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||||
|
int mod = mouseEvent->modifiers();
|
||||||
|
int key = mouseEvent->button();
|
||||||
|
|
||||||
|
return handleEvent(target, mod, key, true);
|
||||||
|
}
|
||||||
|
else if (event->type() == QEvent::MouseButtonRelease)
|
||||||
|
{
|
||||||
|
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
|
||||||
|
int mod = mouseEvent->modifiers();
|
||||||
|
int key = mouseEvent->button();
|
||||||
|
|
||||||
|
return handleEvent(target, mod, key, false);
|
||||||
|
}
|
||||||
|
else if (event->type() == QEvent::FocusOut)
|
||||||
|
{
|
||||||
|
resetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShortcutSetting::handleEvent(QObject* target, int mod, int value, bool active)
|
||||||
|
{
|
||||||
|
// Modifiers are handled differently
|
||||||
|
const int Blacklist[] =
|
||||||
|
{
|
||||||
|
Qt::Key_Shift,
|
||||||
|
Qt::Key_Control,
|
||||||
|
Qt::Key_Meta,
|
||||||
|
Qt::Key_Alt,
|
||||||
|
Qt::Key_AltGr
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t BlacklistSize = sizeof(Blacklist) / sizeof(int);
|
||||||
|
|
||||||
|
if (!mEditorActive)
|
||||||
|
{
|
||||||
|
if (value == Qt::RightButton && !active)
|
||||||
|
{
|
||||||
|
// Clear sequence
|
||||||
|
QKeySequence sequence = QKeySequence(0, 0, 0, 0);
|
||||||
|
storeValue(sequence);
|
||||||
|
|
||||||
|
resetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle blacklist
|
||||||
|
for (size_t i = 0; i < BlacklistSize; ++i)
|
||||||
|
{
|
||||||
|
if (value == Blacklist[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!active || mEditorPos >= MaxKeys)
|
||||||
|
{
|
||||||
|
// Update key
|
||||||
|
QKeySequence sequence = QKeySequence(mEditorKeys[0], mEditorKeys[1], mEditorKeys[2], mEditorKeys[3]);
|
||||||
|
storeValue(sequence);
|
||||||
|
|
||||||
|
resetState();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mEditorPos == 0)
|
||||||
|
{
|
||||||
|
mEditorKeys[0] = mod | value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mEditorKeys[mEditorPos] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
mEditorPos += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutSetting::storeValue(const QKeySequence& sequence)
|
||||||
|
{
|
||||||
|
State::get().getShortcutManager().setSequence(getKey(), sequence);
|
||||||
|
|
||||||
|
// Convert to string and assign
|
||||||
|
std::string value = State::get().getShortcutManager().convertToString(sequence);
|
||||||
|
|
||||||
|
{
|
||||||
|
QMutexLocker lock(getMutex());
|
||||||
|
getValues().setString(getKey(), getParent()->getKey(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
getParent()->getState()->update(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutSetting::resetState()
|
||||||
|
{
|
||||||
|
mButton->setChecked(false);
|
||||||
|
mEditorActive = false;
|
||||||
|
mEditorPos = 0;
|
||||||
|
for (int i = 0; i < MaxKeys; ++i)
|
||||||
|
{
|
||||||
|
mEditorKeys[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button text
|
||||||
|
QKeySequence sequence;
|
||||||
|
State::get().getShortcutManager().getSequence(getKey(), sequence);
|
||||||
|
|
||||||
|
QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(sequence).c_str());
|
||||||
|
mButton->setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShortcutSetting::buttonToggled(bool checked)
|
||||||
|
{
|
||||||
|
if (checked)
|
||||||
|
mButton->setText("Press keys or click here...");
|
||||||
|
|
||||||
|
mEditorActive = checked;
|
||||||
|
}
|
||||||
|
}
|
49
apps/opencs/model/prefs/shortcutsetting.hpp
Normal file
49
apps/opencs/model/prefs/shortcutsetting.hpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#ifndef CSM_PREFS_SHORTCUTSETTING_H
|
||||||
|
#define CSM_PREFS_SHORTCUTSETTING_H
|
||||||
|
|
||||||
|
#include <QKeySequence>
|
||||||
|
|
||||||
|
#include "setting.hpp"
|
||||||
|
|
||||||
|
class QEvent;
|
||||||
|
class QPushButton;
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class ShortcutSetting : public Setting
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ShortcutSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key,
|
||||||
|
const std::string& label);
|
||||||
|
|
||||||
|
virtual std::pair<QWidget*, QWidget*> makeWidgets(QWidget* parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool eventFilter(QObject* target, QEvent* event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool handleEvent(QObject* target, int mod, int value, bool active);
|
||||||
|
|
||||||
|
void storeValue(const QKeySequence& sequence);
|
||||||
|
void resetState();
|
||||||
|
|
||||||
|
static const int MaxKeys = 4;
|
||||||
|
|
||||||
|
QPushButton* mButton;
|
||||||
|
|
||||||
|
bool mEditorActive;
|
||||||
|
int mEditorPos;
|
||||||
|
int mEditorKeys[MaxKeys];
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void buttonToggled(bool checked);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -9,6 +9,8 @@
|
||||||
#include "doublesetting.hpp"
|
#include "doublesetting.hpp"
|
||||||
#include "boolsetting.hpp"
|
#include "boolsetting.hpp"
|
||||||
#include "coloursetting.hpp"
|
#include "coloursetting.hpp"
|
||||||
|
#include "shortcutsetting.hpp"
|
||||||
|
#include "modifiersetting.hpp"
|
||||||
|
|
||||||
CSMPrefs::State *CSMPrefs::State::sThis = 0;
|
CSMPrefs::State *CSMPrefs::State::sThis = 0;
|
||||||
|
|
||||||
|
@ -165,16 +167,6 @@ void CSMPrefs::State::declare()
|
||||||
"list go to the first/last item");
|
"list go to the first/last item");
|
||||||
|
|
||||||
declareCategory ("3D Scene Input");
|
declareCategory ("3D Scene Input");
|
||||||
EnumValue left ("Left Mouse-Button");
|
|
||||||
EnumValue cLeft ("Ctrl-Left Mouse-Button");
|
|
||||||
EnumValue right ("Right Mouse-Button");
|
|
||||||
EnumValue cRight ("Ctrl-Right Mouse-Button");
|
|
||||||
EnumValue middle ("Middle Mouse-Button");
|
|
||||||
EnumValue cMiddle ("Ctrl-Middle Mouse-Button");
|
|
||||||
EnumValues inputButtons;
|
|
||||||
inputButtons.add (left).add (cLeft).add (right).add (cRight).add (middle).add (cMiddle);
|
|
||||||
declareEnum ("p-navi", "Primary Camera Navigation Button", left).addValues (inputButtons);
|
|
||||||
declareEnum ("s-navi", "Secondary Camera Navigation Button", cLeft).addValues (inputButtons);
|
|
||||||
declareDouble ("p-navi-free-sensitivity", "Free Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0);
|
declareDouble ("p-navi-free-sensitivity", "Free Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0);
|
||||||
declareBool ("p-navi-free-invert", "Invert Free Camera Mouse Input", false);
|
declareBool ("p-navi-free-invert", "Invert Free Camera Mouse Input", false);
|
||||||
declareDouble ("p-navi-orbit-sensitivity", "Orbit Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0);
|
declareDouble ("p-navi-orbit-sensitivity", "Orbit Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0);
|
||||||
|
@ -186,10 +178,6 @@ void CSMPrefs::State::declare()
|
||||||
declareDouble ("navi-free-speed-mult", "Free Camera Speed Multiplier (from Modifier)", 8).setRange(0.001, 1000.0);
|
declareDouble ("navi-free-speed-mult", "Free Camera Speed Multiplier (from Modifier)", 8).setRange(0.001, 1000.0);
|
||||||
declareDouble ("navi-orbit-rot-speed", "Orbital Camera Rotational Speed", 3.14 / 4).setRange(0.001, 6.28);
|
declareDouble ("navi-orbit-rot-speed", "Orbital Camera Rotational Speed", 3.14 / 4).setRange(0.001, 6.28);
|
||||||
declareDouble ("navi-orbit-speed-mult", "Orbital Camera Speed Multiplier (from Modifier)", 4).setRange(0.001, 1000.0);
|
declareDouble ("navi-orbit-speed-mult", "Orbital Camera Speed Multiplier (from Modifier)", 4).setRange(0.001, 1000.0);
|
||||||
declareEnum ("p-edit", "Primary Editing Button", right).addValues (inputButtons);
|
|
||||||
declareEnum ("s-edit", "Secondary Editing Button", cRight).addValues (inputButtons);
|
|
||||||
declareEnum ("p-select", "Primary Selection Button", middle).addValues (inputButtons);
|
|
||||||
declareEnum ("s-select", "Secondary Selection Button", cMiddle).addValues (inputButtons);
|
|
||||||
declareSeparator();
|
declareSeparator();
|
||||||
declareBool ("context-select", "Context Sensitive Selection", false);
|
declareBool ("context-select", "Context Sensitive Selection", false);
|
||||||
declareDouble ("drag-factor", "Mouse sensitivity during drag operations", 1.0).
|
declareDouble ("drag-factor", "Mouse sensitivity during drag operations", 1.0).
|
||||||
|
@ -224,6 +212,119 @@ void CSMPrefs::State::declare()
|
||||||
addValues (insertOutsideCell);
|
addValues (insertOutsideCell);
|
||||||
declareEnum ("outside-visible-drop", "Handling drops outside of visible cells", showAndInsert).
|
declareEnum ("outside-visible-drop", "Handling drops outside of visible cells", showAndInsert).
|
||||||
addValues (insertOutsideVisibleCell);
|
addValues (insertOutsideVisibleCell);
|
||||||
|
|
||||||
|
declareCategory ("Key Bindings");
|
||||||
|
|
||||||
|
declareSubcategory ("Document");
|
||||||
|
declareShortcut ("document-file-newgame", "New Game", QKeySequence(Qt::ControlModifier | Qt::Key_N));
|
||||||
|
declareShortcut ("document-file-newaddon", "New Addon", QKeySequence());
|
||||||
|
declareShortcut ("document-file-open", "Open", QKeySequence(Qt::ControlModifier | Qt::Key_O));
|
||||||
|
declareShortcut ("document-file-save", "Save", QKeySequence(Qt::ControlModifier | Qt::Key_S));
|
||||||
|
declareShortcut ("document-file-verify", "Verify", QKeySequence());
|
||||||
|
declareShortcut ("document-file-merge", "Merge", QKeySequence());
|
||||||
|
declareShortcut ("document-file-errorlog", "Open Load Error Log", QKeySequence());
|
||||||
|
declareShortcut ("document-file-metadata", "Meta Data", QKeySequence());
|
||||||
|
declareShortcut ("document-file-close", "Close Document", QKeySequence(Qt::ControlModifier | Qt::Key_W));
|
||||||
|
declareShortcut ("document-file-exit", "Exit Application", QKeySequence(Qt::ControlModifier | Qt::Key_Q));
|
||||||
|
declareShortcut ("document-edit-undo", "Undo", QKeySequence(Qt::ControlModifier | Qt::Key_Z));
|
||||||
|
declareShortcut ("document-edit-redo", "Redo", QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Z));
|
||||||
|
declareShortcut ("document-edit-preferences", "Open Preferences", QKeySequence());
|
||||||
|
declareShortcut ("document-edit-search", "Search", QKeySequence(Qt::ControlModifier | Qt::Key_F));
|
||||||
|
declareShortcut ("document-view-newview", "New View", QKeySequence());
|
||||||
|
declareShortcut ("document-view-statusbar", "Toggle Status Bar", QKeySequence());
|
||||||
|
declareShortcut ("document-view-filters", "Open Filter List", QKeySequence());
|
||||||
|
declareShortcut ("document-world-regions", "Open Region List", QKeySequence());
|
||||||
|
declareShortcut ("document-world-cells", "Open Cell List", QKeySequence());
|
||||||
|
declareShortcut ("document-world-referencables", "Open Object List", QKeySequence());
|
||||||
|
declareShortcut ("document-world-references", "Open Instance List", QKeySequence());
|
||||||
|
declareShortcut ("document-world-pathgrid", "Open Pathgrid List", QKeySequence());
|
||||||
|
declareShortcut ("document-world-regionmap", "Open Region Map", QKeySequence());
|
||||||
|
declareShortcut ("document-mechanics-globals", "Open Global List", QKeySequence());
|
||||||
|
declareShortcut ("document-mechanics-gamesettings", "Open Game Settings", QKeySequence());
|
||||||
|
declareShortcut ("document-mechanics-scripts", "Open Script List", QKeySequence());
|
||||||
|
declareShortcut ("document-mechanics-spells", "Open Spell List", QKeySequence());
|
||||||
|
declareShortcut ("document-mechanics-enchantments", "Open Enchantment List", QKeySequence());
|
||||||
|
declareShortcut ("document-mechanics-magiceffects", "Open Magic Effect List", QKeySequence());
|
||||||
|
declareShortcut ("document-mechanics-startscripts", "Open Start Script List", QKeySequence());
|
||||||
|
declareShortcut ("document-character-skills", "Open Skill List", QKeySequence());
|
||||||
|
declareShortcut ("document-character-classes", "Open Class List", QKeySequence());
|
||||||
|
declareShortcut ("document-character-factions", "Open Faction List", QKeySequence());
|
||||||
|
declareShortcut ("document-character-races", "Open Race List", QKeySequence());
|
||||||
|
declareShortcut ("document-character-birthsigns", "Open Birthsign List", QKeySequence());
|
||||||
|
declareShortcut ("document-character-topics", "Open Topic List", QKeySequence());
|
||||||
|
declareShortcut ("document-character-journals", "Open Journal List", QKeySequence());
|
||||||
|
declareShortcut ("document-character-topicinfos", "Open Topic Info List", QKeySequence());
|
||||||
|
declareShortcut ("document-character-journalinfos", "Open Journal Info List", QKeySequence());
|
||||||
|
declareShortcut ("document-character-bodyparts", "Open Body Part List", QKeySequence());
|
||||||
|
declareShortcut ("document-assets-sounds", "Open Sound Asset List", QKeySequence());
|
||||||
|
declareShortcut ("document-assets-soundgens", "Open Sound Generator List", QKeySequence());
|
||||||
|
declareShortcut ("document-assets-meshes", "Open Mesh Asset List", QKeySequence());
|
||||||
|
declareShortcut ("document-assets-icons", "Open Icon Asset List", QKeySequence());
|
||||||
|
declareShortcut ("document-assets-music", "Open Music Asset List", QKeySequence());
|
||||||
|
declareShortcut ("document-assets-soundres", "Open Sound File List", QKeySequence());
|
||||||
|
declareShortcut ("document-assets-textures", "Open Texture Asset List", QKeySequence());
|
||||||
|
declareShortcut ("document-assets-videos", "Open Video Asset List", QKeySequence());
|
||||||
|
declareShortcut ("document-debug-run", "Run Debug", QKeySequence());
|
||||||
|
declareShortcut ("document-debug-shutdown", "Stop Debug", QKeySequence());
|
||||||
|
declareShortcut ("document-debug-runlog", "Open Run Log", QKeySequence());
|
||||||
|
|
||||||
|
declareSubcategory ("Table");
|
||||||
|
declareShortcut ("table-edit", "Edit Record", QKeySequence());
|
||||||
|
declareShortcut ("table-add", "Add Row/Record", QKeySequence(Qt::ShiftModifier | Qt::Key_A));
|
||||||
|
declareShortcut ("table-clone", "Clone Record", QKeySequence(Qt::ShiftModifier | Qt::Key_D));
|
||||||
|
declareShortcut ("table-revert", "Revert Record", QKeySequence());
|
||||||
|
declareShortcut ("table-remove", "Remove Row/Record", QKeySequence(Qt::Key_Delete));
|
||||||
|
declareShortcut ("table-moveup", "Move Record Up", QKeySequence());
|
||||||
|
declareShortcut ("table-movedown", "Move Record Down", QKeySequence());
|
||||||
|
declareShortcut ("table-view", "View Record", QKeySequence());
|
||||||
|
declareShortcut ("table-preview", "Preview Record", QKeySequence());
|
||||||
|
declareShortcut ("table-extendeddelete", "Extended Record Deletion", QKeySequence());
|
||||||
|
declareShortcut ("table-extendedrevert", "Extended Record Revertion", QKeySequence());
|
||||||
|
|
||||||
|
declareSubcategory ("Report Table");
|
||||||
|
declareShortcut ("reporttable-show", "Show Report", QKeySequence());
|
||||||
|
declareShortcut ("reporttable-remove", "Remove Report", QKeySequence(Qt::Key_Delete));
|
||||||
|
declareShortcut ("reporttable-replace", "Replace Report", QKeySequence());
|
||||||
|
declareShortcut ("reporttable-refresh", "Refresh Report", QKeySequence());
|
||||||
|
|
||||||
|
declareSubcategory ("Scene");
|
||||||
|
declareShortcut ("scene-navi-primary", "Camera Rotation From Mouse Movement", QKeySequence(Qt::LeftButton));
|
||||||
|
declareShortcut ("scene-navi-secondary", "Camera Translation From Mouse Movement",
|
||||||
|
QKeySequence(Qt::ControlModifier | (int)Qt::LeftButton));
|
||||||
|
declareShortcut ("scene-edit-primary", "Primary Edit", QKeySequence(Qt::RightButton));
|
||||||
|
declareShortcut ("scene-edit-secondary", "Secondary Edit",
|
||||||
|
QKeySequence(Qt::ControlModifier | (int)Qt::RightButton));
|
||||||
|
declareShortcut ("scene-select-primary", "Primary Select", QKeySequence(Qt::MiddleButton));
|
||||||
|
declareShortcut ("scene-select-secondary", "Secondary Select",
|
||||||
|
QKeySequence(Qt::ControlModifier | (int)Qt::MiddleButton));
|
||||||
|
declareModifier ("scene-speed-modifier", "Speed Modifier", Qt::Key_Shift);
|
||||||
|
declareShortcut ("scene-load-cam-cell", "Load Camera Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_5));
|
||||||
|
declareShortcut ("scene-load-cam-eastcell", "Load East Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_6));
|
||||||
|
declareShortcut ("scene-load-cam-northcell", "Load North Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_8));
|
||||||
|
declareShortcut ("scene-load-cam-westcell", "Load West Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_4));
|
||||||
|
declareShortcut ("scene-load-cam-southcell", "Load South Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_2));
|
||||||
|
declareShortcut ("scene-edit-abort", "Abort", QKeySequence(Qt::Key_Escape));
|
||||||
|
declareShortcut ("scene-focus-toolbar", "Toggle Toolbar Focus", QKeySequence(Qt::Key_T));
|
||||||
|
declareShortcut ("scene-render-stats", "Debug Rendering Stats", QKeySequence(Qt::Key_F3));
|
||||||
|
|
||||||
|
declareSubcategory ("1st/Free Camera");
|
||||||
|
declareShortcut ("free-forward", "Forward", QKeySequence(Qt::Key_W));
|
||||||
|
declareShortcut ("free-backward", "Backward", QKeySequence(Qt::Key_S));
|
||||||
|
declareShortcut ("free-left", "Left", QKeySequence(Qt::Key_A));
|
||||||
|
declareShortcut ("free-right", "Right", QKeySequence(Qt::Key_D));
|
||||||
|
declareShortcut ("free-roll-left", "Roll Left", QKeySequence(Qt::Key_Q));
|
||||||
|
declareShortcut ("free-roll-right", "Roll Right", QKeySequence(Qt::Key_E));
|
||||||
|
declareShortcut ("free-speed-mode", "Toggle Speed Mode", QKeySequence(Qt::Key_F));
|
||||||
|
|
||||||
|
declareSubcategory ("Orbit Camera");
|
||||||
|
declareShortcut ("orbit-up", "Up", QKeySequence(Qt::Key_W));
|
||||||
|
declareShortcut ("orbit-down", "Down", QKeySequence(Qt::Key_S));
|
||||||
|
declareShortcut ("orbit-left", "Left", QKeySequence(Qt::Key_A));
|
||||||
|
declareShortcut ("orbit-right", "Right", QKeySequence(Qt::Key_D));
|
||||||
|
declareShortcut ("orbit-roll-left", "Roll Left", QKeySequence(Qt::Key_Q));
|
||||||
|
declareShortcut ("orbit-roll-right", "Roll Right", QKeySequence(Qt::Key_E));
|
||||||
|
declareShortcut ("orbit-speed-mode", "Toggle Speed Mode", QKeySequence(Qt::Key_F));
|
||||||
|
declareShortcut ("orbit-center-selection", "Center On Selected", QKeySequence(Qt::Key_C));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMPrefs::State::declareCategory (const std::string& key)
|
void CSMPrefs::State::declareCategory (const std::string& key)
|
||||||
|
@ -340,6 +441,50 @@ CSMPrefs::ColourSetting& CSMPrefs::State::declareColour (const std::string& key,
|
||||||
return *setting;
|
return *setting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSMPrefs::ShortcutSetting& CSMPrefs::State::declareShortcut (const std::string& key, const std::string& label,
|
||||||
|
const QKeySequence& default_)
|
||||||
|
{
|
||||||
|
if (mCurrentCategory==mCategories.end())
|
||||||
|
throw std::logic_error ("no category for setting");
|
||||||
|
|
||||||
|
std::string seqStr = getShortcutManager().convertToString(default_);
|
||||||
|
setDefault (key, seqStr);
|
||||||
|
|
||||||
|
// Setup with actual data
|
||||||
|
QKeySequence sequence;
|
||||||
|
|
||||||
|
getShortcutManager().convertFromString(mSettings.getString(key, mCurrentCategory->second.getKey()), sequence);
|
||||||
|
getShortcutManager().setSequence(key, sequence);
|
||||||
|
|
||||||
|
CSMPrefs::ShortcutSetting *setting = new CSMPrefs::ShortcutSetting (&mCurrentCategory->second, &mSettings, &mMutex,
|
||||||
|
key, label);
|
||||||
|
mCurrentCategory->second.addSetting (setting);
|
||||||
|
|
||||||
|
return *setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMPrefs::ModifierSetting& CSMPrefs::State::declareModifier(const std::string& key, const std::string& label,
|
||||||
|
int default_)
|
||||||
|
{
|
||||||
|
if (mCurrentCategory==mCategories.end())
|
||||||
|
throw std::logic_error ("no category for setting");
|
||||||
|
|
||||||
|
std::string modStr = getShortcutManager().convertToString(default_);
|
||||||
|
setDefault (key, modStr);
|
||||||
|
|
||||||
|
// Setup with actual data
|
||||||
|
int modifier;
|
||||||
|
|
||||||
|
getShortcutManager().convertFromString(mSettings.getString(key, mCurrentCategory->second.getKey()), modifier);
|
||||||
|
getShortcutManager().setModifier(key, modifier);
|
||||||
|
|
||||||
|
CSMPrefs::ModifierSetting *setting = new CSMPrefs::ModifierSetting (&mCurrentCategory->second, &mSettings, &mMutex,
|
||||||
|
key, label);
|
||||||
|
mCurrentCategory->second.addSetting (setting);
|
||||||
|
|
||||||
|
return *setting;
|
||||||
|
}
|
||||||
|
|
||||||
void CSMPrefs::State::declareSeparator()
|
void CSMPrefs::State::declareSeparator()
|
||||||
{
|
{
|
||||||
if (mCurrentCategory==mCategories.end())
|
if (mCurrentCategory==mCategories.end())
|
||||||
|
@ -351,6 +496,17 @@ void CSMPrefs::State::declareSeparator()
|
||||||
mCurrentCategory->second.addSetting (setting);
|
mCurrentCategory->second.addSetting (setting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSMPrefs::State::declareSubcategory(const std::string& label)
|
||||||
|
{
|
||||||
|
if (mCurrentCategory==mCategories.end())
|
||||||
|
throw std::logic_error ("no category for setting");
|
||||||
|
|
||||||
|
CSMPrefs::Setting *setting =
|
||||||
|
new CSMPrefs::Setting (&mCurrentCategory->second, &mSettings, &mMutex, "", label);
|
||||||
|
|
||||||
|
mCurrentCategory->second.addSetting (setting);
|
||||||
|
}
|
||||||
|
|
||||||
void CSMPrefs::State::setDefault (const std::string& key, const std::string& default_)
|
void CSMPrefs::State::setDefault (const std::string& key, const std::string& default_)
|
||||||
{
|
{
|
||||||
Settings::CategorySetting fullKey (mCurrentCategory->second.getKey(), key);
|
Settings::CategorySetting fullKey (mCurrentCategory->second.getKey(), key);
|
||||||
|
@ -369,10 +525,10 @@ CSMPrefs::State::State (const Files::ConfigurationManager& configurationManager)
|
||||||
if (sThis)
|
if (sThis)
|
||||||
throw std::logic_error ("An instance of CSMPRefs::State already exists");
|
throw std::logic_error ("An instance of CSMPRefs::State already exists");
|
||||||
|
|
||||||
|
sThis = this;
|
||||||
|
|
||||||
load();
|
load();
|
||||||
declare();
|
declare();
|
||||||
|
|
||||||
sThis = this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMPrefs::State::~State()
|
CSMPrefs::State::~State()
|
||||||
|
@ -396,6 +552,11 @@ CSMPrefs::State::Iterator CSMPrefs::State::end()
|
||||||
return mCategories.end();
|
return mCategories.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSMPrefs::ShortcutManager& CSMPrefs::State::getShortcutManager()
|
||||||
|
{
|
||||||
|
return mShortcutManager;
|
||||||
|
}
|
||||||
|
|
||||||
CSMPrefs::Category& CSMPrefs::State::operator[] (const std::string& key)
|
CSMPrefs::Category& CSMPrefs::State::operator[] (const std::string& key)
|
||||||
{
|
{
|
||||||
Iterator iter = mCategories.find (key);
|
Iterator iter = mCategories.find (key);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "category.hpp"
|
#include "category.hpp"
|
||||||
#include "setting.hpp"
|
#include "setting.hpp"
|
||||||
#include "enumsetting.hpp"
|
#include "enumsetting.hpp"
|
||||||
|
#include "shortcutmanager.hpp"
|
||||||
|
|
||||||
class QColor;
|
class QColor;
|
||||||
|
|
||||||
|
@ -25,6 +26,8 @@ namespace CSMPrefs
|
||||||
class DoubleSetting;
|
class DoubleSetting;
|
||||||
class BoolSetting;
|
class BoolSetting;
|
||||||
class ColourSetting;
|
class ColourSetting;
|
||||||
|
class ShortcutSetting;
|
||||||
|
class ModifierSetting;
|
||||||
|
|
||||||
/// \brief User settings state
|
/// \brief User settings state
|
||||||
///
|
///
|
||||||
|
@ -45,6 +48,7 @@ namespace CSMPrefs
|
||||||
|
|
||||||
const std::string mConfigFile;
|
const std::string mConfigFile;
|
||||||
const Files::ConfigurationManager& mConfigurationManager;
|
const Files::ConfigurationManager& mConfigurationManager;
|
||||||
|
ShortcutManager mShortcutManager;
|
||||||
Settings::Manager mSettings;
|
Settings::Manager mSettings;
|
||||||
Collection mCategories;
|
Collection mCategories;
|
||||||
Iterator mCurrentCategory;
|
Iterator mCurrentCategory;
|
||||||
|
@ -71,8 +75,15 @@ namespace CSMPrefs
|
||||||
|
|
||||||
ColourSetting& declareColour (const std::string& key, const std::string& label, QColor default_);
|
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_);
|
||||||
|
|
||||||
|
ModifierSetting& declareModifier(const std::string& key, const std::string& label, int modifier_);
|
||||||
|
|
||||||
void declareSeparator();
|
void declareSeparator();
|
||||||
|
|
||||||
|
void declareSubcategory(const std::string& label);
|
||||||
|
|
||||||
void setDefault (const std::string& key, const std::string& default_);
|
void setDefault (const std::string& key, const std::string& default_);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -87,6 +98,8 @@ namespace CSMPrefs
|
||||||
|
|
||||||
Iterator end();
|
Iterator end();
|
||||||
|
|
||||||
|
ShortcutManager& getShortcutManager();
|
||||||
|
|
||||||
Category& operator[](const std::string& key);
|
Category& operator[](const std::string& key);
|
||||||
|
|
||||||
void update (const Setting& setting);
|
void update (const Setting& setting);
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
@ -44,83 +45,98 @@ void CSVDoc::View::closeEvent (QCloseEvent *event)
|
||||||
|
|
||||||
void CSVDoc::View::setupFileMenu()
|
void CSVDoc::View::setupFileMenu()
|
||||||
{
|
{
|
||||||
QMenu *file = menuBar()->addMenu (tr ("&File"));
|
QMenu *file = menuBar()->addMenu (tr ("File"));
|
||||||
|
|
||||||
QAction *newGame = new QAction (tr ("New Game"), this);
|
QAction *newGame = new QAction (tr ("New Game"), this);
|
||||||
connect (newGame, SIGNAL (triggered()), this, SIGNAL (newGameRequest()));
|
connect (newGame, SIGNAL (triggered()), this, SIGNAL (newGameRequest()));
|
||||||
|
setupShortcut("document-file-newgame", newGame);
|
||||||
file->addAction (newGame);
|
file->addAction (newGame);
|
||||||
|
|
||||||
|
|
||||||
QAction *newAddon = new QAction (tr ("New Addon"), this);
|
QAction *newAddon = new QAction (tr ("New Addon"), this);
|
||||||
connect (newAddon, SIGNAL (triggered()), this, SIGNAL (newAddonRequest()));
|
connect (newAddon, SIGNAL (triggered()), this, SIGNAL (newAddonRequest()));
|
||||||
|
setupShortcut("document-file-newaddon", newAddon);
|
||||||
file->addAction (newAddon);
|
file->addAction (newAddon);
|
||||||
|
|
||||||
QAction *open = new QAction (tr ("&Open"), this);
|
QAction *open = new QAction (tr ("Open"), this);
|
||||||
connect (open, SIGNAL (triggered()), this, SIGNAL (loadDocumentRequest()));
|
connect (open, SIGNAL (triggered()), this, SIGNAL (loadDocumentRequest()));
|
||||||
|
setupShortcut("document-file-open", open);
|
||||||
file->addAction (open);
|
file->addAction (open);
|
||||||
|
|
||||||
mSave = new QAction (tr ("&Save"), this);
|
mSave = new QAction (tr ("Save"), this);
|
||||||
connect (mSave, SIGNAL (triggered()), this, SLOT (save()));
|
connect (mSave, SIGNAL (triggered()), this, SLOT (save()));
|
||||||
|
setupShortcut("document-file-save", mSave);
|
||||||
file->addAction (mSave);
|
file->addAction (mSave);
|
||||||
|
|
||||||
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()));
|
||||||
|
setupShortcut("document-file-verify", mVerify);
|
||||||
file->addAction (mVerify);
|
file->addAction (mVerify);
|
||||||
|
|
||||||
mMerge = new QAction (tr ("Merge"), this);
|
mMerge = new QAction (tr ("Merge"), this);
|
||||||
connect (mMerge, SIGNAL (triggered()), this, SLOT (merge()));
|
connect (mMerge, SIGNAL (triggered()), this, SLOT (merge()));
|
||||||
|
setupShortcut("document-file-merge", mMerge);
|
||||||
file->addAction (mMerge);
|
file->addAction (mMerge);
|
||||||
|
|
||||||
QAction *loadErrors = new QAction (tr ("Load Error Log"), this);
|
QAction *loadErrors = new QAction (tr ("Open Load Error Log"), this);
|
||||||
connect (loadErrors, SIGNAL (triggered()), this, SLOT (loadErrorLog()));
|
connect (loadErrors, SIGNAL (triggered()), this, SLOT (loadErrorLog()));
|
||||||
|
setupShortcut("document-file-errorlog", loadErrors);
|
||||||
file->addAction (loadErrors);
|
file->addAction (loadErrors);
|
||||||
|
|
||||||
QAction *meta = new QAction (tr ("Meta Data"), this);
|
QAction *meta = new QAction (tr ("Meta Data"), this);
|
||||||
connect (meta, SIGNAL (triggered()), this, SLOT (addMetaDataSubView()));
|
connect (meta, SIGNAL (triggered()), this, SLOT (addMetaDataSubView()));
|
||||||
|
setupShortcut("document-file-metadata", meta);
|
||||||
file->addAction (meta);
|
file->addAction (meta);
|
||||||
|
|
||||||
QAction *close = new QAction (tr ("&Close"), this);
|
QAction *close = new QAction (tr ("Close Document"), this);
|
||||||
connect (close, SIGNAL (triggered()), this, SLOT (close()));
|
connect (close, SIGNAL (triggered()), this, SLOT (close()));
|
||||||
|
setupShortcut("document-file-close", close);
|
||||||
file->addAction(close);
|
file->addAction(close);
|
||||||
|
|
||||||
QAction *exit = new QAction (tr ("&Exit"), this);
|
QAction *exit = new QAction (tr ("Exit Application"), this);
|
||||||
connect (exit, SIGNAL (triggered()), this, SLOT (exit()));
|
connect (exit, SIGNAL (triggered()), this, SLOT (exit()));
|
||||||
connect (this, SIGNAL(exitApplicationRequest(CSVDoc::View *)), &mViewManager, SLOT(exitApplication(CSVDoc::View *)));
|
connect (this, SIGNAL(exitApplicationRequest(CSVDoc::View *)), &mViewManager, SLOT(exitApplication(CSVDoc::View *)));
|
||||||
|
setupShortcut("document-file-exit", exit);
|
||||||
|
|
||||||
file->addAction(exit);
|
file->addAction(exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVDoc::View::setupEditMenu()
|
void CSVDoc::View::setupEditMenu()
|
||||||
{
|
{
|
||||||
QMenu *edit = menuBar()->addMenu (tr ("&Edit"));
|
QMenu *edit = menuBar()->addMenu (tr ("Edit"));
|
||||||
|
|
||||||
mUndo = mDocument->getUndoStack().createUndoAction (this, tr("&Undo"));
|
mUndo = mDocument->getUndoStack().createUndoAction (this, tr("Undo"));
|
||||||
mUndo->setShortcuts (QKeySequence::Undo);
|
setupShortcut("document-edit-undo", mUndo);
|
||||||
edit->addAction (mUndo);
|
edit->addAction (mUndo);
|
||||||
|
|
||||||
mRedo= mDocument->getUndoStack().createRedoAction (this, tr("&Redo"));
|
mRedo= mDocument->getUndoStack().createRedoAction (this, tr("Redo"));
|
||||||
mRedo->setShortcuts (QKeySequence::Redo);
|
setupShortcut("document-edit-redo", mRedo);
|
||||||
edit->addAction (mRedo);
|
edit->addAction (mRedo);
|
||||||
|
|
||||||
QAction *userSettings = new QAction (tr ("&Preferences"), this);
|
QAction *userSettings = new QAction (tr ("Preferences"), this);
|
||||||
connect (userSettings, SIGNAL (triggered()), this, SIGNAL (editSettingsRequest()));
|
connect (userSettings, SIGNAL (triggered()), this, SIGNAL (editSettingsRequest()));
|
||||||
|
setupShortcut("document-edit-preferences", userSettings);
|
||||||
edit->addAction (userSettings);
|
edit->addAction (userSettings);
|
||||||
|
|
||||||
QAction *search = new QAction (tr ("Search"), this);
|
QAction *search = new QAction (tr ("Search"), this);
|
||||||
connect (search, SIGNAL (triggered()), this, SLOT (addSearchSubView()));
|
connect (search, SIGNAL (triggered()), this, SLOT (addSearchSubView()));
|
||||||
|
setupShortcut("document-edit-search", search);
|
||||||
edit->addAction (search);
|
edit->addAction (search);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVDoc::View::setupViewMenu()
|
void CSVDoc::View::setupViewMenu()
|
||||||
{
|
{
|
||||||
QMenu *view = menuBar()->addMenu (tr ("&View"));
|
QMenu *view = menuBar()->addMenu (tr ("View"));
|
||||||
|
|
||||||
QAction *newWindow = new QAction (tr ("&New View"), this);
|
QAction *newWindow = new QAction (tr ("New View"), this);
|
||||||
connect (newWindow, SIGNAL (triggered()), this, SLOT (newView()));
|
connect (newWindow, SIGNAL (triggered()), this, SLOT (newView()));
|
||||||
|
setupShortcut("document-view-newview", newWindow);
|
||||||
view->addAction (newWindow);
|
view->addAction (newWindow);
|
||||||
|
|
||||||
mShowStatusBar = new QAction (tr ("Show Status Bar"), this);
|
mShowStatusBar = new QAction (tr ("Toggle Status Bar"), this);
|
||||||
mShowStatusBar->setCheckable (true);
|
mShowStatusBar->setCheckable (true);
|
||||||
connect (mShowStatusBar, SIGNAL (toggled (bool)), this, SLOT (toggleShowStatusBar (bool)));
|
connect (mShowStatusBar, SIGNAL (toggled (bool)), this, SLOT (toggleShowStatusBar (bool)));
|
||||||
|
setupShortcut("document-view-statusbar", mShowStatusBar);
|
||||||
|
|
||||||
mShowStatusBar->setChecked (CSMPrefs::get()["Windows"]["show-statusbar"].isTrue());
|
mShowStatusBar->setChecked (CSMPrefs::get()["Windows"]["show-statusbar"].isTrue());
|
||||||
|
|
||||||
|
@ -128,70 +144,84 @@ void CSVDoc::View::setupViewMenu()
|
||||||
|
|
||||||
QAction *filters = new QAction (tr ("Filters"), this);
|
QAction *filters = new QAction (tr ("Filters"), this);
|
||||||
connect (filters, SIGNAL (triggered()), this, SLOT (addFiltersSubView()));
|
connect (filters, SIGNAL (triggered()), this, SLOT (addFiltersSubView()));
|
||||||
|
setupShortcut("document-view-filters", filters);
|
||||||
view->addAction (filters);
|
view->addAction (filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVDoc::View::setupWorldMenu()
|
void CSVDoc::View::setupWorldMenu()
|
||||||
{
|
{
|
||||||
QMenu *world = menuBar()->addMenu (tr ("&World"));
|
QMenu *world = menuBar()->addMenu (tr ("World"));
|
||||||
|
|
||||||
QAction *regions = new QAction (tr ("Regions"), this);
|
QAction *regions = new QAction (tr ("Regions"), this);
|
||||||
connect (regions, SIGNAL (triggered()), this, SLOT (addRegionsSubView()));
|
connect (regions, SIGNAL (triggered()), this, SLOT (addRegionsSubView()));
|
||||||
|
setupShortcut("document-world-regions", regions);
|
||||||
world->addAction (regions);
|
world->addAction (regions);
|
||||||
|
|
||||||
QAction *cells = new QAction (tr ("Cells"), this);
|
QAction *cells = new QAction (tr ("Cells"), this);
|
||||||
connect (cells, SIGNAL (triggered()), this, SLOT (addCellsSubView()));
|
connect (cells, SIGNAL (triggered()), this, SLOT (addCellsSubView()));
|
||||||
|
setupShortcut("document-world-cells", cells);
|
||||||
world->addAction (cells);
|
world->addAction (cells);
|
||||||
|
|
||||||
QAction *referenceables = new QAction (tr ("Objects"), this);
|
QAction *referenceables = new QAction (tr ("Objects"), this);
|
||||||
connect (referenceables, SIGNAL (triggered()), this, SLOT (addReferenceablesSubView()));
|
connect (referenceables, SIGNAL (triggered()), this, SLOT (addReferenceablesSubView()));
|
||||||
|
setupShortcut("document-world-referencables", referenceables);
|
||||||
world->addAction (referenceables);
|
world->addAction (referenceables);
|
||||||
|
|
||||||
QAction *references = new QAction (tr ("Instances"), this);
|
QAction *references = new QAction (tr ("Instances"), this);
|
||||||
connect (references, SIGNAL (triggered()), this, SLOT (addReferencesSubView()));
|
connect (references, SIGNAL (triggered()), this, SLOT (addReferencesSubView()));
|
||||||
|
setupShortcut("document-world-references", references);
|
||||||
world->addAction (references);
|
world->addAction (references);
|
||||||
|
|
||||||
QAction *grid = new QAction (tr ("Pathgrid"), this);
|
QAction *grid = new QAction (tr ("Pathgrid"), this);
|
||||||
connect (grid, SIGNAL (triggered()), this, SLOT (addPathgridSubView()));
|
connect (grid, SIGNAL (triggered()), this, SLOT (addPathgridSubView()));
|
||||||
|
setupShortcut("document-world-pathgrid", grid);
|
||||||
world->addAction (grid);
|
world->addAction (grid);
|
||||||
|
|
||||||
world->addSeparator(); // items that don't represent single record lists follow here
|
world->addSeparator(); // items that don't represent single record lists follow here
|
||||||
|
|
||||||
QAction *regionMap = new QAction (tr ("Region Map"), this);
|
QAction *regionMap = new QAction (tr ("Region Map"), this);
|
||||||
connect (regionMap, SIGNAL (triggered()), this, SLOT (addRegionMapSubView()));
|
connect (regionMap, SIGNAL (triggered()), this, SLOT (addRegionMapSubView()));
|
||||||
|
setupShortcut("document-world-regionmap", regionMap);
|
||||||
world->addAction (regionMap);
|
world->addAction (regionMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVDoc::View::setupMechanicsMenu()
|
void CSVDoc::View::setupMechanicsMenu()
|
||||||
{
|
{
|
||||||
QMenu *mechanics = menuBar()->addMenu (tr ("&Mechanics"));
|
QMenu *mechanics = menuBar()->addMenu (tr ("Mechanics"));
|
||||||
|
|
||||||
QAction *globals = new QAction (tr ("Globals"), this);
|
QAction *globals = new QAction (tr ("Globals"), this);
|
||||||
connect (globals, SIGNAL (triggered()), this, SLOT (addGlobalsSubView()));
|
connect (globals, SIGNAL (triggered()), this, SLOT (addGlobalsSubView()));
|
||||||
|
setupShortcut("document-mechanics-globals", globals);
|
||||||
mechanics->addAction (globals);
|
mechanics->addAction (globals);
|
||||||
|
|
||||||
QAction *gmsts = new QAction (tr ("Game settings"), this);
|
QAction *gmsts = new QAction (tr ("Game Settings"), this);
|
||||||
connect (gmsts, SIGNAL (triggered()), this, SLOT (addGmstsSubView()));
|
connect (gmsts, SIGNAL (triggered()), this, SLOT (addGmstsSubView()));
|
||||||
|
setupShortcut("document-mechanics-gamesettings", gmsts);
|
||||||
mechanics->addAction (gmsts);
|
mechanics->addAction (gmsts);
|
||||||
|
|
||||||
QAction *scripts = new QAction (tr ("Scripts"), this);
|
QAction *scripts = new QAction (tr ("Scripts"), this);
|
||||||
connect (scripts, SIGNAL (triggered()), this, SLOT (addScriptsSubView()));
|
connect (scripts, SIGNAL (triggered()), this, SLOT (addScriptsSubView()));
|
||||||
|
setupShortcut("document-mechanics-scripts", scripts);
|
||||||
mechanics->addAction (scripts);
|
mechanics->addAction (scripts);
|
||||||
|
|
||||||
QAction *spells = new QAction (tr ("Spells"), this);
|
QAction *spells = new QAction (tr ("Spells"), this);
|
||||||
connect (spells, SIGNAL (triggered()), this, SLOT (addSpellsSubView()));
|
connect (spells, SIGNAL (triggered()), this, SLOT (addSpellsSubView()));
|
||||||
|
setupShortcut("document-mechanics-spells", spells);
|
||||||
mechanics->addAction (spells);
|
mechanics->addAction (spells);
|
||||||
|
|
||||||
QAction *enchantments = new QAction (tr ("Enchantments"), this);
|
QAction *enchantments = new QAction (tr ("Enchantments"), this);
|
||||||
connect (enchantments, SIGNAL (triggered()), this, SLOT (addEnchantmentsSubView()));
|
connect (enchantments, SIGNAL (triggered()), this, SLOT (addEnchantmentsSubView()));
|
||||||
|
setupShortcut("document-mechanics-enchantments", enchantments);
|
||||||
mechanics->addAction (enchantments);
|
mechanics->addAction (enchantments);
|
||||||
|
|
||||||
QAction *effects = new QAction (tr ("Magic Effects"), this);
|
QAction *effects = new QAction (tr ("Magic Effects"), this);
|
||||||
connect (effects, SIGNAL (triggered()), this, SLOT (addMagicEffectsSubView()));
|
connect (effects, SIGNAL (triggered()), this, SLOT (addMagicEffectsSubView()));
|
||||||
|
setupShortcut("document-mechanics-magiceffects", effects);
|
||||||
mechanics->addAction (effects);
|
mechanics->addAction (effects);
|
||||||
|
|
||||||
QAction *startScripts = new QAction (tr ("Start Scripts"), this);
|
QAction *startScripts = new QAction (tr ("Start Scripts"), this);
|
||||||
connect (startScripts, SIGNAL (triggered()), this, SLOT (addStartScriptsSubView()));
|
connect (startScripts, SIGNAL (triggered()), this, SLOT (addStartScriptsSubView()));
|
||||||
|
setupShortcut("document-mechanics-startscripts", startScripts);
|
||||||
mechanics->addAction (startScripts);
|
mechanics->addAction (startScripts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,81 +231,99 @@ void CSVDoc::View::setupCharacterMenu()
|
||||||
|
|
||||||
QAction *skills = new QAction (tr ("Skills"), this);
|
QAction *skills = new QAction (tr ("Skills"), this);
|
||||||
connect (skills, SIGNAL (triggered()), this, SLOT (addSkillsSubView()));
|
connect (skills, SIGNAL (triggered()), this, SLOT (addSkillsSubView()));
|
||||||
|
setupShortcut("document-character-skills", skills);
|
||||||
characters->addAction (skills);
|
characters->addAction (skills);
|
||||||
|
|
||||||
QAction *classes = new QAction (tr ("Classes"), this);
|
QAction *classes = new QAction (tr ("Classes"), this);
|
||||||
connect (classes, SIGNAL (triggered()), this, SLOT (addClassesSubView()));
|
connect (classes, SIGNAL (triggered()), this, SLOT (addClassesSubView()));
|
||||||
|
setupShortcut("document-character-classes", classes);
|
||||||
characters->addAction (classes);
|
characters->addAction (classes);
|
||||||
|
|
||||||
QAction *factions = new QAction (tr ("Factions"), this);
|
QAction *factions = new QAction (tr ("Factions"), this);
|
||||||
connect (factions, SIGNAL (triggered()), this, SLOT (addFactionsSubView()));
|
connect (factions, SIGNAL (triggered()), this, SLOT (addFactionsSubView()));
|
||||||
|
setupShortcut("document-character-factions", factions);
|
||||||
characters->addAction (factions);
|
characters->addAction (factions);
|
||||||
|
|
||||||
QAction *races = new QAction (tr ("Races"), this);
|
QAction *races = new QAction (tr ("Races"), this);
|
||||||
connect (races, SIGNAL (triggered()), this, SLOT (addRacesSubView()));
|
connect (races, SIGNAL (triggered()), this, SLOT (addRacesSubView()));
|
||||||
|
setupShortcut("document-character-races", races);
|
||||||
characters->addAction (races);
|
characters->addAction (races);
|
||||||
|
|
||||||
QAction *birthsigns = new QAction (tr ("Birthsigns"), this);
|
QAction *birthsigns = new QAction (tr ("Birthsigns"), this);
|
||||||
connect (birthsigns, SIGNAL (triggered()), this, SLOT (addBirthsignsSubView()));
|
connect (birthsigns, SIGNAL (triggered()), this, SLOT (addBirthsignsSubView()));
|
||||||
|
setupShortcut("document-character-birthsigns", birthsigns);
|
||||||
characters->addAction (birthsigns);
|
characters->addAction (birthsigns);
|
||||||
|
|
||||||
QAction *topics = new QAction (tr ("Topics"), this);
|
QAction *topics = new QAction (tr ("Topics"), this);
|
||||||
connect (topics, SIGNAL (triggered()), this, SLOT (addTopicsSubView()));
|
connect (topics, SIGNAL (triggered()), this, SLOT (addTopicsSubView()));
|
||||||
|
setupShortcut("document-character-topics", topics);
|
||||||
characters->addAction (topics);
|
characters->addAction (topics);
|
||||||
|
|
||||||
QAction *journals = new QAction (tr ("Journals"), this);
|
QAction *journals = new QAction (tr ("Journals"), this);
|
||||||
connect (journals, SIGNAL (triggered()), this, SLOT (addJournalsSubView()));
|
connect (journals, SIGNAL (triggered()), this, SLOT (addJournalsSubView()));
|
||||||
|
setupShortcut("document-character-journals", journals);
|
||||||
characters->addAction (journals);
|
characters->addAction (journals);
|
||||||
|
|
||||||
QAction *topicInfos = new QAction (tr ("Topic Infos"), this);
|
QAction *topicInfos = new QAction (tr ("Topic Infos"), this);
|
||||||
connect (topicInfos, SIGNAL (triggered()), this, SLOT (addTopicInfosSubView()));
|
connect (topicInfos, SIGNAL (triggered()), this, SLOT (addTopicInfosSubView()));
|
||||||
|
setupShortcut("document-character-topicinfos", topicInfos);
|
||||||
characters->addAction (topicInfos);
|
characters->addAction (topicInfos);
|
||||||
|
|
||||||
QAction *journalInfos = new QAction (tr ("Journal Infos"), this);
|
QAction *journalInfos = new QAction (tr ("Journal Infos"), this);
|
||||||
connect (journalInfos, SIGNAL (triggered()), this, SLOT (addJournalInfosSubView()));
|
connect (journalInfos, SIGNAL (triggered()), this, SLOT (addJournalInfosSubView()));
|
||||||
|
setupShortcut("document-character-journalinfos", journalInfos);
|
||||||
characters->addAction (journalInfos);
|
characters->addAction (journalInfos);
|
||||||
|
|
||||||
QAction *bodyParts = new QAction (tr ("Body Parts"), this);
|
QAction *bodyParts = new QAction (tr ("Body Parts"), this);
|
||||||
connect (bodyParts, SIGNAL (triggered()), this, SLOT (addBodyPartsSubView()));
|
connect (bodyParts, SIGNAL (triggered()), this, SLOT (addBodyPartsSubView()));
|
||||||
|
setupShortcut("document-character-bodyparts", bodyParts);
|
||||||
characters->addAction (bodyParts);
|
characters->addAction (bodyParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVDoc::View::setupAssetsMenu()
|
void CSVDoc::View::setupAssetsMenu()
|
||||||
{
|
{
|
||||||
QMenu *assets = menuBar()->addMenu (tr ("&Assets"));
|
QMenu *assets = menuBar()->addMenu (tr ("Assets"));
|
||||||
|
|
||||||
QAction *sounds = new QAction (tr ("Sounds"), this);
|
QAction *sounds = new QAction (tr ("Sounds"), this);
|
||||||
connect (sounds, SIGNAL (triggered()), this, SLOT (addSoundsSubView()));
|
connect (sounds, SIGNAL (triggered()), this, SLOT (addSoundsSubView()));
|
||||||
|
setupShortcut("document-assets-sounds", sounds);
|
||||||
assets->addAction (sounds);
|
assets->addAction (sounds);
|
||||||
|
|
||||||
QAction *soundGens = new QAction (tr ("Sound Generators"), this);
|
QAction *soundGens = new QAction (tr ("Sound Generators"), this);
|
||||||
connect (soundGens, SIGNAL (triggered()), this, SLOT (addSoundGensSubView()));
|
connect (soundGens, SIGNAL (triggered()), this, SLOT (addSoundGensSubView()));
|
||||||
|
setupShortcut("document-assets-soundgens", soundGens);
|
||||||
assets->addAction (soundGens);
|
assets->addAction (soundGens);
|
||||||
|
|
||||||
assets->addSeparator(); // resources follow here
|
assets->addSeparator(); // resources follow here
|
||||||
|
|
||||||
QAction *meshes = new QAction (tr ("Meshes"), this);
|
QAction *meshes = new QAction (tr ("Meshes"), this);
|
||||||
connect (meshes, SIGNAL (triggered()), this, SLOT (addMeshesSubView()));
|
connect (meshes, SIGNAL (triggered()), this, SLOT (addMeshesSubView()));
|
||||||
|
setupShortcut("document-assets-meshes", meshes);
|
||||||
assets->addAction (meshes);
|
assets->addAction (meshes);
|
||||||
|
|
||||||
QAction *icons = new QAction (tr ("Icons"), this);
|
QAction *icons = new QAction (tr ("Icons"), this);
|
||||||
connect (icons, SIGNAL (triggered()), this, SLOT (addIconsSubView()));
|
connect (icons, SIGNAL (triggered()), this, SLOT (addIconsSubView()));
|
||||||
|
setupShortcut("document-assets-icons", icons);
|
||||||
assets->addAction (icons);
|
assets->addAction (icons);
|
||||||
|
|
||||||
QAction *musics = new QAction (tr ("Music"), this);
|
QAction *musics = new QAction (tr ("Music"), this);
|
||||||
connect (musics, SIGNAL (triggered()), this, SLOT (addMusicsSubView()));
|
connect (musics, SIGNAL (triggered()), this, SLOT (addMusicsSubView()));
|
||||||
|
setupShortcut("document-assets-music", musics);
|
||||||
assets->addAction (musics);
|
assets->addAction (musics);
|
||||||
|
|
||||||
QAction *soundsRes = new QAction (tr ("Sound Files"), this);
|
QAction *soundsRes = new QAction (tr ("Sound Files"), this);
|
||||||
connect (soundsRes, SIGNAL (triggered()), this, SLOT (addSoundsResSubView()));
|
connect (soundsRes, SIGNAL (triggered()), this, SLOT (addSoundsResSubView()));
|
||||||
|
setupShortcut("document-assets-soundres", soundsRes);
|
||||||
assets->addAction (soundsRes);
|
assets->addAction (soundsRes);
|
||||||
|
|
||||||
QAction *textures = new QAction (tr ("Textures"), this);
|
QAction *textures = new QAction (tr ("Textures"), this);
|
||||||
connect (textures, SIGNAL (triggered()), this, SLOT (addTexturesSubView()));
|
connect (textures, SIGNAL (triggered()), this, SLOT (addTexturesSubView()));
|
||||||
|
setupShortcut("document-assets-textures", textures);
|
||||||
assets->addAction (textures);
|
assets->addAction (textures);
|
||||||
|
|
||||||
QAction *videos = new QAction (tr ("Videos"), this);
|
QAction *videos = new QAction (tr ("Videos"), this);
|
||||||
connect (videos, SIGNAL (triggered()), this, SLOT (addVideosSubView()));
|
connect (videos, SIGNAL (triggered()), this, SLOT (addVideosSubView()));
|
||||||
|
setupShortcut("document-assets-videos", videos);
|
||||||
assets->addAction (videos);
|
assets->addAction (videos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,12 +347,16 @@ void CSVDoc::View::setupDebugMenu()
|
||||||
QAction *runDebug = debug->addMenu (mGlobalDebugProfileMenu);
|
QAction *runDebug = debug->addMenu (mGlobalDebugProfileMenu);
|
||||||
runDebug->setText (tr ("Run OpenMW"));
|
runDebug->setText (tr ("Run OpenMW"));
|
||||||
|
|
||||||
|
setupShortcut("document-debug-run", runDebug);
|
||||||
|
|
||||||
mStopDebug = new QAction (tr ("Shutdown OpenMW"), this);
|
mStopDebug = new QAction (tr ("Shutdown OpenMW"), this);
|
||||||
connect (mStopDebug, SIGNAL (triggered()), this, SLOT (stop()));
|
connect (mStopDebug, SIGNAL (triggered()), this, SLOT (stop()));
|
||||||
|
setupShortcut("document-debug-shutdown", mStopDebug);
|
||||||
debug->addAction (mStopDebug);
|
debug->addAction (mStopDebug);
|
||||||
|
|
||||||
QAction *runLog = new QAction (tr ("Run Log"), this);
|
QAction *runLog = new QAction (tr ("Open Run Log"), this);
|
||||||
connect (runLog, SIGNAL (triggered()), this, SLOT (addRunLogSubView()));
|
connect (runLog, SIGNAL (triggered()), this, SLOT (addRunLogSubView()));
|
||||||
|
setupShortcut("document-debug-runlog", runLog);
|
||||||
debug->addAction (runLog);
|
debug->addAction (runLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,6 +372,12 @@ void CSVDoc::View::setupUi()
|
||||||
setupDebugMenu();
|
setupDebugMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVDoc::View::setupShortcut(const char* name, QAction* action)
|
||||||
|
{
|
||||||
|
CSMPrefs::Shortcut* shortcut = new CSMPrefs::Shortcut(name, this);
|
||||||
|
shortcut->associateAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
void CSVDoc::View::updateTitle()
|
void CSVDoc::View::updateTitle()
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
|
|
|
@ -84,6 +84,8 @@ namespace CSVDoc
|
||||||
|
|
||||||
void setupUi();
|
void setupUi();
|
||||||
|
|
||||||
|
void setupShortcut(const char* name, QAction* action);
|
||||||
|
|
||||||
void updateActions();
|
void updateActions();
|
||||||
|
|
||||||
void exitApplication();
|
void exitApplication();
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "../../model/prefs/state.hpp"
|
#include "../../model/prefs/state.hpp"
|
||||||
|
|
||||||
#include "page.hpp"
|
#include "page.hpp"
|
||||||
|
#include "keybindingpage.hpp"
|
||||||
|
|
||||||
void CSVPrefs::Dialogue::buildCategorySelector (QSplitter *main)
|
void CSVPrefs::Dialogue::buildCategorySelector (QSplitter *main)
|
||||||
{
|
{
|
||||||
|
@ -52,8 +53,10 @@ void CSVPrefs::Dialogue::buildContentArea (QSplitter *main)
|
||||||
CSVPrefs::PageBase *CSVPrefs::Dialogue::makePage (const std::string& key)
|
CSVPrefs::PageBase *CSVPrefs::Dialogue::makePage (const std::string& key)
|
||||||
{
|
{
|
||||||
// special case page code goes here
|
// special case page code goes here
|
||||||
|
if (key == "Key Bindings")
|
||||||
return new Page (CSMPrefs::get()[key], mContent);
|
return new KeyBindingPage(CSMPrefs::get()[key], mContent);
|
||||||
|
else
|
||||||
|
return new Page (CSMPrefs::get()[key], mContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVPrefs::Dialogue::Dialogue()
|
CSVPrefs::Dialogue::Dialogue()
|
||||||
|
|
88
apps/opencs/view/prefs/keybindingpage.cpp
Normal file
88
apps/opencs/view/prefs/keybindingpage.cpp
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
#include "keybindingpage.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QStackedLayout>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "../../model/prefs/setting.hpp"
|
||||||
|
#include "../../model/prefs/category.hpp"
|
||||||
|
|
||||||
|
namespace CSVPrefs
|
||||||
|
{
|
||||||
|
KeyBindingPage::KeyBindingPage(CSMPrefs::Category& category, QWidget* parent)
|
||||||
|
: PageBase(category, parent)
|
||||||
|
, mStackedLayout(0)
|
||||||
|
, mPageLayout(0)
|
||||||
|
, mPageSelector(0)
|
||||||
|
{
|
||||||
|
// Need one widget for scroll area
|
||||||
|
QWidget* topWidget = new QWidget();
|
||||||
|
QVBoxLayout* topLayout = new QVBoxLayout(topWidget);
|
||||||
|
|
||||||
|
// Allows switching between "pages"
|
||||||
|
QWidget* stackedWidget = new QWidget();
|
||||||
|
mStackedLayout = new QStackedLayout(stackedWidget);
|
||||||
|
|
||||||
|
mPageSelector = new QComboBox();
|
||||||
|
connect(mPageSelector, SIGNAL(currentIndexChanged(int)), mStackedLayout, SLOT(setCurrentIndex(int)));
|
||||||
|
|
||||||
|
topLayout->addWidget(mPageSelector);
|
||||||
|
topLayout->addWidget(stackedWidget);
|
||||||
|
topLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
|
||||||
|
|
||||||
|
// Add each option
|
||||||
|
for (CSMPrefs::Category::Iterator iter = category.begin(); iter!=category.end(); ++iter)
|
||||||
|
addSetting (*iter);
|
||||||
|
|
||||||
|
setWidgetResizable(true);
|
||||||
|
setWidget(topWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyBindingPage::addSetting(CSMPrefs::Setting *setting)
|
||||||
|
{
|
||||||
|
std::pair<QWidget*, QWidget*> widgets = setting->makeWidgets (this);
|
||||||
|
|
||||||
|
if (widgets.first)
|
||||||
|
{
|
||||||
|
// Label, Option widgets
|
||||||
|
assert(mPageLayout);
|
||||||
|
|
||||||
|
int next = mPageLayout->rowCount();
|
||||||
|
mPageLayout->addWidget(widgets.first, next, 0);
|
||||||
|
mPageLayout->addWidget(widgets.second, next, 1);
|
||||||
|
}
|
||||||
|
else if (widgets.second)
|
||||||
|
{
|
||||||
|
// Wide single widget
|
||||||
|
assert(mPageLayout);
|
||||||
|
|
||||||
|
int next = mPageLayout->rowCount();
|
||||||
|
mPageLayout->addWidget(widgets.second, next, 0, 1, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (setting->getLabel().empty())
|
||||||
|
{
|
||||||
|
// Insert empty space
|
||||||
|
assert(mPageLayout);
|
||||||
|
|
||||||
|
int next = mPageLayout->rowCount();
|
||||||
|
mPageLayout->addWidget(new QWidget(), next, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create new page
|
||||||
|
QWidget* pageWidget = new QWidget();
|
||||||
|
mPageLayout = new QGridLayout(pageWidget);
|
||||||
|
mPageLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
|
||||||
|
|
||||||
|
mStackedLayout->addWidget(pageWidget);
|
||||||
|
|
||||||
|
mPageSelector->addItem(QString::fromUtf8(setting->getLabel().c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
apps/opencs/view/prefs/keybindingpage.hpp
Normal file
35
apps/opencs/view/prefs/keybindingpage.hpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef CSV_PREFS_KEYBINDINGPAGE_H
|
||||||
|
#define CSV_PREFS_KEYBINDINGPAGE_H
|
||||||
|
|
||||||
|
#include "pagebase.hpp"
|
||||||
|
|
||||||
|
class QComboBox;
|
||||||
|
class QGridLayout;
|
||||||
|
class QStackedLayout;
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class Setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVPrefs
|
||||||
|
{
|
||||||
|
class KeyBindingPage : public PageBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
KeyBindingPage(CSMPrefs::Category& category, QWidget* parent);
|
||||||
|
|
||||||
|
void addSetting(CSMPrefs::Setting* setting);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QStackedLayout* mStackedLayout;
|
||||||
|
QGridLayout* mPageLayout;
|
||||||
|
QComboBox* mPageSelector;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include <QKeyEvent>
|
#include <QWidget>
|
||||||
|
|
||||||
#include <osg/BoundingBox>
|
#include <osg/BoundingBox>
|
||||||
#include <osg/Camera>
|
#include <osg/Camera>
|
||||||
|
@ -14,6 +14,10 @@
|
||||||
|
|
||||||
#include <osgUtil/LineSegmentIntersector>
|
#include <osgUtil/LineSegmentIntersector>
|
||||||
|
|
||||||
|
#include "../../model/prefs/shortcut.hpp"
|
||||||
|
|
||||||
|
#include "scenewidget.hpp"
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -27,8 +31,9 @@ namespace CSVRender
|
||||||
const osg::Vec3d CameraController::LocalLeft = osg::Vec3d(1, 0, 0);
|
const osg::Vec3d CameraController::LocalLeft = osg::Vec3d(1, 0, 0);
|
||||||
const osg::Vec3d CameraController::LocalForward = osg::Vec3d(0, 0, 1);
|
const osg::Vec3d CameraController::LocalForward = osg::Vec3d(0, 0, 1);
|
||||||
|
|
||||||
CameraController::CameraController()
|
CameraController::CameraController(QObject* parent)
|
||||||
: mActive(false)
|
: QObject(parent)
|
||||||
|
, mActive(false)
|
||||||
, mInverted(false)
|
, mInverted(false)
|
||||||
, mCameraSensitivity(1/650.f)
|
, mCameraSensitivity(1/650.f)
|
||||||
, mSecondaryMoveMult(50)
|
, mSecondaryMoveMult(50)
|
||||||
|
@ -73,11 +78,19 @@ 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)
|
||||||
|
{
|
||||||
|
CSMPrefs::Shortcut* shortcut = *it;
|
||||||
|
shortcut->enable(mActive);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraController::setCameraSensitivity(double value)
|
void CameraController::setCameraSensitivity(double value)
|
||||||
|
@ -136,14 +149,23 @@ 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()
|
FreeCameraController::FreeCameraController(QWidget* widget)
|
||||||
: mLockUpright(false)
|
: CameraController(widget)
|
||||||
|
, mLockUpright(false)
|
||||||
, mModified(false)
|
, mModified(false)
|
||||||
|
, mNaviPrimary(false)
|
||||||
|
, mNaviSecondary(false)
|
||||||
, mFast(false)
|
, mFast(false)
|
||||||
|
, mFastAlternate(false)
|
||||||
, mLeft(false)
|
, mLeft(false)
|
||||||
, mRight(false)
|
, mRight(false)
|
||||||
, mForward(false)
|
, mForward(false)
|
||||||
|
@ -155,6 +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", widget);
|
||||||
|
naviPrimaryShortcut->enable(false);
|
||||||
|
connect(naviPrimaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviPrimary(bool)));
|
||||||
|
|
||||||
|
addShortcut(naviPrimaryShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* naviSecondaryShortcut = new CSMPrefs::Shortcut("scene-navi-secondary", widget);
|
||||||
|
naviSecondaryShortcut->enable(false);
|
||||||
|
connect(naviSecondaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviSecondary(bool)));
|
||||||
|
|
||||||
|
addShortcut(naviSecondaryShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* forwardShortcut = new CSMPrefs::Shortcut("free-forward", "scene-speed-modifier",
|
||||||
|
CSMPrefs::Shortcut::SM_Detach, widget);
|
||||||
|
forwardShortcut->enable(false);
|
||||||
|
connect(forwardShortcut, SIGNAL(activated(bool)), this, SLOT(forward(bool)));
|
||||||
|
connect(forwardShortcut, SIGNAL(secondary(bool)), this, SLOT(alternateFast(bool)));
|
||||||
|
|
||||||
|
addShortcut(forwardShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("free-left", widget);
|
||||||
|
leftShortcut->enable(false);
|
||||||
|
connect(leftShortcut, SIGNAL(activated(bool)), this, SLOT(left(bool)));
|
||||||
|
|
||||||
|
addShortcut(leftShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* backShortcut = new CSMPrefs::Shortcut("free-backward", widget);
|
||||||
|
backShortcut->enable(false);
|
||||||
|
connect(backShortcut, SIGNAL(activated(bool)), this, SLOT(backward(bool)));
|
||||||
|
|
||||||
|
addShortcut(backShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* rightShortcut = new CSMPrefs::Shortcut("free-right", widget);
|
||||||
|
rightShortcut->enable(false);
|
||||||
|
connect(rightShortcut, SIGNAL(activated(bool)), this, SLOT(right(bool)));
|
||||||
|
|
||||||
|
addShortcut(rightShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* rollLeftShortcut = new CSMPrefs::Shortcut("free-roll-left", widget);
|
||||||
|
rollLeftShortcut->enable(false);
|
||||||
|
connect(rollLeftShortcut, SIGNAL(activated(bool)), this, SLOT(rollLeft(bool)));
|
||||||
|
|
||||||
|
addShortcut(rollLeftShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* rollRightShortcut = new CSMPrefs::Shortcut("free-roll-right", widget);
|
||||||
|
rollRightShortcut->enable(false);
|
||||||
|
connect(rollRightShortcut, SIGNAL(activated(bool)), this, SLOT(rollRight(bool)));
|
||||||
|
|
||||||
|
addShortcut(rollRightShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("free-speed-mode", widget);
|
||||||
|
speedModeShortcut->enable(false);
|
||||||
|
connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
|
||||||
|
|
||||||
|
addShortcut(speedModeShortcut);
|
||||||
}
|
}
|
||||||
|
|
||||||
double FreeCameraController::getLinearSpeed() const
|
double FreeCameraController::getLinearSpeed() const
|
||||||
|
@ -199,59 +276,18 @@ namespace CSVRender
|
||||||
mLockUpright = false;
|
mLockUpright = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FreeCameraController::handleKeyEvent(QKeyEvent* event, bool pressed)
|
void FreeCameraController::handleMouseMoveEvent(int x, int y)
|
||||||
{
|
{
|
||||||
if (!isActive())
|
if (!isActive())
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
if (event->key() == Qt::Key_Q)
|
if (mNaviPrimary)
|
||||||
{
|
|
||||||
mRollLeft = pressed;
|
|
||||||
}
|
|
||||||
else if (event->key() == Qt::Key_E)
|
|
||||||
{
|
|
||||||
mRollRight = pressed;
|
|
||||||
}
|
|
||||||
else if (event->key() == Qt::Key_A)
|
|
||||||
{
|
|
||||||
mLeft = pressed;
|
|
||||||
}
|
|
||||||
else if (event->key() == Qt::Key_D)
|
|
||||||
{
|
|
||||||
mRight = pressed;
|
|
||||||
}
|
|
||||||
else if (event->key() == Qt::Key_W)
|
|
||||||
{
|
|
||||||
mForward = pressed;
|
|
||||||
}
|
|
||||||
else if (event->key() == Qt::Key_S)
|
|
||||||
{
|
|
||||||
mBackward = pressed;
|
|
||||||
}
|
|
||||||
else if (event->key() == Qt::Key_Shift)
|
|
||||||
{
|
|
||||||
mFast = pressed;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FreeCameraController::handleMouseMoveEvent(std::string mode, int x, int y)
|
|
||||||
{
|
|
||||||
if (!isActive())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (mode == "p-navi")
|
|
||||||
{
|
{
|
||||||
double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0);
|
double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0);
|
||||||
yaw(x * scalar);
|
yaw(x * scalar);
|
||||||
pitch(y * scalar);
|
pitch(y * scalar);
|
||||||
}
|
}
|
||||||
else if (mode == "s-navi")
|
else if (mNaviSecondary)
|
||||||
{
|
{
|
||||||
osg::Vec3d movement;
|
osg::Vec3d movement;
|
||||||
movement += LocalLeft * -x * getSecondaryMovementMultiplier();
|
movement += LocalLeft * -x * getSecondaryMovementMultiplier();
|
||||||
|
@ -259,16 +295,14 @@ namespace CSVRender
|
||||||
|
|
||||||
translate(movement);
|
translate(movement);
|
||||||
}
|
}
|
||||||
else if (mode == "t-navi")
|
}
|
||||||
{
|
|
||||||
translate(LocalForward * x * (mFast ? getWheelMovementMultiplier() : 1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
void FreeCameraController::handleMouseScrollEvent(int x)
|
||||||
|
{
|
||||||
|
if (!isActive())
|
||||||
|
return;
|
||||||
|
|
||||||
|
translate(LocalForward * x * ((mFast ^ mFastAlternate) ? getWheelMovementMultiplier() : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeCameraController::update(double dt)
|
void FreeCameraController::update(double dt)
|
||||||
|
@ -279,7 +313,7 @@ namespace CSVRender
|
||||||
double linDist = mLinSpeed * dt;
|
double linDist = mLinSpeed * dt;
|
||||||
double rotDist = mRotSpeed * dt;
|
double rotDist = mRotSpeed * dt;
|
||||||
|
|
||||||
if (mFast)
|
if (mFast ^ mFastAlternate)
|
||||||
linDist *= mSpeedMult;
|
linDist *= mSpeedMult;
|
||||||
|
|
||||||
if (mLeft)
|
if (mLeft)
|
||||||
|
@ -308,17 +342,6 @@ namespace CSVRender
|
||||||
getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix());
|
getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeCameraController::resetInput()
|
|
||||||
{
|
|
||||||
mFast = false;
|
|
||||||
mLeft = false;
|
|
||||||
mRight = false;
|
|
||||||
mForward = false;
|
|
||||||
mBackward = false;
|
|
||||||
mRollLeft = false;
|
|
||||||
mRollRight = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FreeCameraController::yaw(double value)
|
void FreeCameraController::yaw(double value)
|
||||||
{
|
{
|
||||||
getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalUp);
|
getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalUp);
|
||||||
|
@ -368,13 +391,67 @@ namespace CSVRender
|
||||||
getCamera()->setViewMatrixAsLookAt(eye, center, mUp);
|
getCamera()->setViewMatrixAsLookAt(eye, center, mUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FreeCameraController::naviPrimary(bool active)
|
||||||
|
{
|
||||||
|
mNaviPrimary = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeCameraController::naviSecondary(bool active)
|
||||||
|
{
|
||||||
|
mNaviSecondary = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeCameraController::forward(bool active)
|
||||||
|
{
|
||||||
|
mForward = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeCameraController::left(bool active)
|
||||||
|
{
|
||||||
|
mLeft = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeCameraController::backward(bool active)
|
||||||
|
{
|
||||||
|
mBackward = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeCameraController::right(bool active)
|
||||||
|
{
|
||||||
|
mRight = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeCameraController::rollLeft(bool active)
|
||||||
|
{
|
||||||
|
mRollLeft = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeCameraController::rollRight(bool active)
|
||||||
|
{
|
||||||
|
mRollRight = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeCameraController::alternateFast(bool active)
|
||||||
|
{
|
||||||
|
mFastAlternate = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeCameraController::swapSpeedMode()
|
||||||
|
{
|
||||||
|
mFast = !mFast;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Orbit Camera Controller
|
Orbit Camera Controller
|
||||||
*/
|
*/
|
||||||
|
|
||||||
OrbitCameraController::OrbitCameraController()
|
OrbitCameraController::OrbitCameraController(QWidget* widget)
|
||||||
: mInitialized(false)
|
: CameraController(widget)
|
||||||
|
, mInitialized(false)
|
||||||
|
, mNaviPrimary(false)
|
||||||
|
, mNaviSecondary(false)
|
||||||
, mFast(false)
|
, mFast(false)
|
||||||
|
, mFastAlternate(false)
|
||||||
, mLeft(false)
|
, mLeft(false)
|
||||||
, mRight(false)
|
, mRight(false)
|
||||||
, mUp(false)
|
, mUp(false)
|
||||||
|
@ -387,6 +464,61 @@ namespace CSVRender
|
||||||
, mOrbitSpeed(osg::PI / 4)
|
, mOrbitSpeed(osg::PI / 4)
|
||||||
, mOrbitSpeedMult(4)
|
, mOrbitSpeedMult(4)
|
||||||
{
|
{
|
||||||
|
CSMPrefs::Shortcut* naviPrimaryShortcut = new CSMPrefs::Shortcut("scene-navi-primary", widget);
|
||||||
|
naviPrimaryShortcut->enable(false);
|
||||||
|
connect(naviPrimaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviPrimary(bool)));
|
||||||
|
|
||||||
|
addShortcut(naviPrimaryShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* naviSecondaryShortcut = new CSMPrefs::Shortcut("scene-navi-secondary", widget);
|
||||||
|
naviSecondaryShortcut->enable(false);
|
||||||
|
connect(naviSecondaryShortcut, SIGNAL(activated(bool)), this, SLOT(naviSecondary(bool)));
|
||||||
|
|
||||||
|
addShortcut(naviSecondaryShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* upShortcut = new CSMPrefs::Shortcut("orbit-up", "scene-speed-modifier",
|
||||||
|
CSMPrefs::Shortcut::SM_Detach, widget);
|
||||||
|
upShortcut->enable(false);
|
||||||
|
connect(upShortcut, SIGNAL(activated(bool)), this, SLOT(up(bool)));
|
||||||
|
connect(upShortcut, SIGNAL(secondary(bool)), this, SLOT(alternateFast(bool)));
|
||||||
|
|
||||||
|
addShortcut(upShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("orbit-left", widget);
|
||||||
|
leftShortcut->enable(false);
|
||||||
|
connect(leftShortcut, SIGNAL(activated(bool)), this, SLOT(left(bool)));
|
||||||
|
|
||||||
|
addShortcut(leftShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* downShortcut = new CSMPrefs::Shortcut("orbit-down", widget);
|
||||||
|
downShortcut->enable(false);
|
||||||
|
connect(downShortcut, SIGNAL(activated(bool)), this, SLOT(down(bool)));
|
||||||
|
|
||||||
|
addShortcut(downShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* rightShortcut = new CSMPrefs::Shortcut("orbit-right", widget);
|
||||||
|
rightShortcut->enable(false);
|
||||||
|
connect(rightShortcut, SIGNAL(activated(bool)), this, SLOT(right(bool)));
|
||||||
|
|
||||||
|
addShortcut(rightShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* rollLeftShortcut = new CSMPrefs::Shortcut("orbit-roll-left", widget);
|
||||||
|
rollLeftShortcut->enable(false);
|
||||||
|
connect(rollLeftShortcut, SIGNAL(activated(bool)), this, SLOT(rollLeft(bool)));
|
||||||
|
|
||||||
|
addShortcut(rollLeftShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* rollRightShortcut = new CSMPrefs::Shortcut("orbit-roll-right", widget);
|
||||||
|
rollRightShortcut->enable(false);
|
||||||
|
connect(rollRightShortcut, SIGNAL(activated(bool)), this, SLOT(rollRight(bool)));
|
||||||
|
|
||||||
|
addShortcut(rollRightShortcut);
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("orbit-speed-mode", widget);
|
||||||
|
speedModeShortcut->enable(false);
|
||||||
|
connect(speedModeShortcut, SIGNAL(activated()), this, SLOT(swapSpeedMode()));
|
||||||
|
|
||||||
|
addShortcut(speedModeShortcut);
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3d OrbitCameraController::getCenter() const
|
osg::Vec3d OrbitCameraController::getCenter() const
|
||||||
|
@ -437,65 +569,21 @@ namespace CSVRender
|
||||||
mPickingMask = value;
|
mPickingMask = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OrbitCameraController::handleKeyEvent(QKeyEvent* event, bool pressed)
|
void OrbitCameraController::handleMouseMoveEvent(int x, int y)
|
||||||
{
|
{
|
||||||
if (!isActive())
|
if (!isActive())
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
if (!mInitialized)
|
if (!mInitialized)
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
if (event->key() == Qt::Key_Q)
|
if (mNaviPrimary)
|
||||||
{
|
|
||||||
mRollLeft = pressed;
|
|
||||||
}
|
|
||||||
else if (event->key() == Qt::Key_E)
|
|
||||||
{
|
|
||||||
mRollRight = pressed;
|
|
||||||
}
|
|
||||||
else if (event->key() == Qt::Key_A)
|
|
||||||
{
|
|
||||||
mLeft = pressed;
|
|
||||||
}
|
|
||||||
else if (event->key() == Qt::Key_D)
|
|
||||||
{
|
|
||||||
mRight = pressed;
|
|
||||||
}
|
|
||||||
else if (event->key() == Qt::Key_W)
|
|
||||||
{
|
|
||||||
mUp = pressed;
|
|
||||||
}
|
|
||||||
else if (event->key() == Qt::Key_S)
|
|
||||||
{
|
|
||||||
mDown = pressed;
|
|
||||||
}
|
|
||||||
else if (event->key() == Qt::Key_Shift)
|
|
||||||
{
|
|
||||||
mFast = pressed;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OrbitCameraController::handleMouseMoveEvent(std::string mode, int x, int y)
|
|
||||||
{
|
|
||||||
if (!isActive())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!mInitialized)
|
|
||||||
initialize();
|
|
||||||
|
|
||||||
if (mode == "p-navi")
|
|
||||||
{
|
{
|
||||||
double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0);
|
double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0);
|
||||||
rotateHorizontal(x * scalar);
|
rotateHorizontal(x * scalar);
|
||||||
rotateVertical(-y * scalar);
|
rotateVertical(-y * scalar);
|
||||||
}
|
}
|
||||||
else if (mode == "s-navi")
|
else if (mNaviSecondary)
|
||||||
{
|
{
|
||||||
osg::Vec3d movement;
|
osg::Vec3d movement;
|
||||||
movement += LocalLeft * x * getSecondaryMovementMultiplier();
|
movement += LocalLeft * x * getSecondaryMovementMultiplier();
|
||||||
|
@ -503,16 +591,14 @@ namespace CSVRender
|
||||||
|
|
||||||
translate(movement);
|
translate(movement);
|
||||||
}
|
}
|
||||||
else if (mode == "t-navi")
|
}
|
||||||
{
|
|
||||||
zoom(-x * (mFast ? getWheelMovementMultiplier() : 1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
void OrbitCameraController::handleMouseScrollEvent(int x)
|
||||||
|
{
|
||||||
|
if (!isActive())
|
||||||
|
return;
|
||||||
|
|
||||||
|
zoom(-x * ((mFast ^ mFastAlternate) ? getWheelMovementMultiplier() : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OrbitCameraController::update(double dt)
|
void OrbitCameraController::update(double dt)
|
||||||
|
@ -525,7 +611,7 @@ namespace CSVRender
|
||||||
|
|
||||||
double rotDist = mOrbitSpeed * dt;
|
double rotDist = mOrbitSpeed * dt;
|
||||||
|
|
||||||
if (mFast)
|
if (mFast ^ mFastAlternate)
|
||||||
rotDist *= mOrbitSpeedMult;
|
rotDist *= mOrbitSpeedMult;
|
||||||
|
|
||||||
if (mLeft)
|
if (mLeft)
|
||||||
|
@ -546,17 +632,6 @@ namespace CSVRender
|
||||||
getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix());
|
getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OrbitCameraController::resetInput()
|
|
||||||
{
|
|
||||||
mFast = false;
|
|
||||||
mLeft = false;
|
|
||||||
mRight =false;
|
|
||||||
mUp = false;
|
|
||||||
mDown = false;
|
|
||||||
mRollLeft = false;
|
|
||||||
mRollRight = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OrbitCameraController::onActivate()
|
void OrbitCameraController::onActivate()
|
||||||
{
|
{
|
||||||
mInitialized = false;
|
mInitialized = false;
|
||||||
|
@ -647,4 +722,55 @@ namespace CSVRender
|
||||||
|
|
||||||
getCamera()->setViewMatrixAsLookAt(mCenter + offset, mCenter, up);
|
getCamera()->setViewMatrixAsLookAt(mCenter + offset, mCenter, up);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OrbitCameraController::naviPrimary(bool active)
|
||||||
|
{
|
||||||
|
mNaviPrimary = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrbitCameraController::naviSecondary(bool active)
|
||||||
|
{
|
||||||
|
mNaviSecondary = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrbitCameraController::up(bool active)
|
||||||
|
{
|
||||||
|
mUp = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrbitCameraController::left(bool active)
|
||||||
|
{
|
||||||
|
mLeft = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrbitCameraController::down(bool active)
|
||||||
|
{
|
||||||
|
mDown = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrbitCameraController::right(bool active)
|
||||||
|
{
|
||||||
|
mRight = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrbitCameraController::rollLeft(bool active)
|
||||||
|
{
|
||||||
|
if (isActive())
|
||||||
|
mRollLeft = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrbitCameraController::rollRight(bool active)
|
||||||
|
{
|
||||||
|
mRollRight = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrbitCameraController::alternateFast(bool active)
|
||||||
|
{
|
||||||
|
mFastAlternate = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrbitCameraController::swapSpeedMode()
|
||||||
|
{
|
||||||
|
mFast = !mFast;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,22 +2,32 @@
|
||||||
#define OPENCS_VIEW_CAMERACONTROLLER_H
|
#define OPENCS_VIEW_CAMERACONTROLLER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#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;
|
||||||
class Group;
|
class Group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class Shortcut;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
{
|
{
|
||||||
class CameraController
|
class SceneWidget;
|
||||||
|
|
||||||
|
class CameraController : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static const osg::Vec3d WorldUp;
|
static const osg::Vec3d WorldUp;
|
||||||
|
@ -26,7 +36,7 @@ namespace CSVRender
|
||||||
static const osg::Vec3d LocalLeft;
|
static const osg::Vec3d LocalLeft;
|
||||||
static const osg::Vec3d LocalForward;
|
static const osg::Vec3d LocalForward;
|
||||||
|
|
||||||
CameraController();
|
CameraController(QObject* parent);
|
||||||
virtual ~CameraController();
|
virtual ~CameraController();
|
||||||
|
|
||||||
bool isActive() const;
|
bool isActive() const;
|
||||||
|
@ -46,17 +56,17 @@ namespace CSVRender
|
||||||
// moves the camera to an intelligent position
|
// moves the camera to an intelligent position
|
||||||
void setup(osg::Group* root, unsigned int mask, const osg::Vec3d& up);
|
void setup(osg::Group* root, unsigned int mask, const osg::Vec3d& up);
|
||||||
|
|
||||||
virtual bool handleKeyEvent(QKeyEvent* event, bool pressed) = 0;
|
virtual void handleMouseMoveEvent(int x, int y) = 0;
|
||||||
virtual bool handleMouseMoveEvent(std::string mode, int x, int y) = 0;
|
virtual void handleMouseScrollEvent(int x) = 0;
|
||||||
|
|
||||||
virtual void update(double dt) = 0;
|
virtual void update(double dt) = 0;
|
||||||
|
|
||||||
virtual void resetInput() = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void onActivate(){}
|
virtual void onActivate(){}
|
||||||
|
|
||||||
|
void addShortcut(CSMPrefs::Shortcut* shortcut);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool mActive, mInverted;
|
bool mActive, mInverted;
|
||||||
|
@ -65,13 +75,17 @@ 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
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FreeCameraController();
|
FreeCameraController(QWidget* parent);
|
||||||
|
|
||||||
double getLinearSpeed() const;
|
double getLinearSpeed() const;
|
||||||
double getRotationalSpeed() const;
|
double getRotationalSpeed() const;
|
||||||
|
@ -84,13 +98,11 @@ namespace CSVRender
|
||||||
void fixUpAxis(const osg::Vec3d& up);
|
void fixUpAxis(const osg::Vec3d& up);
|
||||||
void unfixUpAxis();
|
void unfixUpAxis();
|
||||||
|
|
||||||
bool handleKeyEvent(QKeyEvent* event, bool pressed);
|
void handleMouseMoveEvent(int x, int y);
|
||||||
bool handleMouseMoveEvent(std::string mode, int x, int y);
|
void handleMouseScrollEvent(int x);
|
||||||
|
|
||||||
void update(double dt);
|
void update(double dt);
|
||||||
|
|
||||||
void resetInput();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void yaw(double value);
|
void yaw(double value);
|
||||||
|
@ -101,19 +113,36 @@ namespace CSVRender
|
||||||
void stabilize();
|
void stabilize();
|
||||||
|
|
||||||
bool mLockUpright, mModified;
|
bool mLockUpright, mModified;
|
||||||
bool mFast, mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight;
|
bool mNaviPrimary, mNaviSecondary;
|
||||||
|
bool mFast, mFastAlternate;
|
||||||
|
bool mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight;
|
||||||
osg::Vec3d mUp;
|
osg::Vec3d mUp;
|
||||||
|
|
||||||
double mLinSpeed;
|
double mLinSpeed;
|
||||||
double mRotSpeed;
|
double mRotSpeed;
|
||||||
double mSpeedMult;
|
double mSpeedMult;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void naviPrimary(bool active);
|
||||||
|
void naviSecondary(bool active);
|
||||||
|
void forward(bool active);
|
||||||
|
void left(bool active);
|
||||||
|
void backward(bool active);
|
||||||
|
void right(bool active);
|
||||||
|
void rollLeft(bool active);
|
||||||
|
void rollRight(bool active);
|
||||||
|
void alternateFast(bool active);
|
||||||
|
void swapSpeedMode();
|
||||||
};
|
};
|
||||||
|
|
||||||
class OrbitCameraController : public CameraController
|
class OrbitCameraController : public CameraController
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
OrbitCameraController();
|
OrbitCameraController(QWidget* parent);
|
||||||
|
|
||||||
osg::Vec3d getCenter() const;
|
osg::Vec3d getCenter() const;
|
||||||
double getOrbitSpeed() const;
|
double getOrbitSpeed() const;
|
||||||
|
@ -125,13 +154,11 @@ namespace CSVRender
|
||||||
void setOrbitSpeedMultiplier(double value);
|
void setOrbitSpeedMultiplier(double value);
|
||||||
void setPickingMask(unsigned int value);
|
void setPickingMask(unsigned int value);
|
||||||
|
|
||||||
bool handleKeyEvent(QKeyEvent* event, bool pressed);
|
void handleMouseMoveEvent(int x, int y);
|
||||||
bool handleMouseMoveEvent(std::string mode, int x, int y);
|
void handleMouseScrollEvent(int x);
|
||||||
|
|
||||||
void update(double dt);
|
void update(double dt);
|
||||||
|
|
||||||
void resetInput();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void onActivate();
|
void onActivate();
|
||||||
|
@ -145,13 +172,28 @@ namespace CSVRender
|
||||||
void zoom(double value);
|
void zoom(double value);
|
||||||
|
|
||||||
bool mInitialized;
|
bool mInitialized;
|
||||||
bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight;
|
bool mNaviPrimary, mNaviSecondary;
|
||||||
|
bool mFast, mFastAlternate;
|
||||||
|
bool mLeft, mRight, mUp, mDown, mRollLeft, mRollRight;
|
||||||
unsigned int mPickingMask;
|
unsigned int mPickingMask;
|
||||||
osg::Vec3d mCenter;
|
osg::Vec3d mCenter;
|
||||||
double mDistance;
|
double mDistance;
|
||||||
|
|
||||||
double mOrbitSpeed;
|
double mOrbitSpeed;
|
||||||
double mOrbitSpeedMult;
|
double mOrbitSpeedMult;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void naviPrimary(bool active);
|
||||||
|
void naviSecondary(bool active);
|
||||||
|
void up(bool active);
|
||||||
|
void left(bool active);
|
||||||
|
void down(bool active);
|
||||||
|
void right(bool active);
|
||||||
|
void rollLeft(bool active);
|
||||||
|
void rollRight(bool active);
|
||||||
|
void alternateFast(bool active);
|
||||||
|
void swapSpeedMode();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
#include <osg/Geometry>
|
#include <osg/Geometry>
|
||||||
#include <osg/PrimitiveSet>
|
#include <osg/PrimitiveSet>
|
||||||
|
|
||||||
|
#include "../../model/prefs/state.hpp"
|
||||||
|
#include "../../model/prefs/shortcutmanager.hpp"
|
||||||
|
|
||||||
#include "mask.hpp"
|
#include "mask.hpp"
|
||||||
|
|
||||||
CSVRender::CellArrowTag::CellArrowTag (CellArrow *arrow)
|
CSVRender::CellArrowTag::CellArrowTag (CellArrow *arrow)
|
||||||
|
@ -35,14 +38,19 @@ QString CSVRender::CellArrowTag::getToolTip (bool hideBasics) const
|
||||||
text +=
|
text +=
|
||||||
"<p>"
|
"<p>"
|
||||||
"Modify which cells are shown"
|
"Modify which cells are shown"
|
||||||
"<ul><li>Primary-Edit: Add cell in given direction</li>"
|
"<ul><li>{scene-edit-primary}: Add cell in given direction</li>"
|
||||||
"<li>Secondary-Edit: Add cell and remove old cell</li>"
|
"<li>{scene-edit-secondary}: Add cell and remove old cell</li>"
|
||||||
"<li>Shift Primary-Edit: Add cells in given direction</li>"
|
"<li>{scene-select-primary}: Add cells in given direction</li>"
|
||||||
"<li>Shift Secondary-Edit: Add cells and remove old cells</li>"
|
"<li>{scene-select-secondary}: Add cells and remove old cells</li>"
|
||||||
|
"<li>{scene-load-cam-cell}: Load cell where camera is located</li>"
|
||||||
|
"<li>{scene-load-cam-eastcell}: Load cell to east</li>"
|
||||||
|
"<li>{scene-load-cam-northcell}: Load cell to north</li>"
|
||||||
|
"<li>{scene-load-cam-westcell}: Load cell to west</li>"
|
||||||
|
"<li>{scene-load-cam-southcell}: Load cell to south</li>"
|
||||||
"</ul>";
|
"</ul>";
|
||||||
}
|
}
|
||||||
|
|
||||||
return text;
|
return CSMPrefs::State::get().getShortcutManager().processToolTip(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,14 +42,14 @@ void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
|
||||||
mSubMode->addButton (new InstanceMoveMode (this), "move");
|
mSubMode->addButton (new InstanceMoveMode (this), "move");
|
||||||
mSubMode->addButton (":placeholder", "rotate",
|
mSubMode->addButton (":placeholder", "rotate",
|
||||||
"Rotate selected instances"
|
"Rotate selected instances"
|
||||||
"<ul><li>Use primary edit to rotate instances freely</li>"
|
"<ul><li>Use {scene-edit-primary} to rotate instances freely</li>"
|
||||||
"<li>Use secondary edit to rotate instances within the grid</li>"
|
"<li>Use {scene-edit-secondary} to rotate instances within the grid</li>"
|
||||||
"</ul>"
|
"</ul>"
|
||||||
"<font color=Red>Not implemented yet</font color>");
|
"<font color=Red>Not implemented yet</font color>");
|
||||||
mSubMode->addButton (":placeholder", "scale",
|
mSubMode->addButton (":placeholder", "scale",
|
||||||
"Scale selected instances"
|
"Scale selected instances"
|
||||||
"<ul><li>Use primary edit to scale instances freely</li>"
|
"<ul><li>Use {scene-edit-primary} to scale instances freely</li>"
|
||||||
"<li>Use secondary edit to scale instances along the grid</li>"
|
"<li>Use {scene-edit-secondary} to scale instances along the grid</li>"
|
||||||
"</ul>"
|
"</ul>"
|
||||||
"<font color=Red>Not implemented yet</font color>");
|
"<font color=Red>Not implemented yet</font color>");
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
CSVRender::InstanceMoveMode::InstanceMoveMode (QWidget *parent)
|
CSVRender::InstanceMoveMode::InstanceMoveMode (QWidget *parent)
|
||||||
: ModeButton (QIcon (QPixmap (":placeholder")),
|
: ModeButton (QIcon (QPixmap (":placeholder")),
|
||||||
"Move selected instances"
|
"Move selected instances"
|
||||||
"<ul><li>Use primary edit to move instances around freely</li>"
|
"<ul><li>Use {scene-edit-primary} to move instances around freely</li>"
|
||||||
"<li>Use secondary edit to move instances around within the grid</li>"
|
"<li>Use {scene-edit-secondary} to move instances around within the grid</li>"
|
||||||
"</ul>"
|
"</ul>"
|
||||||
"<font color=Red>Grid move not implemented yet</font color>",
|
"<font color=Red>Grid move not implemented yet</font color>",
|
||||||
parent)
|
parent)
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
|
||||||
|
#include "../../model/prefs/shortcut.hpp"
|
||||||
|
#include "../../model/prefs/shortcuteventhandler.hpp"
|
||||||
|
|
||||||
#include "worldspacewidget.hpp"
|
#include "worldspacewidget.hpp"
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
|
@ -11,13 +14,29 @@ namespace CSVRender
|
||||||
: ModeButton(icon, tooltip, parent)
|
: ModeButton(icon, tooltip, parent)
|
||||||
, mWorldspaceWidget(worldspaceWidget)
|
, mWorldspaceWidget(worldspaceWidget)
|
||||||
, mCenterOnSelection(0)
|
, mCenterOnSelection(0)
|
||||||
|
{
|
||||||
|
mCenterShortcut.reset(new CSMPrefs::Shortcut("orbit-center-selection", worldspaceWidget));
|
||||||
|
mCenterShortcut->enable(false);
|
||||||
|
connect(mCenterShortcut.get(), SIGNAL(activated()), this, SLOT(centerSelection()));
|
||||||
|
}
|
||||||
|
|
||||||
|
OrbitCameraMode::~OrbitCameraMode()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void OrbitCameraMode::activate(CSVWidget::SceneToolbar* toolbar)
|
void OrbitCameraMode::activate(CSVWidget::SceneToolbar* toolbar)
|
||||||
{
|
{
|
||||||
mCenterOnSelection = new QAction("Center on selected object", this);
|
mCenterOnSelection = new QAction("Center on selected object", this);
|
||||||
|
mCenterShortcut->associateAction(mCenterOnSelection);
|
||||||
connect(mCenterOnSelection, SIGNAL(triggered()), this, SLOT(centerSelection()));
|
connect(mCenterOnSelection, SIGNAL(triggered()), this, SLOT(centerSelection()));
|
||||||
|
|
||||||
|
mCenterShortcut->enable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrbitCameraMode::deactivate(CSVWidget::SceneToolbar* toolbar)
|
||||||
|
{
|
||||||
|
mCenterShortcut->associateAction(0);
|
||||||
|
mCenterShortcut->enable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OrbitCameraMode::createContextMenu(QMenu* menu)
|
bool OrbitCameraMode::createContextMenu(QMenu* menu)
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
#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
|
||||||
|
{
|
||||||
|
class Shortcut;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
{
|
{
|
||||||
class WorldspaceWidget;
|
class WorldspaceWidget;
|
||||||
|
@ -15,14 +22,17 @@ namespace CSVRender
|
||||||
|
|
||||||
OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip = "",
|
OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip = "",
|
||||||
QWidget* parent = 0);
|
QWidget* parent = 0);
|
||||||
|
~OrbitCameraMode();
|
||||||
|
|
||||||
virtual void activate(CSVWidget::SceneToolbar* toolbar);
|
virtual void activate(CSVWidget::SceneToolbar* toolbar);
|
||||||
|
virtual void deactivate(CSVWidget::SceneToolbar* toolbar);
|
||||||
virtual bool createContextMenu(QMenu* menu);
|
virtual bool createContextMenu(QMenu* menu);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
WorldspaceWidget* mWorldspaceWidget;
|
WorldspaceWidget* mWorldspaceWidget;
|
||||||
QAction* mCenterOnSelection;
|
QAction* mCenterOnSelection;
|
||||||
|
std::auto_ptr<CSMPrefs::Shortcut> mCenterShortcut;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#include <components/esm/loadland.hpp>
|
#include <components/esm/loadland.hpp>
|
||||||
|
|
||||||
|
#include "../../model/prefs/shortcut.hpp"
|
||||||
|
|
||||||
#include "../../model/world/tablemimedata.hpp"
|
#include "../../model/world/tablemimedata.hpp"
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
|
@ -142,75 +144,71 @@ void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
|
||||||
"terrain-move");
|
"terrain-move");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::PagedWorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, const std::string& button,
|
void CSVRender::PagedWorldspaceWidget::handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type)
|
||||||
bool shift)
|
|
||||||
{
|
{
|
||||||
if (hit.tag && hit.tag->getMask()==Mask_CellArrow)
|
if (hit.tag && hit.tag->getMask()==Mask_CellArrow)
|
||||||
{
|
{
|
||||||
if (button=="p-edit" || button=="s-edit")
|
if (CellArrowTag *cellArrowTag = dynamic_cast<CSVRender::CellArrowTag *> (hit.tag.get()))
|
||||||
{
|
{
|
||||||
if (CellArrowTag *cellArrowTag =
|
CellArrow *arrow = cellArrowTag->getCellArrow();
|
||||||
dynamic_cast<CSVRender::CellArrowTag *> (hit.tag.get()))
|
|
||||||
|
CSMWorld::CellCoordinates coordinates = arrow->getCoordinates();
|
||||||
|
|
||||||
|
CellArrow::Direction direction = arrow->getDirection();
|
||||||
|
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
|
||||||
|
switch (direction)
|
||||||
{
|
{
|
||||||
CellArrow *arrow = cellArrowTag->getCellArrow();
|
case CellArrow::Direction_North: y = 1; break;
|
||||||
|
case CellArrow::Direction_West: x = -1; break;
|
||||||
|
case CellArrow::Direction_South: y = -1; break;
|
||||||
|
case CellArrow::Direction_East: x = 1; break;
|
||||||
|
}
|
||||||
|
|
||||||
CSMWorld::CellCoordinates coordinates = arrow->getCoordinates();
|
bool modified = false;
|
||||||
|
|
||||||
CellArrow::Direction direction = arrow->getDirection();
|
if (type == InteractionType_PrimarySelect)
|
||||||
|
{
|
||||||
|
addCellSelection (x, y);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
else if (type == InteractionType_SecondarySelect)
|
||||||
|
{
|
||||||
|
moveCellSelection (x, y);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
else // Primary/SecondaryEdit
|
||||||
|
{
|
||||||
|
CSMWorld::CellCoordinates newCoordinates = coordinates.move (x, y);
|
||||||
|
|
||||||
int x = 0;
|
if (mCells.find (newCoordinates)==mCells.end())
|
||||||
int y = 0;
|
|
||||||
|
|
||||||
switch (direction)
|
|
||||||
{
|
{
|
||||||
case CellArrow::Direction_North: y = 1; break;
|
addCellToScene (newCoordinates);
|
||||||
case CellArrow::Direction_West: x = -1; break;
|
mSelection.add (newCoordinates);
|
||||||
case CellArrow::Direction_South: y = -1; break;
|
|
||||||
case CellArrow::Direction_East: x = 1; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool modified = false;
|
|
||||||
|
|
||||||
if (shift)
|
|
||||||
{
|
|
||||||
if (button=="p-edit")
|
|
||||||
addCellSelection (x, y);
|
|
||||||
else
|
|
||||||
moveCellSelection (x, y);
|
|
||||||
|
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
CSMWorld::CellCoordinates newCoordinates = coordinates.move (x, y);
|
|
||||||
|
|
||||||
if (mCells.find (newCoordinates)==mCells.end())
|
if (type == InteractionType_SecondaryEdit)
|
||||||
|
{
|
||||||
|
if (mCells.find (coordinates)!=mCells.end())
|
||||||
{
|
{
|
||||||
addCellToScene (newCoordinates);
|
removeCellFromScene (coordinates);
|
||||||
mSelection.add (newCoordinates);
|
mSelection.remove (coordinates);
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (button=="s-edit")
|
|
||||||
{
|
|
||||||
if (mCells.find (coordinates)!=mCells.end())
|
|
||||||
{
|
|
||||||
removeCellFromScene (coordinates);
|
|
||||||
mSelection.remove (coordinates);
|
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modified)
|
|
||||||
adjustCells();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (modified)
|
||||||
|
adjustCells();
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldspaceWidget::handleMouseClick (hit, button, shift);
|
WorldspaceWidget::handleInteractionPress (hit, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
|
void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
@ -437,6 +435,27 @@ void CSVRender::PagedWorldspaceWidget::moveCellSelection (int x, int y)
|
||||||
mSelection = newSelection;
|
mSelection = newSelection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::addCellToSceneFromCamera (int offsetX, int offsetY)
|
||||||
|
{
|
||||||
|
const int CellSize = 8192;
|
||||||
|
|
||||||
|
osg::Vec3f eye, center, up;
|
||||||
|
getCamera()->getViewMatrixAsLookAt(eye, center, up);
|
||||||
|
|
||||||
|
int cellX = (int)std::floor(center.x() / CellSize) + offsetX;
|
||||||
|
int cellY = (int)std::floor(center.y() / CellSize) + offsetY;
|
||||||
|
|
||||||
|
CSMWorld::CellCoordinates cellCoordinates(cellX, cellY);
|
||||||
|
|
||||||
|
if (!mSelection.has(cellCoordinates))
|
||||||
|
{
|
||||||
|
addCellToScene(cellCoordinates);
|
||||||
|
mSelection.add(cellCoordinates);
|
||||||
|
|
||||||
|
adjustCells();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document)
|
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document)
|
||||||
: WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default"),
|
: WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default"),
|
||||||
mControlElements(NULL), mDisplayCellCoord(true)
|
mControlElements(NULL), mDisplayCellCoord(true)
|
||||||
|
@ -450,6 +469,22 @@ CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc
|
||||||
this, SLOT (cellRemoved (const QModelIndex&, int, int)));
|
this, SLOT (cellRemoved (const QModelIndex&, int, int)));
|
||||||
connect (cells, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
connect (cells, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||||
this, SLOT (cellAdded (const QModelIndex&, int, int)));
|
this, SLOT (cellAdded (const QModelIndex&, int, int)));
|
||||||
|
|
||||||
|
// Shortcuts
|
||||||
|
CSMPrefs::Shortcut* loadCameraCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-cell", this);
|
||||||
|
connect(loadCameraCellShortcut, SIGNAL(activated()), this, SLOT(loadCameraCell()));
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* loadCameraEastCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-eastcell", this);
|
||||||
|
connect(loadCameraEastCellShortcut, SIGNAL(activated()), this, SLOT(loadEastCell()));
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* loadCameraNorthCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-northcell", this);
|
||||||
|
connect(loadCameraNorthCellShortcut, SIGNAL(activated()), this, SLOT(loadNorthCell()));
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* loadCameraWestCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-westcell", this);
|
||||||
|
connect(loadCameraWestCellShortcut, SIGNAL(activated()), this, SLOT(loadWestCell()));
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* loadCameraSouthCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-southcell", this);
|
||||||
|
connect(loadCameraSouthCellShortcut, SIGNAL(activated()), this, SLOT(loadSouthCell()));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget()
|
CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget()
|
||||||
|
@ -722,3 +757,28 @@ void CSVRender::PagedWorldspaceWidget::cellAdded (const QModelIndex& index, int
|
||||||
if (adjustCells())
|
if (adjustCells())
|
||||||
flagAsModified();
|
flagAsModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::loadCameraCell()
|
||||||
|
{
|
||||||
|
addCellToSceneFromCamera(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::loadEastCell()
|
||||||
|
{
|
||||||
|
addCellToSceneFromCamera(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::loadNorthCell()
|
||||||
|
{
|
||||||
|
addCellToSceneFromCamera(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::loadWestCell()
|
||||||
|
{
|
||||||
|
addCellToSceneFromCamera(-1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::loadSouthCell()
|
||||||
|
{
|
||||||
|
addCellToSceneFromCamera(0, -1);
|
||||||
|
}
|
||||||
|
|
|
@ -74,6 +74,8 @@ namespace CSVRender
|
||||||
/// \note Does not update the view or any cell marker
|
/// \note Does not update the view or any cell marker
|
||||||
void moveCellSelection (int x, int y);
|
void moveCellSelection (int x, int y);
|
||||||
|
|
||||||
|
void addCellToSceneFromCamera (int offsetX, int offsetY);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document);
|
PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document);
|
||||||
|
@ -138,7 +140,7 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);
|
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);
|
||||||
|
|
||||||
virtual void handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, bool shift);
|
virtual void handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
@ -152,6 +154,16 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual void cellAdded (const QModelIndex& index, int start, int end);
|
virtual void cellAdded (const QModelIndex& index, int start, int end);
|
||||||
|
|
||||||
|
void loadCameraCell();
|
||||||
|
|
||||||
|
void loadEastCell();
|
||||||
|
|
||||||
|
void loadNorthCell();
|
||||||
|
|
||||||
|
void loadWestCell();
|
||||||
|
|
||||||
|
void loadSouthCell();
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,10 @@ namespace CSVRender
|
||||||
{
|
{
|
||||||
return QString(
|
return QString(
|
||||||
"Pathgrid editing"
|
"Pathgrid editing"
|
||||||
"<ul><li>Primary edit: Add node to scene</li>"
|
"<ul><li>Press {scene-edit-primary} to add a node to the cursor location</li>"
|
||||||
"<li>Secondary edit: Connect selected nodes to node</li>"
|
"<li>Press {scene-edit-secondary} to connect the selected nodes to the node beneath the cursor</li>"
|
||||||
"<li>Primary drag: Move selected nodes</li>"
|
"<li>Press {scene-edit-primary} and drag to move selected nodes</li>"
|
||||||
"<li>Secondary drag: Connect one node to another</li>"
|
"<li>Press {scene-edit-secondary} and drag to connect one node to another</li>"
|
||||||
"</ul><p>Note: Only a single cell's pathgrid may be edited at a time");
|
"</ul><p>Note: Only a single cell's pathgrid may be edited at a time");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,16 @@ namespace CSVRender
|
||||||
toolbar->addTool(mSelectionMode);
|
toolbar->addTool(mSelectionMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PathgridMode::deactivate(CSVWidget::SceneToolbar* toolbar)
|
||||||
|
{
|
||||||
|
if (mSelectionMode)
|
||||||
|
{
|
||||||
|
toolbar->removeTool (mSelectionMode);
|
||||||
|
delete mSelectionMode;
|
||||||
|
mSelectionMode = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PathgridMode::primaryEditPressed(const WorldspaceHitResult& hitResult)
|
void PathgridMode::primaryEditPressed(const WorldspaceHitResult& hitResult)
|
||||||
{
|
{
|
||||||
if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue() &&
|
if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue() &&
|
||||||
|
|
|
@ -19,6 +19,8 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual void activate(CSVWidget::SceneToolbar* toolbar);
|
virtual void activate(CSVWidget::SceneToolbar* toolbar);
|
||||||
|
|
||||||
|
virtual void deactivate(CSVWidget::SceneToolbar* toolbar);
|
||||||
|
|
||||||
virtual void primaryEditPressed(const WorldspaceHitResult& hit);
|
virtual void primaryEditPressed(const WorldspaceHitResult& hit);
|
||||||
|
|
||||||
virtual void secondaryEditPressed(const WorldspaceHitResult& hit);
|
virtual void secondaryEditPressed(const WorldspaceHitResult& hit);
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QResizeEvent>
|
#include <QResizeEvent>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QShortcut>
|
|
||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
|
|
||||||
#include <extern/osgQt/GraphicsWindowQt>
|
#include <extern/osgQt/GraphicsWindowQt>
|
||||||
|
@ -19,6 +18,8 @@
|
||||||
#include "../widget/scenetoolmode.hpp"
|
#include "../widget/scenetoolmode.hpp"
|
||||||
|
|
||||||
#include "../../model/prefs/state.hpp"
|
#include "../../model/prefs/state.hpp"
|
||||||
|
#include "../../model/prefs/shortcut.hpp"
|
||||||
|
#include "../../model/prefs/shortcuteventhandler.hpp"
|
||||||
|
|
||||||
#include "lighting.hpp"
|
#include "lighting.hpp"
|
||||||
#include "mask.hpp"
|
#include "mask.hpp"
|
||||||
|
@ -75,7 +76,7 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
|
||||||
|
|
||||||
mView->setSceneData(mRootNode);
|
mView->setSceneData(mRootNode);
|
||||||
|
|
||||||
// Press S to reveal profiling stats
|
// Add ability to signal osg to show its statistics for debugging purposes
|
||||||
mView->addEventHandler(new osgViewer::StatsHandler);
|
mView->addEventHandler(new osgViewer::StatsHandler);
|
||||||
|
|
||||||
mView->getCamera()->setCullMask(~(Mask_UpdateVisitor));
|
mView->getCamera()->setCullMask(~(Mask_UpdateVisitor));
|
||||||
|
@ -105,6 +106,15 @@ osg::Camera *RenderWidget::getCamera()
|
||||||
return mView->getCamera();
|
return mView->getCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderWidget::toggleRenderStats()
|
||||||
|
{
|
||||||
|
osgViewer::GraphicsWindow* window =
|
||||||
|
static_cast<osgViewer::GraphicsWindow*>(mView->getCamera()->getGraphicsContext());
|
||||||
|
|
||||||
|
window->getEventQueue()->keyPress(osgGA::GUIEventAdapter::KEY_S);
|
||||||
|
window->getEventQueue()->keyRelease(osgGA::GUIEventAdapter::KEY_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
@ -158,13 +168,13 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
|
||||||
, mHasDefaultAmbient(false)
|
, mHasDefaultAmbient(false)
|
||||||
, mPrevMouseX(0)
|
, mPrevMouseX(0)
|
||||||
, mPrevMouseY(0)
|
, mPrevMouseY(0)
|
||||||
, mFreeCamControl(new FreeCameraController())
|
|
||||||
, mOrbitCamControl(new OrbitCameraController())
|
|
||||||
, mCurrentCamControl(mFreeCamControl.get())
|
|
||||||
, mCamPositionSet(false)
|
, mCamPositionSet(false)
|
||||||
{
|
{
|
||||||
|
mFreeCamControl = new FreeCameraController(this);
|
||||||
|
mOrbitCamControl = new OrbitCameraController(this);
|
||||||
|
mCurrentCamControl = mFreeCamControl;
|
||||||
|
|
||||||
mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain);
|
mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain);
|
||||||
selectNavigationMode("free");
|
|
||||||
|
|
||||||
// we handle lighting manually
|
// we handle lighting manually
|
||||||
mView->setLightingMode(osgViewer::View::NO_LIGHT);
|
mView->setLightingMode(osgViewer::View::NO_LIGHT);
|
||||||
|
@ -175,11 +185,7 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
|
||||||
|
|
||||||
// Recieve mouse move event even if mouse button is not pressed
|
// Recieve mouse move event even if mouse button is not pressed
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
setFocusPolicy(Qt::StrongFocus);
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
|
|
||||||
/// \todo make shortcut configurable
|
|
||||||
QShortcut *focusToolbar = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut);
|
|
||||||
connect (focusToolbar, SIGNAL (activated()), this, SIGNAL (focusToolbarRequest()));
|
|
||||||
|
|
||||||
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
|
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
|
||||||
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
|
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
|
||||||
|
@ -192,6 +198,13 @@ SceneWidget::SceneWidget(boost::shared_ptr<Resource::ResourceSystem> resourceSys
|
||||||
}
|
}
|
||||||
|
|
||||||
connect (&CompositeViewer::get(), SIGNAL (simulationUpdated(double)), this, SLOT (update(double)));
|
connect (&CompositeViewer::get(), SIGNAL (simulationUpdated(double)), this, SLOT (update(double)));
|
||||||
|
|
||||||
|
// Shortcuts
|
||||||
|
CSMPrefs::Shortcut* focusToolbarShortcut = new CSMPrefs::Shortcut("scene-focus-toolbar", this);
|
||||||
|
connect(focusToolbarShortcut, SIGNAL(activated()), this, SIGNAL(focusToolbarRequest()));
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* renderStatsShortcut = new CSMPrefs::Shortcut("scene-render-stats", this);
|
||||||
|
connect(renderStatsShortcut, SIGNAL(activated()), this, SLOT(toggleRenderStats()));
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneWidget::~SceneWidget()
|
SceneWidget::~SceneWidget()
|
||||||
|
@ -271,45 +284,17 @@ void SceneWidget::setDefaultAmbient (const osg::Vec4f& colour)
|
||||||
setAmbient(mLighting->getAmbientColour(&mDefaultAmbient));
|
setAmbient(mLighting->getAmbientColour(&mDefaultAmbient));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneWidget::mousePressEvent (QMouseEvent *event)
|
|
||||||
{
|
|
||||||
mMouseMode = mapButton(event);
|
|
||||||
|
|
||||||
mPrevMouseX = event->x();
|
|
||||||
mPrevMouseY = event->y();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneWidget::mouseReleaseEvent (QMouseEvent *event)
|
|
||||||
{
|
|
||||||
mMouseMode = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneWidget::mouseMoveEvent (QMouseEvent *event)
|
void SceneWidget::mouseMoveEvent (QMouseEvent *event)
|
||||||
{
|
{
|
||||||
mCurrentCamControl->handleMouseMoveEvent(mMouseMode, event->x() - mPrevMouseX, event->y() - mPrevMouseY);
|
mCurrentCamControl->handleMouseMoveEvent(event->x() - mPrevMouseX, event->y() - mPrevMouseY);
|
||||||
|
|
||||||
mPrevMouseX = event->x();
|
mPrevMouseX = event->x();
|
||||||
mPrevMouseY = event->y();
|
mPrevMouseY = event->y();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneWidget::focusOutEvent (QFocusEvent *event)
|
|
||||||
{
|
|
||||||
mCurrentCamControl->resetInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneWidget::wheelEvent(QWheelEvent *event)
|
void SceneWidget::wheelEvent(QWheelEvent *event)
|
||||||
{
|
{
|
||||||
mCurrentCamControl->handleMouseMoveEvent("t-navi", event->delta(), 0);
|
mCurrentCamControl->handleMouseScrollEvent(event->delta());
|
||||||
}
|
|
||||||
|
|
||||||
void SceneWidget::keyPressEvent (QKeyEvent *event)
|
|
||||||
{
|
|
||||||
mCurrentCamControl->handleKeyEvent(event, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneWidget::keyReleaseEvent (QKeyEvent *event)
|
|
||||||
{
|
|
||||||
mCurrentCamControl->handleKeyEvent(event, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneWidget::update(double dt)
|
void SceneWidget::update(double dt)
|
||||||
|
@ -373,10 +358,6 @@ void SceneWidget::settingChanged (const CSMPrefs::Setting *setting)
|
||||||
{
|
{
|
||||||
mOrbitCamControl->setOrbitSpeedMultiplier(setting->toDouble());
|
mOrbitCamControl->setOrbitSpeedMultiplier(setting->toDouble());
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
storeMappingSetting(setting);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneWidget::selectNavigationMode (const std::string& mode)
|
void SceneWidget::selectNavigationMode (const std::string& mode)
|
||||||
|
@ -384,73 +365,23 @@ void SceneWidget::selectNavigationMode (const std::string& mode)
|
||||||
if (mode=="1st")
|
if (mode=="1st")
|
||||||
{
|
{
|
||||||
mCurrentCamControl->setCamera(NULL);
|
mCurrentCamControl->setCamera(NULL);
|
||||||
mCurrentCamControl = mFreeCamControl.get();
|
mCurrentCamControl = mFreeCamControl;
|
||||||
mCurrentCamControl->setCamera(getCamera());
|
mFreeCamControl->setCamera(getCamera());
|
||||||
mFreeCamControl->fixUpAxis(CameraController::WorldUp);
|
mFreeCamControl->fixUpAxis(CameraController::WorldUp);
|
||||||
}
|
}
|
||||||
else if (mode=="free")
|
else if (mode=="free")
|
||||||
{
|
{
|
||||||
mCurrentCamControl->setCamera(NULL);
|
mCurrentCamControl->setCamera(NULL);
|
||||||
mCurrentCamControl = mFreeCamControl.get();
|
mCurrentCamControl = mFreeCamControl;
|
||||||
mCurrentCamControl->setCamera(getCamera());
|
mFreeCamControl->setCamera(getCamera());
|
||||||
mFreeCamControl->unfixUpAxis();
|
mFreeCamControl->unfixUpAxis();
|
||||||
}
|
}
|
||||||
else if (mode=="orbit")
|
else if (mode=="orbit")
|
||||||
{
|
{
|
||||||
mCurrentCamControl->setCamera(NULL);
|
mCurrentCamControl->setCamera(NULL);
|
||||||
mCurrentCamControl = mOrbitCamControl.get();
|
mCurrentCamControl = mOrbitCamControl;
|
||||||
mCurrentCamControl->setCamera(getCamera());
|
mOrbitCamControl->setCamera(getCamera());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SceneWidget::storeMappingSetting (const CSMPrefs::Setting *setting)
|
|
||||||
{
|
|
||||||
if (setting->getParent()->getKey()!="3D Scene Input")
|
|
||||||
return false;
|
|
||||||
|
|
||||||
static const char * const sMappingSettings[] =
|
|
||||||
{
|
|
||||||
"p-navi", "s-navi",
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i=0; sMappingSettings[i]; ++i)
|
|
||||||
if (setting->getKey()==sMappingSettings[i])
|
|
||||||
{
|
|
||||||
QString value = QString::fromUtf8 (setting->toString().c_str());
|
|
||||||
|
|
||||||
Qt::MouseButton button = Qt::NoButton;
|
|
||||||
|
|
||||||
if (value.endsWith ("Left Mouse-Button"))
|
|
||||||
button = Qt::LeftButton;
|
|
||||||
else if (value.endsWith ("Right Mouse-Button"))
|
|
||||||
button = Qt::RightButton;
|
|
||||||
else if (value.endsWith ("Middle Mouse-Button"))
|
|
||||||
button = Qt::MiddleButton;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool ctrl = value.startsWith ("Ctrl-");
|
|
||||||
|
|
||||||
mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string SceneWidget::mapButton (QMouseEvent *event)
|
|
||||||
{
|
|
||||||
std::pair<Qt::MouseButton, bool> phyiscal (
|
|
||||||
event->button(), event->modifiers() & Qt::ControlModifier);
|
|
||||||
|
|
||||||
std::map<std::pair<Qt::MouseButton, bool>, std::string>::const_iterator iter =
|
|
||||||
mButtonMapping.find (phyiscal);
|
|
||||||
|
|
||||||
if (iter!=mButtonMapping.end())
|
|
||||||
return iter->second;
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,15 @@
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <osgViewer/View>
|
||||||
|
#include <osgViewer/CompositeViewer>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include "lightingday.hpp"
|
#include "lightingday.hpp"
|
||||||
#include "lightingnight.hpp"
|
#include "lightingnight.hpp"
|
||||||
#include "lightingbright.hpp"
|
#include "lightingbright.hpp"
|
||||||
|
|
||||||
#include <osgViewer/View>
|
|
||||||
#include <osgViewer/CompositeViewer>
|
|
||||||
|
|
||||||
namespace Resource
|
namespace Resource
|
||||||
{
|
{
|
||||||
|
@ -53,6 +54,7 @@ namespace CSVRender
|
||||||
RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
|
RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
|
||||||
virtual ~RenderWidget();
|
virtual ~RenderWidget();
|
||||||
|
|
||||||
|
/// Initiates a request to redraw the view
|
||||||
void flagAsModified();
|
void flagAsModified();
|
||||||
|
|
||||||
void setVisibilityMask(int mask);
|
void setVisibilityMask(int mask);
|
||||||
|
@ -62,13 +64,16 @@ namespace CSVRender
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
osg::ref_ptr<osgViewer::View> mView;
|
osg::ref_ptr<osgViewer::View> mView;
|
||||||
|
osg::ref_ptr<osg::Group> mRootNode;
|
||||||
osg::Group* mRootNode;
|
|
||||||
|
|
||||||
QTimer mTimer;
|
QTimer mTimer;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
|
||||||
|
void toggleRenderStats();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extension of RenderWidget to support lighting mode selection & toolbar
|
/// Extension of RenderWidget to support lighting mode selection & toolbar
|
||||||
class SceneWidget : public RenderWidget
|
class SceneWidget : public RenderWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -90,18 +95,8 @@ namespace CSVRender
|
||||||
|
|
||||||
void setAmbient(const osg::Vec4f& ambient);
|
void setAmbient(const osg::Vec4f& ambient);
|
||||||
|
|
||||||
virtual void mousePressEvent (QMouseEvent *event);
|
|
||||||
virtual void mouseReleaseEvent (QMouseEvent *event);
|
|
||||||
virtual void mouseMoveEvent (QMouseEvent *event);
|
virtual void mouseMoveEvent (QMouseEvent *event);
|
||||||
virtual void wheelEvent (QWheelEvent *event);
|
virtual void wheelEvent (QWheelEvent *event);
|
||||||
virtual void keyPressEvent (QKeyEvent *event);
|
|
||||||
virtual void keyReleaseEvent (QKeyEvent *event);
|
|
||||||
virtual void focusOutEvent (QFocusEvent *event);
|
|
||||||
|
|
||||||
/// \return Is \a key a button mapping setting? (ignored otherwise)
|
|
||||||
virtual bool storeMappingSetting (const CSMPrefs::Setting *setting);
|
|
||||||
|
|
||||||
std::string mapButton (QMouseEvent *event);
|
|
||||||
|
|
||||||
boost::shared_ptr<Resource::ResourceSystem> mResourceSystem;
|
boost::shared_ptr<Resource::ResourceSystem> mResourceSystem;
|
||||||
|
|
||||||
|
@ -114,12 +109,10 @@ namespace CSVRender
|
||||||
LightingBright mLightingBright;
|
LightingBright mLightingBright;
|
||||||
|
|
||||||
int mPrevMouseX, mPrevMouseY;
|
int mPrevMouseX, mPrevMouseY;
|
||||||
std::string mMouseMode;
|
|
||||||
std::auto_ptr<FreeCameraController> mFreeCamControl;
|
|
||||||
std::auto_ptr<OrbitCameraController> mOrbitCamControl;
|
|
||||||
CameraController* mCurrentCamControl;
|
|
||||||
|
|
||||||
std::map<std::pair<Qt::MouseButton, bool>, std::string> mButtonMapping;
|
FreeCameraController* mFreeCamControl;
|
||||||
|
OrbitCameraController* mOrbitCamControl;
|
||||||
|
CameraController* mCurrentCamControl;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mCamPositionSet;
|
bool mCamPositionSet;
|
||||||
|
|
|
@ -15,22 +15,28 @@ namespace CSVRender
|
||||||
{
|
{
|
||||||
addButton(":placeholder", "cube-centre",
|
addButton(":placeholder", "cube-centre",
|
||||||
"Centred cube"
|
"Centred cube"
|
||||||
"<ul><li>Drag with primary (make instances the selection) or secondary (invert selection state) select button from the centre of the selection cube outwards</li>"
|
"<ul><li>Drag with {scene-select-primary} (make instances the selection) or {scene-select-secondary} "
|
||||||
|
"(invert selection state) from the centre of the selection cube outwards</li>"
|
||||||
"<li>The selection cube is aligned to the word space axis</li>"
|
"<li>The selection cube is aligned to the word space axis</li>"
|
||||||
"<li>If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect</li>"
|
"<li>If context selection mode is enabled, a drag with {scene-edit-primary} or {scene-edit-secondary} not "
|
||||||
|
"starting on an instance will have the same effect</li>"
|
||||||
"</ul>"
|
"</ul>"
|
||||||
"<font color=Red>Not implemented yet</font color>");
|
"<font color=Red>Not implemented yet</font color>");
|
||||||
addButton(":placeholder", "cube-corner",
|
addButton(":placeholder", "cube-corner",
|
||||||
"Cube corner to corner"
|
"Cube corner to corner"
|
||||||
"<ul><li>Drag with primary (make instances the selection) or secondary (invert selection state) select button from one corner of the selection cube to the opposite corner</li>"
|
"<ul><li>Drag with {scene-select-primary} (make instances the selection) or {scene-select-secondary} "
|
||||||
|
"(invert selection state) from one corner of the selection cube to the opposite corner</li>"
|
||||||
"<li>The selection cube is aligned to the word space axis</li>"
|
"<li>The selection cube is aligned to the word space axis</li>"
|
||||||
"<li>If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect</li>"
|
"<li>If context selection mode is enabled, a drag with {scene-edit-primary} or {scene-edit-secondary} not "
|
||||||
|
"starting on an instance will have the same effect</li>"
|
||||||
"</ul>"
|
"</ul>"
|
||||||
"<font color=Red>Not implemented yet</font color>");
|
"<font color=Red>Not implemented yet</font color>");
|
||||||
addButton(":placeholder", "sphere",
|
addButton(":placeholder", "sphere",
|
||||||
"Centred sphere"
|
"Centred sphere"
|
||||||
"<ul><li>Drag with primary (make instances the selection) or secondary (invert selection state) select button from the centre of the selection sphere outwards</li>"
|
"<ul><li>Drag with {scene-select-primary} (make instances the selection) or {scene-select-secondary} "
|
||||||
"<li>If context selection mode is enabled, a drag with primary/secondary edit not starting on an instance will have the same effect</li>"
|
"(invert selection state) from the centre of the selection sphere outwards</li>"
|
||||||
|
"<li>If context selection mode is enabled, a drag with {scene-edit-primary} or {scene-edit-secondary} not "
|
||||||
|
"starting on an instance will have the same effect</li>"
|
||||||
"</ul>"
|
"</ul>"
|
||||||
"<font color=Red>Not implemented yet</font color>");
|
"<font color=Red>Not implemented yet</font color>");
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#include "../../model/world/universalid.hpp"
|
#include "../../model/world/universalid.hpp"
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
|
#include "../../model/prefs/shortcut.hpp"
|
||||||
|
#include "../../model/prefs/shortcuteventhandler.hpp"
|
||||||
#include "../../model/prefs/state.hpp"
|
#include "../../model/prefs/state.hpp"
|
||||||
|
|
||||||
#include "../render/orbitcameramode.hpp"
|
#include "../render/orbitcameramode.hpp"
|
||||||
|
@ -31,10 +33,24 @@
|
||||||
#include "cameracontroller.hpp"
|
#include "cameracontroller.hpp"
|
||||||
|
|
||||||
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
|
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
|
||||||
: SceneWidget (document.getData().getResourceSystem(), parent, 0, false), mSceneElements(0), mRun(0), mDocument(document),
|
: SceneWidget (document.getData().getResourceSystem(), parent, 0, false)
|
||||||
mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false), mDragX(0), mDragY(0), mDragFactor(0),
|
, mSceneElements(0)
|
||||||
mDragWheelFactor(0), mDragShiftFactor(0),
|
, mRun(0)
|
||||||
mToolTipPos (-1, -1), mShowToolTips(false), mToolTipDelay(0)
|
, mDocument(document)
|
||||||
|
, mInteractionMask (0)
|
||||||
|
, mEditMode (0)
|
||||||
|
, mLocked (false)
|
||||||
|
, mDragMode(InteractionType_None)
|
||||||
|
, mDragging (false)
|
||||||
|
, mDragX(0)
|
||||||
|
, mDragY(0)
|
||||||
|
, mSpeedMode(false)
|
||||||
|
, mDragFactor(0)
|
||||||
|
, mDragWheelFactor(0)
|
||||||
|
, mDragShiftFactor(0)
|
||||||
|
, mToolTipPos (-1, -1)
|
||||||
|
, mShowToolTips(false)
|
||||||
|
, mToolTipDelay(0)
|
||||||
{
|
{
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
|
|
||||||
|
@ -80,6 +96,24 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg
|
||||||
|
|
||||||
CSMPrefs::get()["3D Scene Input"].update();
|
CSMPrefs::get()["3D Scene Input"].update();
|
||||||
CSMPrefs::get()["Tooltips"].update();
|
CSMPrefs::get()["Tooltips"].update();
|
||||||
|
|
||||||
|
// Shortcuts
|
||||||
|
CSMPrefs::Shortcut* primaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-primary", "scene-speed-modifier",
|
||||||
|
CSMPrefs::Shortcut::SM_Detach, this);
|
||||||
|
connect(primaryEditShortcut, SIGNAL(activated(bool)), this, SLOT(primaryEdit(bool)));
|
||||||
|
connect(primaryEditShortcut, SIGNAL(secondary(bool)), this, SLOT(speedMode(bool)));
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* secondaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-secondary", this);
|
||||||
|
connect(secondaryEditShortcut, SIGNAL(activated(bool)), this, SLOT(secondaryEdit(bool)));
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* primarySelectShortcut = new CSMPrefs::Shortcut("scene-select-primary", this);
|
||||||
|
connect(primarySelectShortcut, SIGNAL(activated(bool)), this, SLOT(primarySelect(bool)));
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* secondarySelectShortcut = new CSMPrefs::Shortcut("scene-select-secondary", this);
|
||||||
|
connect(secondarySelectShortcut, SIGNAL(activated(bool)), this, SLOT(secondarySelect(bool)));
|
||||||
|
|
||||||
|
CSMPrefs::Shortcut* abortShortcut = new CSMPrefs::Shortcut("scene-edit-abort", this);
|
||||||
|
connect(abortShortcut, SIGNAL(activated()), this, SLOT(abortDrag()));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVRender::WorldspaceWidget::~WorldspaceWidget ()
|
CSVRender::WorldspaceWidget::~WorldspaceWidget ()
|
||||||
|
@ -132,30 +166,32 @@ CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector (
|
||||||
/// \todo consider user-defined button-mapping
|
/// \todo consider user-defined button-mapping
|
||||||
tool->addButton (":scenetoolbar/1st-person", "1st",
|
tool->addButton (":scenetoolbar/1st-person", "1st",
|
||||||
"First Person"
|
"First Person"
|
||||||
"<ul><li>Mouse-Look while holding the left button</li>"
|
"<ul><li>Camera is held upright</li>"
|
||||||
"<li>WASD movement keys</li>"
|
"<li>Mouse-Look while holding {scene-navi-primary}</li>"
|
||||||
|
"<li>Movement keys: {free-forward}(forward), {free-left}(left), {free-backward}(back), {free-right}(right)</li>"
|
||||||
|
"<li>Strafing (also vertically) by holding {scene-navi-secondary}</li>"
|
||||||
"<li>Mouse wheel moves the camera forward/backward</li>"
|
"<li>Mouse wheel moves the camera forward/backward</li>"
|
||||||
"<li>Strafing (also vertically) by holding the left mouse button and control</li>"
|
"<li>Hold {scene-speed-modifier} to speed up movement</li>"
|
||||||
"<li>Camera is held upright</li>"
|
|
||||||
"<li>Hold shift to speed up movement</li>"
|
|
||||||
"</ul>");
|
"</ul>");
|
||||||
tool->addButton (":scenetoolbar/free-camera", "free",
|
tool->addButton (":scenetoolbar/free-camera", "free",
|
||||||
"Free Camera"
|
"Free Camera"
|
||||||
"<ul><li>Mouse-Look while holding the left button</li>"
|
"<ul><li>Mouse-Look while holding {scene-navi-primary}</li>"
|
||||||
"<li>Strafing (also vertically) via WASD or by holding the left mouse button and control</li>"
|
"<li>Movement keys: {free-forward}(forward), {free-left}(left), {free-backward}(back), {free-right}(right)</li>"
|
||||||
|
"<li>Roll camera with {free-roll-left} and {free-roll-right} keys</li>"
|
||||||
|
"<li>Strafing (also vertically) by holding {scene-navi-secondary}</li>"
|
||||||
"<li>Mouse wheel moves the camera forward/backward</li>"
|
"<li>Mouse wheel moves the camera forward/backward</li>"
|
||||||
"<li>Roll camera with Q and E keys</li>"
|
"<li>Hold {free-forward:mod} to speed up movement</li>"
|
||||||
"<li>Hold shift to speed up movement</li>"
|
|
||||||
"</ul>");
|
"</ul>");
|
||||||
tool->addButton(
|
tool->addButton(
|
||||||
new CSVRender::OrbitCameraMode(this, 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 {orbit-up}, {orbit-left}, {orbit-down}, {orbit-right} or by moving "
|
||||||
|
"the mouse while holding {scene-navi-primary}</li>"
|
||||||
|
"<li>Roll camera with {orbit-roll-left} and {orbit-roll-right} keys</li>"
|
||||||
|
"<li>Strafing (also vertically) by holding {scene-navi-secondary} (includes relocation of the centre point)</li>"
|
||||||
"<li>Mouse wheel moves camera away or towards centre point but can not pass through it</li>"
|
"<li>Mouse wheel moves camera away or towards centre point but can not pass through it</li>"
|
||||||
"<li>Roll camera with Q and E keys</li>"
|
"<li>Hold {scene-speed-modifier} to speed up movement</li>"
|
||||||
"<li>Strafing (also vertically) by holding the left mouse button and control (includes relocation of the centre point)</li>"
|
|
||||||
"<li>Hold shift to speed up movement</li>"
|
|
||||||
"</ul>", tool),
|
"</ul>", tool),
|
||||||
"orbit");
|
"orbit");
|
||||||
|
|
||||||
|
@ -409,7 +445,7 @@ void CSVRender::WorldspaceWidget::abortDrag()
|
||||||
|
|
||||||
editMode.dragAborted();
|
editMode.dragAborted();
|
||||||
mDragging = false;
|
mDragging = false;
|
||||||
mDragMode.clear();
|
mDragMode = InteractionType_None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,45 +489,6 @@ void CSVRender::WorldspaceWidget::dragMoveEvent(QDragMoveEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSVRender::WorldspaceWidget::storeMappingSetting (const CSMPrefs::Setting *setting)
|
|
||||||
{
|
|
||||||
static const char * const sMappingSettings[] =
|
|
||||||
{
|
|
||||||
"p-edit", "s-edit",
|
|
||||||
"p-select", "s-select",
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
if (setting->getParent()->getKey()=="3D Scene Input")
|
|
||||||
{
|
|
||||||
for (int i=0; sMappingSettings[i]; ++i)
|
|
||||||
{
|
|
||||||
if (setting->getKey()==sMappingSettings[i])
|
|
||||||
{
|
|
||||||
QString value = QString::fromUtf8 (setting->toString().c_str());
|
|
||||||
|
|
||||||
Qt::MouseButton button = Qt::NoButton;
|
|
||||||
|
|
||||||
if (value.endsWith ("Left Mouse-Button"))
|
|
||||||
button = Qt::LeftButton;
|
|
||||||
else if (value.endsWith ("Right Mouse-Button"))
|
|
||||||
button = Qt::RightButton;
|
|
||||||
else if (value.endsWith ("Middle Mouse-Button"))
|
|
||||||
button = Qt::MiddleButton;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool ctrl = value.startsWith ("Ctrl-");
|
|
||||||
|
|
||||||
mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return SceneWidget::storeMappingSetting(setting);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event)
|
void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event)
|
||||||
{
|
{
|
||||||
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
|
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
|
||||||
|
@ -567,7 +564,7 @@ void CSVRender::WorldspaceWidget::editModeChanged (const std::string& id)
|
||||||
{
|
{
|
||||||
dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).setEditLock (mLocked);
|
dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).setEditLock (mLocked);
|
||||||
mDragging = false;
|
mDragging = false;
|
||||||
mDragMode.clear();
|
mDragMode = InteractionType_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::showToolTip()
|
void CSVRender::WorldspaceWidget::showToolTip()
|
||||||
|
@ -608,24 +605,24 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
|
||||||
|
|
||||||
double factor = mDragFactor;
|
double factor = mDragFactor;
|
||||||
|
|
||||||
if (event->modifiers() & Qt::ShiftModifier)
|
if (mSpeedMode)
|
||||||
factor *= mDragShiftFactor;
|
factor *= mDragShiftFactor;
|
||||||
|
|
||||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||||
|
|
||||||
editMode.drag (event->pos(), diffX, diffY, factor);
|
editMode.drag (event->pos(), diffX, diffY, factor);
|
||||||
}
|
}
|
||||||
else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="p-select" || mDragMode=="s-select")
|
else if (mDragMode != InteractionType_None)
|
||||||
{
|
{
|
||||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||||
|
|
||||||
if (mDragMode=="p-edit")
|
if (mDragMode == InteractionType_PrimaryEdit)
|
||||||
mDragging = editMode.primaryEditStartDrag (event->pos());
|
mDragging = editMode.primaryEditStartDrag (event->pos());
|
||||||
else if (mDragMode=="s-edit")
|
else if (mDragMode == InteractionType_SecondaryEdit)
|
||||||
mDragging = editMode.secondaryEditStartDrag (event->pos());
|
mDragging = editMode.secondaryEditStartDrag (event->pos());
|
||||||
else if (mDragMode=="p-select")
|
else if (mDragMode == InteractionType_PrimarySelect)
|
||||||
mDragging = editMode.primarySelectStartDrag (event->pos());
|
mDragging = editMode.primarySelectStartDrag (event->pos());
|
||||||
else if (mDragMode=="s-select")
|
else if (mDragMode == InteractionType_SecondarySelect)
|
||||||
mDragging = editMode.secondarySelectStartDrag (event->pos());
|
mDragging = editMode.secondarySelectStartDrag (event->pos());
|
||||||
|
|
||||||
if (mDragging)
|
if (mDragging)
|
||||||
|
@ -656,53 +653,13 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event)
|
|
||||||
{
|
|
||||||
std::string button = mapButton (event);
|
|
||||||
|
|
||||||
if (button=="p-edit" || button=="s-edit" ||
|
|
||||||
button=="p-select" || button=="s-select")
|
|
||||||
{
|
|
||||||
if (!mDragging)
|
|
||||||
mDragMode = button;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
SceneWidget::mousePressEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event)
|
|
||||||
{
|
|
||||||
std::string button = mapButton (event);
|
|
||||||
mDragMode.clear();
|
|
||||||
|
|
||||||
if (button=="p-edit" || button=="s-edit" ||
|
|
||||||
button=="p-select" || button=="s-select")
|
|
||||||
{
|
|
||||||
if (mDragging)
|
|
||||||
{
|
|
||||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
|
||||||
|
|
||||||
editMode.dragCompleted(event->pos());
|
|
||||||
mDragging = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WorldspaceHitResult hit = mousePick(event->pos(), getInteractionMask());
|
|
||||||
|
|
||||||
handleMouseClick (hit, button, event->modifiers() & Qt::ShiftModifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
SceneWidget::mouseReleaseEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
|
void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
|
||||||
{
|
{
|
||||||
if (mDragging)
|
if (mDragging)
|
||||||
{
|
{
|
||||||
double factor = mDragWheelFactor;
|
double factor = mDragWheelFactor;
|
||||||
|
|
||||||
if (event->modifiers() & Qt::ShiftModifier)
|
if (mSpeedMode)
|
||||||
factor *= mDragShiftFactor;
|
factor *= mDragShiftFactor;
|
||||||
|
|
||||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||||
|
@ -713,27 +670,17 @@ void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
|
||||||
SceneWidget::wheelEvent(event);
|
SceneWidget::wheelEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
|
void CSVRender::WorldspaceWidget::handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type)
|
||||||
{
|
|
||||||
if(event->key() == Qt::Key_Escape)
|
|
||||||
{
|
|
||||||
abortDrag();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
SceneWidget::keyPressEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, bool shift)
|
|
||||||
{
|
{
|
||||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||||
|
|
||||||
if (button=="p-edit")
|
if (type == InteractionType_PrimaryEdit)
|
||||||
editMode.primaryEditPressed (hit);
|
editMode.primaryEditPressed (hit);
|
||||||
else if (button=="s-edit")
|
else if (type == InteractionType_SecondaryEdit)
|
||||||
editMode.secondaryEditPressed (hit);
|
editMode.secondaryEditPressed (hit);
|
||||||
else if (button=="p-select")
|
else if (type == InteractionType_PrimarySelect)
|
||||||
editMode.primarySelectPressed (hit);
|
editMode.primarySelectPressed (hit);
|
||||||
else if (button=="s-select")
|
else if (type == InteractionType_SecondarySelect)
|
||||||
editMode.secondarySelectPressed (hit);
|
editMode.secondarySelectPressed (hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,3 +688,53 @@ CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
|
||||||
{
|
{
|
||||||
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
|
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::primaryEdit(bool activate)
|
||||||
|
{
|
||||||
|
handleInteraction(InteractionType_PrimaryEdit, activate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::secondaryEdit(bool activate)
|
||||||
|
{
|
||||||
|
handleInteraction(InteractionType_SecondaryEdit, activate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::primarySelect(bool activate)
|
||||||
|
{
|
||||||
|
handleInteraction(InteractionType_PrimarySelect, activate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::secondarySelect(bool activate)
|
||||||
|
{
|
||||||
|
handleInteraction(InteractionType_SecondarySelect, activate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::speedMode(bool activate)
|
||||||
|
{
|
||||||
|
mSpeedMode = activate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::handleInteraction(InteractionType type, bool activate)
|
||||||
|
{
|
||||||
|
if (activate)
|
||||||
|
{
|
||||||
|
if (!mDragging)
|
||||||
|
mDragMode = type;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mDragMode = InteractionType_None;
|
||||||
|
|
||||||
|
if (mDragging)
|
||||||
|
{
|
||||||
|
EditMode* editMode = getEditMode();
|
||||||
|
editMode->dragCompleted(mapFromGlobal(QCursor::pos()));
|
||||||
|
mDragging = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WorldspaceHitResult hit = mousePick(mapFromGlobal(QCursor::pos()), getInteractionMask());
|
||||||
|
handleInteractionPress(hit, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -55,10 +55,11 @@ namespace CSVRender
|
||||||
unsigned int mInteractionMask;
|
unsigned int mInteractionMask;
|
||||||
CSVWidget::SceneToolMode *mEditMode;
|
CSVWidget::SceneToolMode *mEditMode;
|
||||||
bool mLocked;
|
bool mLocked;
|
||||||
std::string mDragMode;
|
int mDragMode;
|
||||||
bool mDragging;
|
bool mDragging;
|
||||||
int mDragX;
|
int mDragX;
|
||||||
int mDragY;
|
int mDragY;
|
||||||
|
bool mSpeedMode;
|
||||||
double mDragFactor;
|
double mDragFactor;
|
||||||
double mDragWheelFactor;
|
double mDragWheelFactor;
|
||||||
double mDragShiftFactor;
|
double mDragShiftFactor;
|
||||||
|
@ -85,6 +86,15 @@ namespace CSVRender
|
||||||
ignored //either mixed cells, or not cells
|
ignored //either mixed cells, or not cells
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum InteractionType
|
||||||
|
{
|
||||||
|
InteractionType_PrimaryEdit,
|
||||||
|
InteractionType_PrimarySelect,
|
||||||
|
InteractionType_SecondaryEdit,
|
||||||
|
InteractionType_SecondarySelect,
|
||||||
|
InteractionType_None
|
||||||
|
};
|
||||||
|
|
||||||
WorldspaceWidget (CSMDoc::Document& document, QWidget *parent = 0);
|
WorldspaceWidget (CSMDoc::Document& document, QWidget *parent = 0);
|
||||||
~WorldspaceWidget ();
|
~WorldspaceWidget ();
|
||||||
|
|
||||||
|
@ -171,12 +181,6 @@ namespace CSVRender
|
||||||
/// Erase all overrides and restore the visual representation to its true state.
|
/// Erase all overrides and restore the visual representation to its true state.
|
||||||
virtual void reset (unsigned int elementMask) = 0;
|
virtual void reset (unsigned int elementMask) = 0;
|
||||||
|
|
||||||
/// \note Drags will be automatically aborted when the aborting is triggered
|
|
||||||
/// (either explicitly or implicitly) from within this class. This function only
|
|
||||||
/// needs to be called, when the drag abort is triggered externally (e.g. from
|
|
||||||
/// an edit mode).
|
|
||||||
void abortDrag();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// Visual elements in a scene
|
/// Visual elements in a scene
|
||||||
|
@ -197,21 +201,16 @@ namespace CSVRender
|
||||||
virtual void updateOverlay();
|
virtual void updateOverlay();
|
||||||
|
|
||||||
virtual void mouseMoveEvent (QMouseEvent *event);
|
virtual void mouseMoveEvent (QMouseEvent *event);
|
||||||
virtual void mousePressEvent (QMouseEvent *event);
|
|
||||||
virtual void mouseReleaseEvent (QMouseEvent *event);
|
|
||||||
virtual void wheelEvent (QWheelEvent *event);
|
virtual void wheelEvent (QWheelEvent *event);
|
||||||
virtual void keyPressEvent (QKeyEvent *event);
|
|
||||||
|
|
||||||
virtual void handleMouseClick (const WorldspaceHitResult& hit, const std::string& button,
|
virtual void handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type);
|
||||||
bool shift);
|
|
||||||
|
|
||||||
/// \return Is \a key a button mapping setting? (ignored otherwise)
|
|
||||||
virtual bool storeMappingSetting (const CSMPrefs::Setting *setting);
|
|
||||||
|
|
||||||
virtual void settingChanged (const CSMPrefs::Setting *setting);
|
virtual void settingChanged (const CSMPrefs::Setting *setting);
|
||||||
|
|
||||||
EditMode *getEditMode();
|
EditMode *getEditMode();
|
||||||
|
|
||||||
|
bool getSpeedMode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void dragEnterEvent(QDragEnterEvent *event);
|
void dragEnterEvent(QDragEnterEvent *event);
|
||||||
|
@ -222,6 +221,16 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual std::string getStartupInstruction() = 0;
|
virtual std::string getStartupInstruction() = 0;
|
||||||
|
|
||||||
|
void handleInteraction(InteractionType type, bool activate);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
/// \note Drags will be automatically aborted when the aborting is triggered
|
||||||
|
/// (either explicitly or implicitly) from within this class. This function only
|
||||||
|
/// needs to be called, when the drag abort is triggered externally (e.g. from
|
||||||
|
/// an edit mode).
|
||||||
|
void abortDrag();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
virtual void referenceableDataChanged (const QModelIndex& topLeft,
|
virtual void referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
@ -255,6 +264,16 @@ namespace CSVRender
|
||||||
|
|
||||||
void showToolTip();
|
void showToolTip();
|
||||||
|
|
||||||
|
void primaryEdit(bool activate);
|
||||||
|
|
||||||
|
void secondaryEdit(bool activate);
|
||||||
|
|
||||||
|
void primarySelect(bool activate);
|
||||||
|
|
||||||
|
void secondarySelect(bool activate);
|
||||||
|
|
||||||
|
void speedMode(bool activate);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
|
|
||||||
void elementSelectionChanged();
|
void elementSelectionChanged();
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "../../model/tools/reportmodel.hpp"
|
#include "../../model/tools/reportmodel.hpp"
|
||||||
|
|
||||||
#include "../../model/prefs/state.hpp"
|
#include "../../model/prefs/state.hpp"
|
||||||
|
#include "../../model/prefs/shortcut.hpp"
|
||||||
|
|
||||||
#include "../../view/world/idtypedelegate.hpp"
|
#include "../../view/world/idtypedelegate.hpp"
|
||||||
|
|
||||||
|
@ -171,14 +172,20 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
||||||
mShowAction = new QAction (tr ("Show"), this);
|
mShowAction = new QAction (tr ("Show"), this);
|
||||||
connect (mShowAction, SIGNAL (triggered()), this, SLOT (showSelection()));
|
connect (mShowAction, SIGNAL (triggered()), this, SLOT (showSelection()));
|
||||||
addAction (mShowAction);
|
addAction (mShowAction);
|
||||||
|
CSMPrefs::Shortcut* showShortcut = new CSMPrefs::Shortcut("reporttable-show", this);
|
||||||
|
showShortcut->associateAction(mShowAction);
|
||||||
|
|
||||||
mRemoveAction = new QAction (tr ("Remove from list"), this);
|
mRemoveAction = new QAction (tr ("Remove from list"), this);
|
||||||
connect (mRemoveAction, SIGNAL (triggered()), this, SLOT (removeSelection()));
|
connect (mRemoveAction, SIGNAL (triggered()), this, SLOT (removeSelection()));
|
||||||
addAction (mRemoveAction);
|
addAction (mRemoveAction);
|
||||||
|
CSMPrefs::Shortcut* removeShortcut = new CSMPrefs::Shortcut("reporttable-remove", this);
|
||||||
|
removeShortcut->associateAction(mRemoveAction);
|
||||||
|
|
||||||
mReplaceAction = new QAction (tr ("Replace"), this);
|
mReplaceAction = new QAction (tr ("Replace"), this);
|
||||||
connect (mReplaceAction, SIGNAL (triggered()), this, SIGNAL (replaceRequest()));
|
connect (mReplaceAction, SIGNAL (triggered()), this, SIGNAL (replaceRequest()));
|
||||||
addAction (mReplaceAction);
|
addAction (mReplaceAction);
|
||||||
|
CSMPrefs::Shortcut* replaceShortcut = new CSMPrefs::Shortcut("reporttable-replace", this);
|
||||||
|
replaceShortcut->associateAction(mReplaceAction);
|
||||||
|
|
||||||
if (mRefreshState)
|
if (mRefreshState)
|
||||||
{
|
{
|
||||||
|
@ -186,6 +193,8 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
||||||
mRefreshAction->setEnabled (!(mDocument.getState() & mRefreshState));
|
mRefreshAction->setEnabled (!(mDocument.getState() & mRefreshState));
|
||||||
connect (mRefreshAction, SIGNAL (triggered()), this, SIGNAL (refreshRequest()));
|
connect (mRefreshAction, SIGNAL (triggered()), this, SIGNAL (refreshRequest()));
|
||||||
addAction (mRefreshAction);
|
addAction (mRefreshAction);
|
||||||
|
CSMPrefs::Shortcut* refreshShortcut = new CSMPrefs::Shortcut("reporttable-refresh", this);
|
||||||
|
refreshShortcut->associateAction(mRefreshAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
mDoubleClickActions.insert (std::make_pair (Qt::NoModifier, Action_Edit));
|
mDoubleClickActions.insert (std::make_pair (Qt::NoModifier, Action_Edit));
|
||||||
|
|
|
@ -3,9 +3,17 @@
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
|
||||||
|
#include "../../model/prefs/state.hpp"
|
||||||
|
#include "../../model/prefs/shortcutmanager.hpp"
|
||||||
|
|
||||||
|
void CSVWidget::PushButton::processShortcuts()
|
||||||
|
{
|
||||||
|
mProcessedToolTip = CSMPrefs::State::get().getShortcutManager().processToolTip(mToolTip);
|
||||||
|
}
|
||||||
|
|
||||||
void CSVWidget::PushButton::setExtendedToolTip()
|
void CSVWidget::PushButton::setExtendedToolTip()
|
||||||
{
|
{
|
||||||
QString tooltip = mToolTip;
|
QString tooltip = mProcessedToolTip;
|
||||||
|
|
||||||
if (tooltip.isEmpty())
|
if (tooltip.isEmpty())
|
||||||
tooltip = "(Tool tip not implemented yet)";
|
tooltip = "(Tool tip not implemented yet)";
|
||||||
|
@ -77,13 +85,18 @@ CSVWidget::PushButton::PushButton (const QIcon& icon, Type type, const QString&
|
||||||
connect (this, SIGNAL (toggled (bool)), this, SLOT (checkedStateChanged (bool)));
|
connect (this, SIGNAL (toggled (bool)), this, SLOT (checkedStateChanged (bool)));
|
||||||
}
|
}
|
||||||
setCheckable (type==Type_Mode || type==Type_Toggle);
|
setCheckable (type==Type_Mode || type==Type_Toggle);
|
||||||
|
processShortcuts();
|
||||||
setExtendedToolTip();
|
setExtendedToolTip();
|
||||||
|
|
||||||
|
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
|
||||||
|
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVWidget::PushButton::PushButton (Type type, const QString& tooltip, QWidget *parent)
|
CSVWidget::PushButton::PushButton (Type type, const QString& tooltip, QWidget *parent)
|
||||||
: QPushButton (parent), mKeepOpen (false), mType (type), mToolTip (tooltip)
|
: QPushButton (parent), mKeepOpen (false), mType (type), mToolTip (tooltip)
|
||||||
{
|
{
|
||||||
setCheckable (type==Type_Mode || type==Type_Toggle);
|
setCheckable (type==Type_Mode || type==Type_Toggle);
|
||||||
|
processShortcuts();
|
||||||
setExtendedToolTip();
|
setExtendedToolTip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +107,7 @@ bool CSVWidget::PushButton::hasKeepOpen() const
|
||||||
|
|
||||||
QString CSVWidget::PushButton::getBaseToolTip() const
|
QString CSVWidget::PushButton::getBaseToolTip() const
|
||||||
{
|
{
|
||||||
return mToolTip;
|
return mProcessedToolTip;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVWidget::PushButton::Type CSVWidget::PushButton::getType() const
|
CSVWidget::PushButton::Type CSVWidget::PushButton::getType() const
|
||||||
|
@ -106,3 +119,12 @@ void CSVWidget::PushButton::checkedStateChanged (bool checked)
|
||||||
{
|
{
|
||||||
setExtendedToolTip();
|
setExtendedToolTip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVWidget::PushButton::settingChanged (const CSMPrefs::Setting *setting)
|
||||||
|
{
|
||||||
|
if (setting->getParent()->getKey() == "Key Bindings")
|
||||||
|
{
|
||||||
|
processShortcuts();
|
||||||
|
setExtendedToolTip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
|
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
|
namespace CSMPrefs
|
||||||
|
{
|
||||||
|
class Setting;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSVWidget
|
namespace CSVWidget
|
||||||
{
|
{
|
||||||
class PushButton : public QPushButton
|
class PushButton : public QPushButton
|
||||||
|
@ -24,9 +29,11 @@ namespace CSVWidget
|
||||||
bool mKeepOpen;
|
bool mKeepOpen;
|
||||||
Type mType;
|
Type mType;
|
||||||
QString mToolTip;
|
QString mToolTip;
|
||||||
|
QString mProcessedToolTip;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void processShortcuts();
|
||||||
void setExtendedToolTip();
|
void setExtendedToolTip();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -57,6 +64,7 @@ namespace CSVWidget
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void checkedStateChanged (bool checked);
|
void checkedStateChanged (bool checked);
|
||||||
|
void settingChanged (const CSMPrefs::Setting *setting);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#include "scenetoolbar.hpp"
|
#include "scenetoolbar.hpp"
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QShortcut>
|
|
||||||
|
#include "../../model/prefs/shortcut.hpp"
|
||||||
|
|
||||||
#include "scenetool.hpp"
|
#include "scenetool.hpp"
|
||||||
|
|
||||||
|
@ -25,9 +26,8 @@ CSVWidget::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent)
|
||||||
|
|
||||||
setLayout (mLayout);
|
setLayout (mLayout);
|
||||||
|
|
||||||
/// \todo make shortcut configurable
|
CSMPrefs::Shortcut* focusSceneShortcut = new CSMPrefs::Shortcut("scene-focus-toolbar", this);
|
||||||
QShortcut *focusScene = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut);
|
connect(focusSceneShortcut, SIGNAL(activated()), this, SIGNAL(focusSceneRequest()));
|
||||||
connect (focusScene, SIGNAL (activated()), this, SIGNAL (focusSceneRequest()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWidget::SceneToolbar::addTool (SceneTool *tool, SceneTool *insertPoint)
|
void CSVWidget::SceneToolbar::addTool (SceneTool *tool, SceneTool *insertPoint)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QSignalMapper>
|
#include <QSignalMapper>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QContextMenuEvent>
|
#include <QContextMenuEvent>
|
||||||
|
#include <QEvent>
|
||||||
|
|
||||||
#include "scenetoolbar.hpp"
|
#include "scenetoolbar.hpp"
|
||||||
#include "modebutton.hpp"
|
#include "modebutton.hpp"
|
||||||
|
@ -133,6 +134,16 @@ void CSVWidget::SceneToolMode::setButton (const std::string& id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSVWidget::SceneToolMode::event(QEvent* event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::ToolTip)
|
||||||
|
{
|
||||||
|
adjustToolTip(mCurrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SceneTool::event(event);
|
||||||
|
}
|
||||||
|
|
||||||
void CSVWidget::SceneToolMode::selected()
|
void CSVWidget::SceneToolMode::selected()
|
||||||
{
|
{
|
||||||
std::map<ModeButton *, std::string>::iterator iter =
|
std::map<ModeButton *, std::string>::iterator iter =
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
class QHBoxLayout;
|
class QHBoxLayout;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
|
class QEvent;
|
||||||
|
|
||||||
namespace CSVWidget
|
namespace CSVWidget
|
||||||
{
|
{
|
||||||
|
@ -43,6 +44,10 @@ namespace CSVWidget
|
||||||
|
|
||||||
void setButton (std::map<ModeButton *, std::string>::iterator iter);
|
void setButton (std::map<ModeButton *, std::string>::iterator iter);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool event(QEvent* event);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SceneToolMode (SceneToolbar *parent, const QString& toolTip);
|
SceneToolMode (SceneToolbar *parent, const QString& toolTip);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "../../model/prefs/shortcut.hpp"
|
||||||
|
|
||||||
#include "../../model/world/nestedtableproxymodel.hpp"
|
#include "../../model/world/nestedtableproxymodel.hpp"
|
||||||
#include "../../model/world/universalid.hpp"
|
#include "../../model/world/universalid.hpp"
|
||||||
#include "../../model/world/commands.hpp"
|
#include "../../model/world/commands.hpp"
|
||||||
|
@ -60,14 +62,16 @@ CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document,
|
||||||
if (!fixedRows)
|
if (!fixedRows)
|
||||||
{
|
{
|
||||||
mAddNewRowAction = new QAction (tr ("Add new row"), this);
|
mAddNewRowAction = new QAction (tr ("Add new row"), this);
|
||||||
|
|
||||||
connect(mAddNewRowAction, SIGNAL(triggered()),
|
connect(mAddNewRowAction, SIGNAL(triggered()),
|
||||||
this, SLOT(addNewRowActionTriggered()));
|
this, SLOT(addNewRowActionTriggered()));
|
||||||
|
CSMPrefs::Shortcut* addRowShortcut = new CSMPrefs::Shortcut("table-add", this);
|
||||||
|
addRowShortcut->associateAction(mAddNewRowAction);
|
||||||
|
|
||||||
mRemoveRowAction = new QAction (tr ("Remove rows"), this);
|
mRemoveRowAction = new QAction (tr ("Remove rows"), this);
|
||||||
|
|
||||||
connect(mRemoveRowAction, SIGNAL(triggered()),
|
connect(mRemoveRowAction, SIGNAL(triggered()),
|
||||||
this, SLOT(removeRowActionTriggered()));
|
this, SLOT(removeRowActionTriggered()));
|
||||||
|
CSMPrefs::Shortcut* removeRowShortcut = new CSMPrefs::Shortcut("table-remove", this);
|
||||||
|
removeRowShortcut->associateAction(mRemoveRowAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
mEditIdAction = new TableEditIdAction(*this, this);
|
mEditIdAction = new TableEditIdAction(*this, this);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "../../model/world/commanddispatcher.hpp"
|
#include "../../model/world/commanddispatcher.hpp"
|
||||||
|
|
||||||
#include "../../model/prefs/state.hpp"
|
#include "../../model/prefs/state.hpp"
|
||||||
|
#include "../../model/prefs/shortcut.hpp"
|
||||||
|
|
||||||
#include "tableeditidaction.hpp"
|
#include "tableeditidaction.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
@ -283,49 +284,72 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
||||||
mEditAction = new QAction (tr ("Edit Record"), this);
|
mEditAction = new QAction (tr ("Edit Record"), this);
|
||||||
connect (mEditAction, SIGNAL (triggered()), this, SLOT (editRecord()));
|
connect (mEditAction, SIGNAL (triggered()), this, SLOT (editRecord()));
|
||||||
addAction (mEditAction);
|
addAction (mEditAction);
|
||||||
|
CSMPrefs::Shortcut* editShortcut = new CSMPrefs::Shortcut("table-edit", this);
|
||||||
|
editShortcut->associateAction(mEditAction);
|
||||||
|
|
||||||
if (createAndDelete)
|
if (createAndDelete)
|
||||||
{
|
{
|
||||||
mCreateAction = new QAction (tr ("Add Record"), this);
|
mCreateAction = new QAction (tr ("Add Record"), this);
|
||||||
connect (mCreateAction, SIGNAL (triggered()), this, SIGNAL (createRequest()));
|
connect (mCreateAction, SIGNAL (triggered()), this, SIGNAL (createRequest()));
|
||||||
addAction (mCreateAction);
|
addAction (mCreateAction);
|
||||||
|
CSMPrefs::Shortcut* createShortcut = new CSMPrefs::Shortcut("table-add", this);
|
||||||
|
createShortcut->associateAction(mCreateAction);
|
||||||
|
|
||||||
mCloneAction = new QAction (tr ("Clone Record"), this);
|
mCloneAction = new QAction (tr ("Clone Record"), this);
|
||||||
connect(mCloneAction, SIGNAL (triggered()), this, SLOT (cloneRecord()));
|
connect(mCloneAction, SIGNAL (triggered()), this, SLOT (cloneRecord()));
|
||||||
addAction(mCloneAction);
|
addAction(mCloneAction);
|
||||||
|
CSMPrefs::Shortcut* cloneShortcut = new CSMPrefs::Shortcut("table-clone", this);
|
||||||
|
cloneShortcut->associateAction(mCloneAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
mRevertAction = new QAction (tr ("Revert Record"), this);
|
mRevertAction = new QAction (tr ("Revert Record"), this);
|
||||||
connect (mRevertAction, SIGNAL (triggered()), mDispatcher, SLOT (executeRevert()));
|
connect (mRevertAction, SIGNAL (triggered()), mDispatcher, SLOT (executeRevert()));
|
||||||
addAction (mRevertAction);
|
addAction (mRevertAction);
|
||||||
|
CSMPrefs::Shortcut* revertShortcut = new CSMPrefs::Shortcut("table-revert", this);
|
||||||
|
revertShortcut->associateAction(mRevertAction);
|
||||||
|
|
||||||
mDeleteAction = new QAction (tr ("Delete Record"), this);
|
mDeleteAction = new QAction (tr ("Delete Record"), this);
|
||||||
connect (mDeleteAction, SIGNAL (triggered()), mDispatcher, SLOT (executeDelete()));
|
connect (mDeleteAction, SIGNAL (triggered()), mDispatcher, SLOT (executeDelete()));
|
||||||
addAction (mDeleteAction);
|
addAction (mDeleteAction);
|
||||||
|
CSMPrefs::Shortcut* deleteShortcut = new CSMPrefs::Shortcut("table-remove", this);
|
||||||
|
deleteShortcut->associateAction(mDeleteAction);
|
||||||
|
|
||||||
|
|
||||||
mMoveUpAction = new QAction (tr ("Move Up"), this);
|
mMoveUpAction = new QAction (tr ("Move Up"), this);
|
||||||
connect (mMoveUpAction, SIGNAL (triggered()), this, SLOT (moveUpRecord()));
|
connect (mMoveUpAction, SIGNAL (triggered()), this, SLOT (moveUpRecord()));
|
||||||
addAction (mMoveUpAction);
|
addAction (mMoveUpAction);
|
||||||
|
CSMPrefs::Shortcut* moveUpShortcut = new CSMPrefs::Shortcut("table-moveup", this);
|
||||||
|
moveUpShortcut->associateAction(mMoveUpAction);
|
||||||
|
|
||||||
mMoveDownAction = new QAction (tr ("Move Down"), this);
|
mMoveDownAction = new QAction (tr ("Move Down"), this);
|
||||||
connect (mMoveDownAction, SIGNAL (triggered()), this, SLOT (moveDownRecord()));
|
connect (mMoveDownAction, SIGNAL (triggered()), this, SLOT (moveDownRecord()));
|
||||||
addAction (mMoveDownAction);
|
addAction (mMoveDownAction);
|
||||||
|
CSMPrefs::Shortcut* moveDownShortcut = new CSMPrefs::Shortcut("table-movedown", this);
|
||||||
|
moveDownShortcut->associateAction(mMoveDownAction);
|
||||||
|
|
||||||
mViewAction = new QAction (tr ("View"), this);
|
mViewAction = new QAction (tr ("View"), this);
|
||||||
connect (mViewAction, SIGNAL (triggered()), this, SLOT (viewRecord()));
|
connect (mViewAction, SIGNAL (triggered()), this, SLOT (viewRecord()));
|
||||||
addAction (mViewAction);
|
addAction (mViewAction);
|
||||||
|
CSMPrefs::Shortcut* viewShortcut = new CSMPrefs::Shortcut("table-view", this);
|
||||||
|
viewShortcut->associateAction(mViewAction);
|
||||||
|
|
||||||
mPreviewAction = new QAction (tr ("Preview"), this);
|
mPreviewAction = new QAction (tr ("Preview"), this);
|
||||||
connect (mPreviewAction, SIGNAL (triggered()), this, SLOT (previewRecord()));
|
connect (mPreviewAction, SIGNAL (triggered()), this, SLOT (previewRecord()));
|
||||||
addAction (mPreviewAction);
|
addAction (mPreviewAction);
|
||||||
|
CSMPrefs::Shortcut* previewShortcut = new CSMPrefs::Shortcut("table-preview", this);
|
||||||
|
previewShortcut->associateAction(mPreviewAction);
|
||||||
|
|
||||||
mExtendedDeleteAction = new QAction (tr ("Extended Delete Record"), this);
|
mExtendedDeleteAction = new QAction (tr ("Extended Delete Record"), this);
|
||||||
connect (mExtendedDeleteAction, SIGNAL (triggered()), this, SLOT (executeExtendedDelete()));
|
connect (mExtendedDeleteAction, SIGNAL (triggered()), this, SLOT (executeExtendedDelete()));
|
||||||
addAction (mExtendedDeleteAction);
|
addAction (mExtendedDeleteAction);
|
||||||
|
CSMPrefs::Shortcut* extendedDeleteShortcut = new CSMPrefs::Shortcut("table-extendeddelete", this);
|
||||||
|
extendedDeleteShortcut->associateAction(mExtendedDeleteAction);
|
||||||
|
|
||||||
mExtendedRevertAction = new QAction (tr ("Extended Revert Record"), this);
|
mExtendedRevertAction = new QAction (tr ("Extended Revert Record"), this);
|
||||||
connect (mExtendedRevertAction, SIGNAL (triggered()), this, SLOT (executeExtendedRevert()));
|
connect (mExtendedRevertAction, SIGNAL (triggered()), this, SLOT (executeExtendedRevert()));
|
||||||
addAction (mExtendedRevertAction);
|
addAction (mExtendedRevertAction);
|
||||||
|
CSMPrefs::Shortcut* extendedRevertShortcut = new CSMPrefs::Shortcut("table-extendedrevert", this);
|
||||||
|
extendedRevertShortcut->associateAction(mExtendedRevertAction);
|
||||||
|
|
||||||
mEditIdAction = new TableEditIdAction (*this, this);
|
mEditIdAction = new TableEditIdAction (*this, this);
|
||||||
connect (mEditIdAction, SIGNAL (triggered()), this, SLOT (editCell()));
|
connect (mEditIdAction, SIGNAL (triggered()), this, SLOT (editCell()));
|
||||||
|
|
Loading…
Reference in a new issue