From 8d17221ebc9fa936acf3b780551ce82ec0de5065 Mon Sep 17 00:00:00 2001 From: codereader Date: Sun, 13 Sep 2020 16:41:54 +0200 Subject: [PATCH] #5200: Move UI-related toggle state code from RadiantSelectionSystem to the UI module. Fix a bug in RadiantSelectionSystem::getManipulatorIdForType. --- include/iselection.h | 2 + radiant/ui/ManipulatorToggle.h | 67 ++++++++++++++++ radiant/ui/UserInterfaceModule.cpp | 2 + radiant/ui/UserInterfaceModule.h | 2 + .../selection/RadiantSelectionSystem.cpp | 76 ++++++++++++++----- .../selection/RadiantSelectionSystem.h | 8 +- tools/msvc/DarkRadiant.vcxproj | 1 + tools/msvc/DarkRadiant.vcxproj.filters | 3 + 8 files changed, 140 insertions(+), 21 deletions(-) create mode 100644 radiant/ui/ManipulatorToggle.h diff --git a/include/iselection.h b/include/iselection.h index 19e8113d9b..cf72b5b5c1 100644 --- a/include/iselection.h +++ b/include/iselection.h @@ -184,6 +184,8 @@ class SelectionSystem : virtual void setActiveManipulator(std::size_t manipulatorId) = 0; virtual void setActiveManipulator(selection::Manipulator::Type manipulatorType) = 0; + virtual sigc::signal& signal_activeManipulatorChanged() = 0; + virtual const SelectionInfo& getSelectionInfo() = 0; virtual void SetMode(EMode mode) = 0; diff --git a/radiant/ui/ManipulatorToggle.h b/radiant/ui/ManipulatorToggle.h new file mode 100644 index 0000000000..8a9f0d7856 --- /dev/null +++ b/radiant/ui/ManipulatorToggle.h @@ -0,0 +1,67 @@ +#pragma once + +#include "iselection.h" +#include + +namespace ui +{ + +// Adaptor class connecting the EventSystem toggles covering the +// various SelectionSystem manipulator mode to the actual state +// of the backend RadiantSelectionSystem. +class ManipulatorToggle +{ +private: + sigc::connection _activeManipulatorChanged; + +public: + ManipulatorToggle() + { + _activeManipulatorChanged = GlobalSelectionSystem().signal_activeManipulatorChanged() + .connect(sigc::mem_fun(this, &ManipulatorToggle::onActiveManipulatorChanged)); + + GlobalEventManager().addToggle("ToggleClipper", [this](bool) + { + GlobalCommandSystem().executeCommand("ToggleManipulatorMode", { "Clip" }); + }); + + GlobalEventManager().addToggle("MouseTranslate", [this](bool) + { + GlobalCommandSystem().executeCommand("ToggleManipulatorMode", { "Translate" }); + }); + + GlobalEventManager().addToggle("MouseRotate", [this](bool) + { + GlobalCommandSystem().executeCommand("ToggleManipulatorMode", { "Rotate" }); + }); + + GlobalEventManager().addToggle("MouseDrag", [this](bool) + { + GlobalCommandSystem().executeCommand("ToggleManipulatorMode", { "Drag" }); + }); + + GlobalEventManager().addToggle("ToggleModelScaleManipulator", [this](bool) + { + GlobalCommandSystem().executeCommand("ToggleManipulatorMode", { "ModelScale" }); + }); + + onActiveManipulatorChanged(GlobalSelectionSystem().getActiveManipulatorType()); + } + + ~ManipulatorToggle() + { + _activeManipulatorChanged.disconnect(); + } + +private: + void onActiveManipulatorChanged(selection::Manipulator::Type type) + { + GlobalEventManager().setToggled("ToggleClipper", GlobalClipper().clipMode()); + GlobalEventManager().setToggled("MouseTranslate", type == selection::Manipulator::Translate); + GlobalEventManager().setToggled("MouseRotate", type == selection::Manipulator::Rotate); + GlobalEventManager().setToggled("MouseDrag", type == selection::Manipulator::Drag); + GlobalEventManager().setToggled("ToggleModelScaleManipulator", type == selection::Manipulator::ModelScale); + } +}; + +} diff --git a/radiant/ui/UserInterfaceModule.cpp b/radiant/ui/UserInterfaceModule.cpp index 584c24a76c..445449ac5c 100644 --- a/radiant/ui/UserInterfaceModule.cpp +++ b/radiant/ui/UserInterfaceModule.cpp @@ -210,6 +210,7 @@ void UserInterfaceModule::initialiseModule(const IApplicationContext& ctx) _mruMenu.reset(new MRUMenu); _shaderClipboardStatus.reset(new ShaderClipboardStatus); _editStopwatchStatus.reset(new EditingStopwatchStatus); + _manipulatorToggle.reset(new ManipulatorToggle); MouseToolRegistrationHelper::RegisterTools(); @@ -234,6 +235,7 @@ void UserInterfaceModule::shutdownModule() _autoSaveRequestHandler.reset(); _shaderClipboardStatus.reset(); _editStopwatchStatus.reset(); + _manipulatorToggle.reset(); _mruMenu.reset(); } diff --git a/radiant/ui/UserInterfaceModule.h b/radiant/ui/UserInterfaceModule.h index a43f512d61..fea9e813a3 100644 --- a/radiant/ui/UserInterfaceModule.h +++ b/radiant/ui/UserInterfaceModule.h @@ -12,6 +12,7 @@ #include "FileSelectionRequestHandler.h" #include "AutoSaveRequestHandler.h" #include "MapFileProgressHandler.h" +#include "ManipulatorToggle.h" #include "shaderclipboard/ShaderClipboardStatus.h" #include "statusbar/EditingStopwatchStatus.h" #include "messages/CommandExecutionFailed.h" @@ -42,6 +43,7 @@ class UserInterfaceModule : std::unique_ptr _fileSelectionRequestHandler; std::unique_ptr _shaderClipboardStatus; std::unique_ptr _editStopwatchStatus; + std::unique_ptr _manipulatorToggle; sigc::connection _entitySettingsConn; sigc::connection _coloursUpdatedConn; diff --git a/radiantcore/selection/RadiantSelectionSystem.cpp b/radiantcore/selection/RadiantSelectionSystem.cpp index beff8b9caa..e3f1ea6a1d 100644 --- a/radiantcore/selection/RadiantSelectionSystem.cpp +++ b/radiantcore/selection/RadiantSelectionSystem.cpp @@ -295,6 +295,11 @@ void RadiantSelectionSystem::setActiveManipulator(Manipulator::Type manipulatorT rError() << "Cannot activate non-existent manipulator by type " << manipulatorType << std::endl; } +sigc::signal& RadiantSelectionSystem::signal_activeManipulatorChanged() +{ + return _sigActiveManipulatorChanged; +} + // return the number of selected primitives std::size_t RadiantSelectionSystem::countSelected() const { return _countPrimitive; @@ -1090,12 +1095,8 @@ void RadiantSelectionSystem::initialiseModule(const IApplicationContext& ctx) sigc::mem_fun(this, &RadiantSelectionSystem::pivotChanged) ); - GlobalEventManager().addToggle("ToggleClipper", std::bind(&RadiantSelectionSystem::toggleManipulatorMode, this, Manipulator::Clip, std::placeholders::_1)); - GlobalEventManager().addToggle("MouseTranslate", std::bind(&RadiantSelectionSystem::toggleManipulatorMode, this, Manipulator::Translate, std::placeholders::_1)); - GlobalEventManager().addToggle("MouseRotate", std::bind(&RadiantSelectionSystem::toggleManipulatorMode, this, Manipulator::Rotate, std::placeholders::_1)); - GlobalEventManager().addToggle("MouseDrag", std::bind(&RadiantSelectionSystem::toggleManipulatorMode, this, Manipulator::Drag, std::placeholders::_1)); - GlobalEventManager().addToggle("ToggleModelScaleManipulator", std::bind(&RadiantSelectionSystem::toggleManipulatorMode, this, Manipulator::ModelScale, std::placeholders::_1)); - GlobalEventManager().setToggled("MouseDrag", true); + GlobalCommandSystem().addCommand("ToggleManipulatorMode", + std::bind(&RadiantSelectionSystem::toggleManipulatorModeCmd, this, std::placeholders::_1), { cmd::ARGTYPE_STRING }); GlobalEventManager().addToggle("DragVertices", std::bind(&RadiantSelectionSystem::toggleComponentMode, this, eVertex, std::placeholders::_1)); GlobalEventManager().addToggle("DragEdges", std::bind(&RadiantSelectionSystem::toggleComponentMode, this, eEdge, std::placeholders::_1)); @@ -1166,7 +1167,7 @@ std::size_t RadiantSelectionSystem::getManipulatorIdForType(Manipulator::Type ty { for (const Manipulators::value_type& pair : _manipulators) { - if (pair.second->getType() == _defaultManipulatorType) + if (pair.second->getType() == type) { return pair.first; } @@ -1175,7 +1176,7 @@ std::size_t RadiantSelectionSystem::getManipulatorIdForType(Manipulator::Type ty return 0; } -void RadiantSelectionSystem::toggleManipulatorModeById(std::size_t manipId, bool newState) +void RadiantSelectionSystem::toggleManipulatorModeById(std::size_t manipId) { std::size_t defaultManipId = getManipulatorIdForType(_defaultManipulatorType); @@ -1187,7 +1188,7 @@ void RadiantSelectionSystem::toggleManipulatorModeById(std::size_t manipId, bool // Switch back to the default mode if we're already in if (_activeManipulator->getId() == manipId && defaultManipId != manipId) { - toggleManipulatorModeById(defaultManipId, true); + toggleManipulatorModeById(defaultManipId); } else // we're not in yet { @@ -1209,12 +1210,55 @@ void RadiantSelectionSystem::toggleManipulatorModeById(std::size_t manipId, bool } } -void RadiantSelectionSystem::toggleManipulatorMode(Manipulator::Type type, bool newState) +void RadiantSelectionSystem::toggleManipulatorModeCmd(const cmd::ArgumentList& args) +{ + if (args.size() != 1) + { + rWarning() << "Usage: ToggleManipulatorMode " << std::endl; + rWarning() << " with being one of the following: " << std::endl; + rWarning() << " Drag" << std::endl; + rWarning() << " Translate" << std::endl; + rWarning() << " Rotate" << std::endl; + rWarning() << " Scale" << std::endl; + rWarning() << " Clip" << std::endl; + rWarning() << " ModelScale" << std::endl; + return; + } + + auto manip = args[0].getString(); + + if (manip == "Drag") + { + toggleManipulatorModeById(getManipulatorIdForType(Manipulator::Drag)); + } + else if (manip == "Translate") + { + toggleManipulatorModeById(getManipulatorIdForType(Manipulator::Translate)); + } + else if (manip == "Rotate") + { + toggleManipulatorModeById(getManipulatorIdForType(Manipulator::Rotate)); + } + else if (manip == "Scale") + { + toggleManipulatorModeById(getManipulatorIdForType(Manipulator::Drag)); + } + else if (manip == "Clip") + { + toggleManipulatorModeById(getManipulatorIdForType(Manipulator::Clip)); + } + else if (manip == "ModelScale") + { + toggleManipulatorModeById(getManipulatorIdForType(Manipulator::ModelScale)); + } +} + +void RadiantSelectionSystem::toggleManipulatorMode(Manipulator::Type type) { // Switch back to the default mode if we're already in if (_activeManipulator->getType() == type && _defaultManipulatorType != type) { - toggleManipulatorMode(_defaultManipulatorType, true); + toggleManipulatorMode(_defaultManipulatorType); } else // we're not in yet { @@ -1254,7 +1298,7 @@ void RadiantSelectionSystem::toggleComponentMode(EComponentMode mode, bool newSt { if (!_activeManipulator->supportsComponentManipulation()) { - toggleManipulatorMode(_defaultManipulatorType, true); + toggleManipulatorMode(_defaultManipulatorType); } SetMode(eComponent); @@ -1326,13 +1370,7 @@ void RadiantSelectionSystem::toggleGroupPartMode(bool newState) void RadiantSelectionSystem::onManipulatorModeChanged() { - GlobalEventManager().setToggled("ToggleClipper", GlobalClipper().clipMode()); - - GlobalEventManager().setToggled("MouseTranslate", _activeManipulator->getType() == Manipulator::Translate); - GlobalEventManager().setToggled("MouseRotate", _activeManipulator->getType() == Manipulator::Rotate); - GlobalEventManager().setToggled("MouseDrag", _activeManipulator->getType() == Manipulator::Drag); - GlobalEventManager().setToggled("ToggleModelScaleManipulator", _activeManipulator->getType() == Manipulator::ModelScale); - + _sigActiveManipulatorChanged.emit(getActiveManipulatorType()); SceneChangeNotify(); } diff --git a/radiantcore/selection/RadiantSelectionSystem.h b/radiantcore/selection/RadiantSelectionSystem.h index 4f278fd5a5..ab769124aa 100644 --- a/radiantcore/selection/RadiantSelectionSystem.h +++ b/radiantcore/selection/RadiantSelectionSystem.h @@ -68,6 +68,8 @@ class RadiantSelectionSystem : bool nothingSelected() const; + sigc::signal _sigActiveManipulatorChanged; + public: RadiantSelectionSystem(); @@ -101,6 +103,7 @@ class RadiantSelectionSystem : const ManipulatorPtr& getActiveManipulator() override; void setActiveManipulator(std::size_t manipulatorId) override; void setActiveManipulator(Manipulator::Type manipulatorType) override; + sigc::signal& signal_activeManipulatorChanged() override; std::size_t countSelected() const override; std::size_t countSelectedComponents() const override; @@ -181,8 +184,9 @@ class RadiantSelectionSystem : std::size_t getManipulatorIdForType(Manipulator::Type type); // Command targets used to connect to the event system - void toggleManipulatorMode(Manipulator::Type type, bool newState); - void toggleManipulatorModeById(std::size_t manipId, bool newState); + void toggleManipulatorModeCmd(const cmd::ArgumentList& args); + void toggleManipulatorMode(Manipulator::Type type); + void toggleManipulatorModeById(std::size_t manipId); void activateDefaultMode(); diff --git a/tools/msvc/DarkRadiant.vcxproj b/tools/msvc/DarkRadiant.vcxproj index 82455976c6..b3e780ec49 100644 --- a/tools/msvc/DarkRadiant.vcxproj +++ b/tools/msvc/DarkRadiant.vcxproj @@ -448,6 +448,7 @@ + diff --git a/tools/msvc/DarkRadiant.vcxproj.filters b/tools/msvc/DarkRadiant.vcxproj.filters index 4d36279fed..475610dfd5 100644 --- a/tools/msvc/DarkRadiant.vcxproj.filters +++ b/tools/msvc/DarkRadiant.vcxproj.filters @@ -1290,6 +1290,9 @@ src + + src\ui +