From 12db6d21145b955a7f3c35f8f0eaefb689668daf Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Wed, 27 Jul 2016 13:53:33 -0400 Subject: [PATCH] Add modifier setting. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/prefs/modifiersetting.cpp | 125 ++++++++++++++++++++ apps/opencs/model/prefs/modifiersetting.hpp | 41 +++++++ apps/opencs/model/prefs/shortcutsetting.cpp | 9 +- apps/opencs/model/prefs/shortcutsetting.hpp | 4 +- apps/opencs/model/prefs/state.cpp | 17 ++- apps/opencs/model/prefs/state.hpp | 3 + 7 files changed, 193 insertions(+), 8 deletions(-) create mode 100644 apps/opencs/model/prefs/modifiersetting.cpp create mode 100644 apps/opencs/model/prefs/modifiersetting.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 266a9c250..be3fa858a 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -113,7 +113,7 @@ opencs_units (view/prefs opencs_units (model/prefs state setting intsetting doublesetting boolsetting enumsetting coloursetting shortcut - shortcuteventhandler shortcutmanager shortcutsetting + shortcuteventhandler shortcutmanager shortcutsetting modifiersetting ) opencs_units_noqt (model/prefs diff --git a/apps/opencs/model/prefs/modifiersetting.cpp b/apps/opencs/model/prefs/modifiersetting.cpp new file mode 100644 index 000000000..73c8343a3 --- /dev/null +++ b/apps/opencs/model/prefs/modifiersetting.cpp @@ -0,0 +1,125 @@ +#include "modifiersetting.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#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 ModifierSetting::makeWidgets(QWidget* parent) + { + QKeySequence sequence; + int modifier = 0; + State::get().getShortcutManager().getSequence(getKey(), sequence, 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(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(event); + int mod = mouseEvent->modifiers(); + int button = mouseEvent->button(); + + return handleEvent(target, mod, button); + } + + 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) + return false; + + // Handle blacklist + for (size_t i = 0; i < BlacklistSize; ++i) + { + if (value == Blacklist[i]) + return true; + } + + + // Update modifier + QKeySequence sequence; + int modifier = 0; + + State::get().getShortcutManager().getSequence(getKey(), sequence, modifier); + + modifier = value; + State::get().getShortcutManager().setSequence(getKey(), sequence, modifier); + + // Store + { + std::string value = State::get().getShortcutManager().convertToString(sequence, modifier); + + QMutexLocker lock(getMutex()); + getValues().setString(getKey(), getParent()->getKey(), value); + } + + getParent()->getState()->update(*this); + + // Update button + QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(modifier).c_str()); + + mButton->setText(text); + mButton->setChecked(false); + mEditorActive = false; + + return true; + } + + void ModifierSetting::buttonToggled(bool checked) + { + if (checked) + mButton->setText("Press keys or click here..."); + + mEditorActive = checked; + } +} diff --git a/apps/opencs/model/prefs/modifiersetting.hpp b/apps/opencs/model/prefs/modifiersetting.hpp new file mode 100644 index 000000000..b1394b6ea --- /dev/null +++ b/apps/opencs/model/prefs/modifiersetting.hpp @@ -0,0 +1,41 @@ +#ifndef CSM_PREFS_MODIFIERSETTING_H +#define CSM_PREFS_MODIFIERSETTING_H + +#include + +#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 makeWidgets(QWidget* parent); + + protected: + + bool eventFilter(QObject* target, QEvent* event); + + private: + + bool handleEvent(QObject* target, int mod, int value); + + QPushButton* mButton; + bool mEditorActive; + + private slots: + + void buttonToggled(bool checked); + }; +} + +#endif diff --git a/apps/opencs/model/prefs/shortcutsetting.cpp b/apps/opencs/model/prefs/shortcutsetting.cpp index 211aead55..07f9c8052 100644 --- a/apps/opencs/model/prefs/shortcutsetting.cpp +++ b/apps/opencs/model/prefs/shortcutsetting.cpp @@ -14,9 +14,8 @@ namespace CSMPrefs { ShortcutSetting::ShortcutSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key, - const std::string& label, const QKeySequence& default_) + const std::string& label) : Setting(parent, values, mutex, key, label) - , mDefault(default_) , mEditorActive(false) , mEditorPos(0) { @@ -30,7 +29,11 @@ namespace CSMPrefs std::pair ShortcutSetting::makeWidgets(QWidget* parent) { - QString text = QString::fromUtf8(State::get().getShortcutManager().convertToString(mDefault).c_str()); + QKeySequence sequence; + int modifier = 0; + State::get().getShortcutManager().getSequence(getKey(), sequence, modifier); + + 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); diff --git a/apps/opencs/model/prefs/shortcutsetting.hpp b/apps/opencs/model/prefs/shortcutsetting.hpp index 2a86e68dd..0521e2291 100644 --- a/apps/opencs/model/prefs/shortcutsetting.hpp +++ b/apps/opencs/model/prefs/shortcutsetting.hpp @@ -17,7 +17,7 @@ namespace CSMPrefs public: ShortcutSetting(Category* parent, Settings::Manager* values, QMutex* mutex, const std::string& key, - const std::string& label, const QKeySequence& default_); + const std::string& label); virtual std::pair makeWidgets(QWidget* parent); @@ -29,8 +29,6 @@ namespace CSMPrefs bool handleEvent(QObject* target, int mod, int value, bool active); - QKeySequence mDefault; - QPushButton* mButton; bool mEditorActive; diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 89491e8dc..8c5005156 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -12,6 +12,7 @@ #include "boolsetting.hpp" #include "coloursetting.hpp" #include "shortcutsetting.hpp" +#include "modifiersetting.hpp" CSMPrefs::State *CSMPrefs::State::sThis = 0; @@ -292,6 +293,7 @@ void CSMPrefs::State::declare() declareShortcut ("free-backward", "Free camera backward", QKeySequence(Qt::Key_S)); declareShortcut ("free-left", "Free camera left", QKeySequence(Qt::Key_A)); declareShortcut ("free-right", "Free camera right", QKeySequence(Qt::Key_D)); + declareModifier ("free-forward", "Free camera speed modifier"); declareShortcut ("free-roll-left", "Free camera roll left", QKeySequence(Qt::Key_Q)); declareShortcut ("free-roll-right", "Free camera roll right", QKeySequence(Qt::Key_E)); declareShortcut ("free-speed-mode", "Free camera speed mode toggle", QKeySequence(Qt::Key_F)); @@ -301,6 +303,7 @@ void CSMPrefs::State::declare() declareShortcut ("orbit-down", "Orbit camera down", QKeySequence(Qt::Key_S)); declareShortcut ("orbit-left", "Orbit camera left", QKeySequence(Qt::Key_A)); declareShortcut ("orbit-right", "Orbit camera right", QKeySequence(Qt::Key_D)); + declareModifier ("orbit-up", "Orbit camera speed modifier"); declareShortcut ("orbit-roll-left", "Orbit camera roll left", QKeySequence(Qt::Key_Q)); declareShortcut ("orbit-roll-right", "Orbit camera roll right", QKeySequence(Qt::Key_E)); declareShortcut ("orbit-speed-mode", "Orbit camera speed mode toggle", QKeySequence(Qt::Key_F)); @@ -452,7 +455,19 @@ CSMPrefs::ShortcutSetting& CSMPrefs::State::declareShortcut (const std::string& getShortcutManager().setSequence(key, sequence, mod); CSMPrefs::ShortcutSetting *setting = new CSMPrefs::ShortcutSetting (&mCurrentCategory->second, &mSettings, &mMutex, - key, label, sequence); + key, label); + mCurrentCategory->second.addSetting (setting); + + return *setting; +} + +CSMPrefs::ModifierSetting& CSMPrefs::State::declareModifier(const std::string& key, const std::string& label) +{ + if (mCurrentCategory==mCategories.end()) + throw std::logic_error ("no category for setting"); + + CSMPrefs::ModifierSetting *setting = new CSMPrefs::ModifierSetting (&mCurrentCategory->second, &mSettings, &mMutex, + key, label); mCurrentCategory->second.addSetting (setting); return *setting; diff --git a/apps/opencs/model/prefs/state.hpp b/apps/opencs/model/prefs/state.hpp index 23d9df387..d65dc7d00 100644 --- a/apps/opencs/model/prefs/state.hpp +++ b/apps/opencs/model/prefs/state.hpp @@ -27,6 +27,7 @@ namespace CSMPrefs class BoolSetting; class ColourSetting; class ShortcutSetting; + class ModifierSetting; /// \brief User settings state /// @@ -77,6 +78,8 @@ namespace CSMPrefs ShortcutSetting& declareShortcut (const std::string& key, const std::string& label, const QKeySequence& default_, int modifier_=0); + ModifierSetting& declareModifier(const std::string& key, const std::string& label); + void declareSeparator(); void setDefault (const std::string& key, const std::string& default_);