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 e520c2c9b16..c365d156209 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 e3664f26b3b..218d54322e8 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 a0e3e601f49..9ac6fb61691 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 7a9430794f5..b48744f84cf 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 }; };