Browse Source

PaintBrush: Shift key constrains LineTool angle

Holding Shift key will constrain the LineTool's line angle to 15 degrees
increments. Many graphics editors have similar feature.
Zyper 5 years ago
parent
commit
413618454b
2 changed files with 37 additions and 1 deletions
  1. 35 1
      Applications/PaintBrush/LineTool.cpp
  2. 2 0
      Applications/PaintBrush/LineTool.h

+ 35 - 1
Applications/PaintBrush/LineTool.cpp

@@ -3,6 +3,20 @@
 #include <LibGUI/GAction.h>
 #include <LibGUI/GAction.h>
 #include <LibGUI/GMenu.h>
 #include <LibGUI/GMenu.h>
 #include <LibGUI/GPainter.h>
 #include <LibGUI/GPainter.h>
+#include <LibM/math.h>
+
+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()
 LineTool::LineTool()
 {
 {
@@ -44,7 +58,12 @@ void LineTool::on_mousemove(GMouseEvent& event)
     if (!m_widget->rect().contains(event.position()))
     if (!m_widget->rect().contains(event.position()))
         return;
         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();
     m_widget->update();
 }
 }
 
 
@@ -65,6 +84,21 @@ void LineTool::on_keydown(GKeyEvent& event)
         m_widget->update();
         m_widget->update();
         event.accept();
         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)
 void LineTool::on_contextmenu(GContextMenuEvent& event)

+ 2 - 0
Applications/PaintBrush/LineTool.h

@@ -16,6 +16,7 @@ public:
     virtual void on_contextmenu(GContextMenuEvent&) override;
     virtual void on_contextmenu(GContextMenuEvent&) override;
     virtual void on_second_paint(GPaintEvent&) override;
     virtual void on_second_paint(GPaintEvent&) override;
     virtual void on_keydown(GKeyEvent&) override;
     virtual void on_keydown(GKeyEvent&) override;
+    virtual void on_keyup(GKeyEvent&) override;
 
 
 private:
 private:
     virtual const char* class_name() const override { return "LineTool"; }
     virtual const char* class_name() const override { return "LineTool"; }
@@ -25,4 +26,5 @@ private:
     Point m_line_end_position;
     Point m_line_end_position;
     RefPtr<GMenu> m_context_menu;
     RefPtr<GMenu> m_context_menu;
     int m_thickness { 1 };
     int m_thickness { 1 };
+    bool m_constrain_angle { false };
 };
 };