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.
This commit is contained in:
Tim Ledbetter 2023-01-12 19:49:03 +00:00 committed by Jelle Raaijmakers
parent 569ef94228
commit ecc202c59d
Notes: sideshowbarker 2024-07-18 00:34:07 +09:00
4 changed files with 27 additions and 19 deletions

View file

@ -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<float>(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<float>(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);

View file

@ -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();
}

View file

@ -70,4 +70,17 @@ Gfx::IntPoint Tool::editor_stroke_position(Gfx::IntPoint pixel_coords, int strok
return position.to_type<int>();
}
Gfx::IntPoint Tool::constrain_line_angle(Gfx::IntPoint start_pos, Gfx::IntPoint end_pos, float angle_increment)
{
float current_angle = AK::atan2<float>(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<float>(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) };
}
}

View file

@ -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 };
};