From 12e794a78d2ae14aad999b8596d2e34558575a88 Mon Sep 17 00:00:00 2001 From: codereader Date: Sun, 10 Oct 2021 13:21:51 +0200 Subject: [PATCH] #5776: Rotation manipulator buttons --- install/ui/texturetoolmanipulationpanel.fbp | 407 ++++++++++++++++++ install/ui/texturetoolmanipulationpanel.xrc | 74 ++++ install/user.xml | 1 + radiant/textool/TexTool.cpp | 17 + radiant/textool/TexTool.h | 1 + .../textool/TextureToolSelectionSystem.cpp | 34 ++ .../textool/TextureToolSelectionSystem.h | 1 + 7 files changed, 535 insertions(+) diff --git a/install/ui/texturetoolmanipulationpanel.fbp b/install/ui/texturetoolmanipulationpanel.fbp index 4d28b88d34..1868f28ca3 100644 --- a/install/ui/texturetoolmanipulationpanel.fbp +++ b/install/ui/texturetoolmanipulationpanel.fbp @@ -1178,6 +1178,413 @@ + + 8 + wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP + 0 + + + bSizer221 + wxVERTICAL + none + + 6 + wxALIGN_CENTER|wxBOTTOM + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Rotate + 0 + + 0 + + + 0 + + 1 + RotateLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 6 + wxALIGN_CENTER|wxBOTTOM + 0 + + + bSizer2112 + wxHORIZONTAL + none + + 0 + wxALIGN_CENTER|wxBOTTOM + 0 + + 1 + 1 + 1 + 1 + + + + + + + Load From Art Provider; darkradiant:arrow_left_blue.png; + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + MyButton + + 0 + + 0 + + + 0 + + 1 + RotateClockWiseButton + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 6 + wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + Load From Art Provider; darkradiant:arrow_right_blue.png; + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + MyButton + + 0 + + 0 + + + 0 + + 1 + RotateCounterClockWiseButton + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 6 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + 0 + 999 + + 0 + -1,60 + 1 + + 0 + + 1 + RotateAngle + 1 + + + protected + 1 + + Resizable + 1 + 60,-1 + wxSP_ARROW_KEYS + ; ; forward_declare + 0 + + + + + + + + + 3 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + ° + 0 + + 0 + + + 0 + + 1 + m_staticText42 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + + + + + 0 + wxEXPAND | wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + 48,48,48 + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + + 1 + + 0 + 0 + wxID_ANY + + 0 + -1,1 + + 0 + + 1 + m_panel111 + 1 + + + protected + 1 + + Resizable + 1 + -1,1 + ; ; forward_declare + 0 + + + + + + diff --git a/install/ui/texturetoolmanipulationpanel.xrc b/install/ui/texturetoolmanipulationpanel.xrc index 2176140576..91d712760c 100644 --- a/install/ui/texturetoolmanipulationpanel.xrc +++ b/install/ui/texturetoolmanipulationpanel.xrc @@ -205,6 +205,80 @@ 0 + + + wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP + 8 + + wxVERTICAL + + + wxALIGN_CENTER|wxBOTTOM + 6 + + + -1 + + + + + wxALIGN_CENTER|wxBOTTOM + 6 + + wxHORIZONTAL + + + wxALIGN_CENTER|wxBOTTOM + 0 + + undefined.png + 0 + + + + + wxLEFT + 6 + + undefined.png + 0 + + + + + wxALIGN_CENTER_VERTICAL|wxLEFT + 6 + + + 60,-1 + 0 + 1 + 999 + + + + + wxALIGN_CENTER_VERTICAL|wxLEFT + 3 + + + -1 + + + + + + + + + wxEXPAND | wxALL + 0 + + -1,1 + #303030 + 0 + + diff --git a/install/user.xml b/install/user.xml index b9105cc733..13392f1424 100644 --- a/install/user.xml +++ b/install/user.xml @@ -116,6 +116,7 @@ + diff --git a/radiant/textool/TexTool.cpp b/radiant/textool/TexTool.cpp index a3c3bd9d91..4a55822339 100644 --- a/radiant/textool/TexTool.cpp +++ b/radiant/textool/TexTool.cpp @@ -42,6 +42,7 @@ namespace const std::string RKEY_HSCALE_FACTOR = RKEY_TEXTOOL_ROOT + "horizontalScaleFactor"; const std::string RKEY_VSCALE_FACTOR = RKEY_TEXTOOL_ROOT + "verticalScaleFactor"; + const std::string RKEY_ROTATE_ANGLE = RKEY_TEXTOOL_ROOT + "rotateAngle"; constexpr const float ZOOM_MODIFIER = 1.25f; } @@ -129,6 +130,7 @@ wxWindow* TexTool::createManipulationPanel() makeLabelBold(panel, "ShiftLabel"); makeLabelBold(panel, "ScaleLabel"); + makeLabelBold(panel, "RotateLabel"); findNamedObject(panel, "ShiftUpButton")->Bind(wxEVT_BUTTON, [this] (wxCommandEvent&) { onShiftSelected("up"); }); findNamedObject(panel, "ShiftDownButton")->Bind(wxEVT_BUTTON, [this] (wxCommandEvent&) { onShiftSelected("down"); }); @@ -140,11 +142,16 @@ wxWindow* TexTool::createManipulationPanel() findNamedObject(panel, "ScaleVertSmallerButton")->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { onScaleSelected("down"); }); findNamedObject(panel, "ScaleVertLargerButton")->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { onScaleSelected("up"); }); + findNamedObject(panel, "RotateClockWiseButton")->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { onRotateSelected("cw"); }); + findNamedObject(panel, "RotateCounterClockWiseButton")->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { onRotateSelected("ccw"); }); + convertToSpinCtrlDouble(panel, "HorizScaleFactor", 0.1, 1000, 0.5, 1); convertToSpinCtrlDouble(panel, "VertScaleFactor", 0.1, 1000, 0.5, 1); + convertToSpinCtrlDouble(panel, "RotateAngle", 0, 360, 0.5, 1); registry::bindWidget(findNamedObject(panel, "HorizScaleFactor"), RKEY_HSCALE_FACTOR); registry::bindWidget(findNamedObject(panel, "VertScaleFactor"), RKEY_VSCALE_FACTOR); + registry::bindWidget(findNamedObject(panel, "RotateAngle"), RKEY_ROTATE_ANGLE); return panel; } @@ -798,6 +805,8 @@ void TexTool::onMouseUp(wxMouseEvent& ev) void TexTool::onMouseDown(wxMouseEvent& ev) { + _glWidget->SetFocus(); + // Send the event to the mouse tool handler MouseToolHandler::onGLMouseButtonPress(ev); @@ -1019,6 +1028,14 @@ void TexTool::onScaleSelected(const std::string& direction) GlobalCommandSystem().executeCommand("TexToolScaleSelected", scale); } +void TexTool::onRotateSelected(const std::string& direction) +{ + double angle = findNamedObject(this, "RotateAngle")->GetValue(); + angle *= direction == "cw" ? -1 : +1; + + GlobalCommandSystem().executeCommand("TexToolRotateSelected", angle); +} + void TexTool::updateManipulationPanel() { diff --git a/radiant/textool/TexTool.h b/radiant/textool/TexTool.h index a206a56ce4..37c7370f53 100644 --- a/radiant/textool/TexTool.h +++ b/radiant/textool/TexTool.h @@ -137,6 +137,7 @@ class TexTool : void onShiftSelected(const std::string& direction); void onScaleSelected(const std::string& direction); + void onRotateSelected(const std::string& direction); // UndoSystem event handler void onUndoRedoOperation(); diff --git a/radiantcore/selection/textool/TextureToolSelectionSystem.cpp b/radiantcore/selection/textool/TextureToolSelectionSystem.cpp index e55dec92e6..d41d7574ac 100644 --- a/radiantcore/selection/textool/TextureToolSelectionSystem.cpp +++ b/radiantcore/selection/textool/TextureToolSelectionSystem.cpp @@ -63,6 +63,9 @@ void TextureToolSelectionSystem::initialiseModule(const IApplicationContext& ctx GlobalCommandSystem().addCommand("TexToolScaleSelected", std::bind(&TextureToolSelectionSystem::scaleSelectionCmd, this, std::placeholders::_1), { cmd::ARGTYPE_VECTOR2 }); + GlobalCommandSystem().addCommand("TexToolRotateSelected", + std::bind(&TextureToolSelectionSystem::rotateSelectionCmd, this, std::placeholders::_1), + { cmd::ARGTYPE_DOUBLE }); GlobalCommandSystem().addCommand("TexToolFlipS", std::bind(&TextureToolSelectionSystem::flipHorizontallyCmd, this, std::placeholders::_1)); @@ -815,6 +818,37 @@ void TextureToolSelectionSystem::scaleSelectionCmd(const cmd::ArgumentList& args foreachSelectedNode(scaler); } +void TextureToolSelectionSystem::rotateSelectionCmd(const cmd::ArgumentList& args) +{ + if (getSelectionMode() != SelectionMode::Surface) + { + rWarning() << "This command can only be executed in Surface manipulation mode" << std::endl; + return; + } + + UndoableCommand cmd("rotateTexcoords"); + + if (args.size() < 1) + { + return; + } + + auto angle = degrees_to_radians(args[0].getDouble()); + + // Calculate the center based on the selection + selection::algorithm::TextureBoundsAccumulator accumulator; + foreachSelectedNode(accumulator); + + if (!accumulator.getBounds().isValid()) + { + return; + } + + Vector2 pivot{ accumulator.getBounds().origin.x(), accumulator.getBounds().origin.y() }; + selection::algorithm::TextureRotator rotator(pivot, angle); + foreachSelectedNode(rotator); +} + module::StaticModule _textureToolSelectionSystemModule; } diff --git a/radiantcore/selection/textool/TextureToolSelectionSystem.h b/radiantcore/selection/textool/TextureToolSelectionSystem.h index df73547284..e5215960fa 100644 --- a/radiantcore/selection/textool/TextureToolSelectionSystem.h +++ b/radiantcore/selection/textool/TextureToolSelectionSystem.h @@ -95,6 +95,7 @@ class TextureToolSelectionSystem : void normaliseSelectionCmd(const cmd::ArgumentList& args); void shiftSelectionCmd(const cmd::ArgumentList& args); void scaleSelectionCmd(const cmd::ArgumentList& args); + void rotateSelectionCmd(const cmd::ArgumentList& args); void flipSelected(int axis); void performSelectionTest(Selector& selector, SelectionTest& test);