From eaea0869444fccec9809187393cc63236aefee75 Mon Sep 17 00:00:00 2001 From: codereader Date: Fri, 17 Sep 2021 20:44:36 +0200 Subject: [PATCH] #5746: Point and area selection algorithms implemented into TextureToolSelectionSystem, modeled after the one in RadiantSelectionSystem - code is a bit redundant at this point --- include/itexturetoolmodel.h | 3 + include/itexturetoolview.h | 3 - radiant/textool/TexTool.cpp | 38 ---------- radiant/textool/TexTool.h | 1 - .../textool/tools/TextureToolSelectionTool.h | 10 ++- .../textool/TextureToolSelectionSystem.cpp | 75 +++++++++++++++++++ .../textool/TextureToolSelectionSystem.h | 3 + 7 files changed, 90 insertions(+), 43 deletions(-) diff --git a/include/itexturetoolmodel.h b/include/itexturetoolmodel.h index 54cc5d6e1c..bf008da871 100644 --- a/include/itexturetoolmodel.h +++ b/include/itexturetoolmodel.h @@ -88,6 +88,9 @@ class ITextureToolSelectionSystem : // Collection should not be modified during iteration virtual void foreachSelectedNode(const std::function& functor) = 0; + virtual void selectPoint(SelectionTest& test, SelectionSystem::EModifier modifier) = 0; + virtual void selectArea(SelectionTest& test, SelectionSystem::EModifier modifier) = 0; + // Returns the ID of the registered manipulator virtual std::size_t registerManipulator(const selection::ITextureToolManipulator::Ptr& manipulator) = 0; virtual void unregisterManipulator(const selection::ITextureToolManipulator::Ptr& manipulator) = 0; diff --git a/include/itexturetoolview.h b/include/itexturetoolview.h index 31659813e0..6d1e1bc529 100644 --- a/include/itexturetoolview.h +++ b/include/itexturetoolview.h @@ -12,9 +12,6 @@ class ITextureToolView : { public: virtual ~ITextureToolView() {} - - // Perform a selection test using the given test instance - virtual void testSelect(SelectionTest& test) = 0; }; } diff --git a/radiant/textool/TexTool.cpp b/radiant/textool/TexTool.cpp index 8e8bc92fd6..2544ae565f 100644 --- a/radiant/textool/TexTool.cpp +++ b/radiant/textool/TexTool.cpp @@ -354,44 +354,6 @@ void TexTool::scrollByPixels(int x, int y) updateProjection(); } -void TexTool::testSelect(SelectionTest& test) -{ - textool::TexToolItemVec selectables; - selection::SelectionPool selectionPool; - - GlobalTextureToolSceneGraph().foreachNode([&](const textool::INode::Ptr& node) - { - node->testSelect(selectionPool, test); - return true; - }); - -#if 0 - // Cycle through all the toplevel items and test them for selectability - for (const auto& item : _items) - { - item->testSelect(selectionPool, test); - } - - // Cycle through all the items and ask them to deliver the list of child selectables - // residing within the test rectangle - for (const auto& item : _items) - { - // Get the list from each item - auto found = item->getSelectableChildren(rectangle); - - // and append the vector to the existing vector - selectables.insert(selectables.end(), found.begin(), found.end()); - } -#endif - -#if 1 - if (selectionPool.empty()) return; - - auto bestSelectable = *selectionPool.begin(); - bestSelectable.second->setSelected(true); -#endif -} - void TexTool::flipSelected(int axis) { if (countSelected() > 0) { beginOperation(); diff --git a/radiant/textool/TexTool.h b/radiant/textool/TexTool.h index 3af20efa7e..b91581aab0 100644 --- a/radiant/textool/TexTool.h +++ b/radiant/textool/TexTool.h @@ -225,7 +225,6 @@ class TexTool : void forceRedraw() override; void scrollByPixels(int x, int y) override; - void testSelect(SelectionTest& test) override; /** greebo: Updates the GL window */ diff --git a/radiant/textool/tools/TextureToolSelectionTool.h b/radiant/textool/tools/TextureToolSelectionTool.h index a5279460ba..731a4c251f 100644 --- a/radiant/textool/tools/TextureToolSelectionTool.h +++ b/radiant/textool/tools/TextureToolSelectionTool.h @@ -1,6 +1,7 @@ #pragma once #include "i18n.h" +#include "itexturetoolmodel.h" #include "math/Vector2.h" #include "selection/SelectionMouseTools.h" #include "selection/SelectionVolume.h" @@ -36,7 +37,14 @@ class TextureToolSelectionTool : auto mouseEvent = dynamic_cast(&ev); if (mouseEvent == nullptr) return; - mouseEvent->getView().testSelect(volume); + if (type == SelectionType::Area) + { + GlobalTextureToolSelectionSystem().selectArea(volume, SelectionSystem::eToggle); + } + else + { + GlobalTextureToolSelectionSystem().selectPoint(volume, SelectionSystem::eToggle); + } } }; diff --git a/radiantcore/selection/textool/TextureToolSelectionSystem.cpp b/radiantcore/selection/textool/TextureToolSelectionSystem.cpp index 9dcb24a0fe..b98f10ef98 100644 --- a/radiantcore/selection/textool/TextureToolSelectionSystem.cpp +++ b/radiantcore/selection/textool/TextureToolSelectionSystem.cpp @@ -3,6 +3,7 @@ #include "itextstream.h" #include "module/StaticModule.h" #include "../textool/TextureToolRotateManipulator.h" +#include "selection/SelectionPool.h" namespace textool { @@ -178,6 +179,80 @@ sigc::signal& TextureToolSelectionSystem::s return _sigActiveManipulatorChanged; } +void TextureToolSelectionSystem::selectPoint(SelectionTest& test, SelectionSystem::EModifier modifier) +{ + selection::SelectionPool selectionPool; + + GlobalTextureToolSceneGraph().foreachNode([&](const INode::Ptr& node) + { + node->testSelect(selectionPool, test); + return true; + }); + + if (selectionPool.empty()) return; + + auto bestSelectable = *selectionPool.begin(); + + switch (modifier) + { + case SelectionSystem::eToggle: + bestSelectable.second->setSelected(!bestSelectable.second->isSelected()); + break; + + case SelectionSystem::eReplace: + bestSelectable.second->setSelected(bestSelectable.second->isSelected()); + break; + + case SelectionSystem::eCycle: + { + // Cycle through the selection pool and activate the item right after the currently selected + auto i = selectionPool.begin(); + + while (i != selectionPool.end()) + { + if (i->second->isSelected()) + { + // unselect the currently selected one + i->second->setSelected(false); + + // check if there is a "next" item in the list, if not: select the first item + ++i; + + if (i != selectionPool.end()) + { + i->second->setSelected(true); + } + else + { + selectionPool.begin()->second->setSelected(true); + } + break; + } + + ++i; + } + } + break; + } + +} + +void TextureToolSelectionSystem::selectArea(SelectionTest& test, SelectionSystem::EModifier modifier) +{ + selection::SelectionPool selectionPool; + + GlobalTextureToolSceneGraph().foreachNode([&](const INode::Ptr& node) + { + node->testSelect(selectionPool, test); + return true; + }); + + for (const auto& pair : selectionPool) + { + pair.second->setSelected(!pair.second->isSelected()); + } +} + module::StaticModule _textureToolSelectionSystemModule; } diff --git a/radiantcore/selection/textool/TextureToolSelectionSystem.h b/radiantcore/selection/textool/TextureToolSelectionSystem.h index 92c9d6e359..c7233a743a 100644 --- a/radiantcore/selection/textool/TextureToolSelectionSystem.h +++ b/radiantcore/selection/textool/TextureToolSelectionSystem.h @@ -28,6 +28,9 @@ class TextureToolSelectionSystem : void foreachSelectedNode(const std::function& functor) override; + void selectPoint(SelectionTest& test, SelectionSystem::EModifier modifier) override; + void selectArea(SelectionTest& test, SelectionSystem::EModifier modifier) override; + // Returns the ID of the registered manipulator std::size_t registerManipulator(const selection::ITextureToolManipulator::Ptr& manipulator) override; void unregisterManipulator(const selection::ITextureToolManipulator::Ptr& manipulator) override;