diff --git a/Applications/PaintBrush/LineTool.cpp b/Applications/PaintBrush/LineTool.cpp index 03bc4761cd..fb60a2c814 100644 --- a/Applications/PaintBrush/LineTool.cpp +++ b/Applications/PaintBrush/LineTool.cpp @@ -3,6 +3,20 @@ #include #include #include +#include + +Point constrain_line_angle(const Point& start_pos, const Point& end_pos, float angle_increment) +{ + float current_angle = atan2(end_pos.y() - start_pos.y(), end_pos.x() - start_pos.x()) + 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 = sqrt(diff.x() * diff.x() + diff.y() * diff.y()); + + return { start_pos.x() + (int)(cos(constrained_angle) * line_length), + start_pos.y() + (int)(sin(constrained_angle) * line_length) }; +} LineTool::LineTool() { @@ -44,7 +58,12 @@ void LineTool::on_mousemove(GMouseEvent& event) if (!m_widget->rect().contains(event.position())) return; - m_line_end_position = event.position(); + if (!m_constrain_angle) { + m_line_end_position = event.position(); + } else { + const float ANGLE_STEP = M_PI / 8.0f; + m_line_end_position = constrain_line_angle(m_line_start_position, event.position(), ANGLE_STEP); + } m_widget->update(); } @@ -65,6 +84,21 @@ void LineTool::on_keydown(GKeyEvent& event) m_widget->update(); event.accept(); } + + if (event.key() == Key_Shift) { + m_constrain_angle = true; + m_widget->update(); + event.accept(); + } +} + +void LineTool::on_keyup(GKeyEvent& event) +{ + if (event.key() == Key_Shift) { + m_constrain_angle = false; + m_widget->update(); + event.accept(); + } } void LineTool::on_contextmenu(GContextMenuEvent& event) diff --git a/Applications/PaintBrush/LineTool.h b/Applications/PaintBrush/LineTool.h index 4c5920f54b..619f02cfea 100644 --- a/Applications/PaintBrush/LineTool.h +++ b/Applications/PaintBrush/LineTool.h @@ -16,6 +16,7 @@ public: virtual void on_contextmenu(GContextMenuEvent&) override; virtual void on_second_paint(GPaintEvent&) override; virtual void on_keydown(GKeyEvent&) override; + virtual void on_keyup(GKeyEvent&) override; private: virtual const char* class_name() const override { return "LineTool"; } @@ -25,4 +26,5 @@ private: Point m_line_end_position; RefPtr m_context_menu; int m_thickness { 1 }; + bool m_constrain_angle { false }; };