From ecc202c59dffe3ba26ff953e94c5589efc993fc9 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Thu, 12 Jan 2023 19:49:03 +0000 Subject: [PATCH] PixelPaint: Hold shift to constrain polygonal select tool line angle Holding shift while using the polygonal select tool now constrains the line angle in 22.5 degree increments. This matches the behavior of the line tool. --- .../PixelPaint/Tools/LineTool.cpp | 21 +++---------------- .../PixelPaint/Tools/PolygonalSelectTool.cpp | 10 ++++++++- .../Applications/PixelPaint/Tools/Tool.cpp | 13 ++++++++++++ Userland/Applications/PixelPaint/Tools/Tool.h | 2 ++ 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Userland/Applications/PixelPaint/Tools/LineTool.cpp b/Userland/Applications/PixelPaint/Tools/LineTool.cpp index e520c2c9b1..c365d15620 100644 --- a/Userland/Applications/PixelPaint/Tools/LineTool.cpp +++ b/Userland/Applications/PixelPaint/Tools/LineTool.cpp @@ -22,19 +22,6 @@ namespace PixelPaint { -static Gfx::IntPoint constrain_line_angle(Gfx::IntPoint start_pos, Gfx::IntPoint end_pos, float angle_increment) -{ - float current_angle = AK::atan2(end_pos.y() - start_pos.y(), end_pos.x() - start_pos.x()) + float { M_PI * 2 }; - - float constrained_angle = ((int)((current_angle + angle_increment / 2) / angle_increment)) * angle_increment; - - auto diff = end_pos - start_pos; - float line_length = AK::hypot(diff.x(), diff.y()); - - return { start_pos.x() + (int)(AK::cos(constrained_angle) * line_length), - start_pos.y() + (int)(AK::sin(constrained_angle) * line_length) }; -} - void LineTool::on_mousedown(Layer* layer, MouseEvent& event) { if (!layer) @@ -95,12 +82,10 @@ void LineTool::on_mousemove(Layer* layer, MouseEvent& event) if (m_drawing_button == GUI::MouseButton::None) return; - if (layer_event.shift()) { - constexpr auto ANGLE_STEP = M_PI / 8; - m_line_end_position = constrain_line_angle(m_drag_start_position, layer_event.position(), ANGLE_STEP); - } else { + if (layer_event.shift()) + m_line_end_position = constrain_line_angle(m_drag_start_position, layer_event.position()); + else m_line_end_position = layer_event.position(); - } if (layer_event.alt()) { m_line_start_position = m_drag_start_position + (m_drag_start_position - m_line_end_position); diff --git a/Userland/Applications/PixelPaint/Tools/PolygonalSelectTool.cpp b/Userland/Applications/PixelPaint/Tools/PolygonalSelectTool.cpp index e3664f26b3..218d54322e 100644 --- a/Userland/Applications/PixelPaint/Tools/PolygonalSelectTool.cpp +++ b/Userland/Applications/PixelPaint/Tools/PolygonalSelectTool.cpp @@ -92,6 +92,8 @@ void PolygonalSelectTool::on_mousedown(Layer*, MouseEvent& event) m_selecting = true; auto new_point = event.layer_event().position(); + if (!m_polygon_points.is_empty() && event.layer_event().shift()) + new_point = Tool::constrain_line_angle(m_polygon_points.last(), new_point); // This point matches the first point exactly. Consider this polygon finished. if (m_polygon_points.size() > 0 && new_point == m_polygon_points.at(0)) { @@ -115,8 +117,14 @@ void PolygonalSelectTool::on_mousedown(Layer*, MouseEvent& event) void PolygonalSelectTool::on_mousemove(Layer*, MouseEvent& event) { - if (m_selecting) + if (!m_selecting) + return; + + if (event.layer_event().shift()) + m_last_selecting_cursor_position = Tool::constrain_line_angle(m_polygon_points.last(), event.layer_event().position()); + else m_last_selecting_cursor_position = event.layer_event().position(); + m_editor->update(); } diff --git a/Userland/Applications/PixelPaint/Tools/Tool.cpp b/Userland/Applications/PixelPaint/Tools/Tool.cpp index a0e3e601f4..9ac6fb6169 100644 --- a/Userland/Applications/PixelPaint/Tools/Tool.cpp +++ b/Userland/Applications/PixelPaint/Tools/Tool.cpp @@ -70,4 +70,17 @@ Gfx::IntPoint Tool::editor_stroke_position(Gfx::IntPoint pixel_coords, int strok return position.to_type(); } +Gfx::IntPoint Tool::constrain_line_angle(Gfx::IntPoint start_pos, Gfx::IntPoint end_pos, float angle_increment) +{ + float current_angle = AK::atan2(end_pos.y() - start_pos.y(), end_pos.x() - start_pos.x()) + float { M_PI * 2 }; + + float constrained_angle = ((int)((current_angle + angle_increment / 2) / angle_increment)) * angle_increment; + + auto diff = end_pos - start_pos; + float line_length = AK::hypot(diff.x(), diff.y()); + + return { start_pos.x() + (int)(AK::cos(constrained_angle) * line_length), + start_pos.y() + (int)(AK::sin(constrained_angle) * line_length) }; +} + } diff --git a/Userland/Applications/PixelPaint/Tools/Tool.h b/Userland/Applications/PixelPaint/Tools/Tool.h index 7a9430794f..b48744f84c 100644 --- a/Userland/Applications/PixelPaint/Tools/Tool.h +++ b/Userland/Applications/PixelPaint/Tools/Tool.h @@ -95,6 +95,8 @@ protected: void set_primary_slider(GUI::ValueSlider* primary) { m_primary_slider = primary; } void set_secondary_slider(GUI::ValueSlider* secondary) { m_secondary_slider = secondary; } + static Gfx::IntPoint constrain_line_angle(Gfx::IntPoint start_pos, Gfx::IntPoint end_pos, float angle_increment = M_PI / 8); + GUI::ValueSlider* m_primary_slider { nullptr }; GUI::ValueSlider* m_secondary_slider { nullptr }; };