diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index be3fa858a..6e19c03b2 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -108,7 +108,7 @@ opencs_units_noqt (view/tools ) opencs_units (view/prefs - dialogue pagebase page + dialogue pagebase page keybindingpage ) opencs_units (model/prefs diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 8c5005156..0b0f9d700 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -217,6 +217,7 @@ void CSMPrefs::State::declare() declareCategory ("Key Bindings"); + declareSubcategory ("Document"); declareShortcut ("document-file-newgame", "Create new game", QKeySequence()); declareShortcut ("document-file-newaddon", "Create new addon", QKeySequence()); declareShortcut ("document-file-open", "Open", QKeySequence()); @@ -269,12 +270,12 @@ void CSMPrefs::State::declare() declareShortcut ("document-debug-shutdown", "Stop Debug", QKeySequence()); declareShortcut ("document-debug-runlog", "Run Log", QKeySequence()); - declareSeparator (); + declareSubcategory ("Table"); declareShortcut ("table-edit", "Edit record", QKeySequence()); declareShortcut ("table-add", "Add row/record", QKeySequence(Qt::ControlModifier | Qt::Key_N)); declareShortcut ("table-clone", "Clone record", QKeySequence()); declareShortcut ("table-revert", "Revert record", QKeySequence()); - declareShortcut ("table-remove", "Remove record", QKeySequence(Qt::Key_Delete)); + 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()); @@ -282,46 +283,46 @@ void CSMPrefs::State::declare() declareShortcut ("table-extendeddelete", "Extended record deletion", QKeySequence()); declareShortcut ("table-extendedrevert", "Extended record revertion", QKeySequence()); - declareSeparator (); + 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()); - declareSeparator (); - declareShortcut ("free-forward", "Free camera forward", QKeySequence(Qt::Key_W), Qt::Key_Shift); - declareShortcut ("free-backward", "Free camera backward", QKeySequence(Qt::Key_S)); - declareShortcut ("free-left", "Free camera left", QKeySequence(Qt::Key_A)); - 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)); - - declareSeparator (); - declareShortcut ("orbit-up", "Orbit camera up", QKeySequence(Qt::Key_W), Qt::Key_Shift); - declareShortcut ("orbit-down", "Orbit camera down", QKeySequence(Qt::Key_S)); - declareShortcut ("orbit-left", "Orbit camera left", QKeySequence(Qt::Key_A)); - declareShortcut ("orbit-right", "Orbit camera right", QKeySequence(Qt::Key_D)); - 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)); - declareShortcut ("orbit-center-selection", "Centers the camera on the selected item", QKeySequence(Qt::Key_C)); - - declareSeparator (); + declareSubcategory ("1st/Free Camera"); + declareShortcut ("free-forward", "Forward", QKeySequence(Qt::Key_W), Qt::Key_Shift); + declareShortcut ("free-backward", "Backward", QKeySequence(Qt::Key_S)); + declareShortcut ("free-left", "Left", QKeySequence(Qt::Key_A)); + declareShortcut ("free-right", "Right", QKeySequence(Qt::Key_D)); + declareModifier ("free-forward", "Speed modifier"); + declareShortcut ("free-roll-left", "Roll left", QKeySequence(Qt::Key_Q)); + declareShortcut ("free-roll-right", "Roll right", QKeySequence(Qt::Key_E)); + declareShortcut ("free-speed-mode", "Speed mode toggle", QKeySequence(Qt::Key_F)); + + declareSubcategory ("Orbit Camera"); + declareShortcut ("orbit-up", "Up", QKeySequence(Qt::Key_W), Qt::Key_Shift); + declareShortcut ("orbit-down", "Down", QKeySequence(Qt::Key_S)); + declareShortcut ("orbit-left", "Left", QKeySequence(Qt::Key_A)); + declareShortcut ("orbit-right", "Right", QKeySequence(Qt::Key_D)); + declareModifier ("orbit-up", "Speed modifier"); + declareShortcut ("orbit-roll-left", "Roll left", QKeySequence(Qt::Key_Q)); + declareShortcut ("orbit-roll-right", "Roll right", QKeySequence(Qt::Key_E)); + declareShortcut ("orbit-speed-mode", "Speed mode toggle", QKeySequence(Qt::Key_F)); + declareShortcut ("orbit-center-selection", "Center on selected", QKeySequence(Qt::Key_C)); + + 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", "Scene primary edit button", QKeySequence(Qt::RightButton)); - declareShortcut ("scene-edit-secondary", "Scene secondary edit button", + 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", "Scene primary select button", QKeySequence(Qt::MiddleButton)); - declareShortcut ("scene-select-secondary", "Scene secondary select button", + declareShortcut ("scene-select-primary", "Primary select", QKeySequence(Qt::MiddleButton)); + declareShortcut ("scene-select-secondary", "Secondary select", QKeySequence(Qt::ControlModifier | (int)Qt::MiddleButton)); - declareShortcut ("scene-edit-abort", "Scene editor abort key", QKeySequence(Qt::Key_Escape)); - declareShortcut ("scene-focus-toolbar", "Change focus in scene editor", QKeySequence(Qt::Key_T)); - declareShortcut ("scene-render-stats", "Displays debug rendering stats", QKeySequence(Qt::Key_F3)); + 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)); } void CSMPrefs::State::declareCategory (const std::string& key) @@ -484,6 +485,17 @@ void CSMPrefs::State::declareSeparator() 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_) { Settings::CategorySetting fullKey (mCurrentCategory->second.getKey(), key); diff --git a/apps/opencs/model/prefs/state.hpp b/apps/opencs/model/prefs/state.hpp index d65dc7d00..64927f881 100644 --- a/apps/opencs/model/prefs/state.hpp +++ b/apps/opencs/model/prefs/state.hpp @@ -82,6 +82,8 @@ namespace CSMPrefs void declareSeparator(); + void declareSubcategory(const std::string& label); + void setDefault (const std::string& key, const std::string& default_); public: diff --git a/apps/opencs/view/prefs/dialogue.cpp b/apps/opencs/view/prefs/dialogue.cpp index f04092653..6848bcaba 100644 --- a/apps/opencs/view/prefs/dialogue.cpp +++ b/apps/opencs/view/prefs/dialogue.cpp @@ -11,6 +11,7 @@ #include "../../model/prefs/state.hpp" #include "page.hpp" +#include "keybindingpage.hpp" 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) { // special case page code goes here - - return new Page (CSMPrefs::get()[key], mContent); + if (key == "Key Bindings") + return new KeyBindingPage(CSMPrefs::get()[key], mContent); + else + return new Page (CSMPrefs::get()[key], mContent); } CSVPrefs::Dialogue::Dialogue() diff --git a/apps/opencs/view/prefs/keybindingpage.cpp b/apps/opencs/view/prefs/keybindingpage.cpp new file mode 100644 index 000000000..63b196831 --- /dev/null +++ b/apps/opencs/view/prefs/keybindingpage.cpp @@ -0,0 +1,89 @@ +#include "keybindingpage.hpp" + +#include + +#include +#include +#include +#include +#include + +#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 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())); + } + } + } +} diff --git a/apps/opencs/view/prefs/keybindingpage.hpp b/apps/opencs/view/prefs/keybindingpage.hpp new file mode 100644 index 000000000..8a0cb2952 --- /dev/null +++ b/apps/opencs/view/prefs/keybindingpage.hpp @@ -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