diff --git a/Applications/PaintBrush/LineTool.cpp b/Applications/PaintBrush/LineTool.cpp new file mode 100644 index 0000000000..9620164896 --- /dev/null +++ b/Applications/PaintBrush/LineTool.cpp @@ -0,0 +1,79 @@ +#include "LineTool.h" +#include "PaintableWidget.h" +#include +#include +#include + +LineTool::LineTool() +{ +} + +LineTool::~LineTool() +{ +} + +void LineTool::on_mousedown(GMouseEvent& event) +{ + if (event.button() != GMouseButton::Left && event.button() != GMouseButton::Right) + return; + + if (m_drawing_button != GMouseButton::None) + return; + + m_drawing_button = event.button(); + m_line_start_position = event.position(); + m_line_end_position = event.position(); + m_widget->update(); +} + +void LineTool::on_mouseup(GMouseEvent& event) +{ + if (event.button() == m_drawing_button) { + GPainter painter(m_widget->bitmap()); + painter.draw_line(m_line_start_position, m_line_end_position, m_widget->color_for(m_drawing_button), m_thickness); + m_drawing_button = GMouseButton::None; + m_widget->update(); + } +} + +void LineTool::on_mousemove(GMouseEvent& event) +{ + if (m_drawing_button == GMouseButton::None) + return; + + if (!m_widget->rect().contains(event.position())) + return; + + m_line_end_position = event.position(); + m_widget->update(); +} + +void LineTool::on_second_paint(GPaintEvent& event) +{ + if (m_drawing_button == GMouseButton::None) + return; + + GPainter painter(*m_widget); + painter.add_clip_rect(event.rect()); + painter.draw_line(m_line_start_position, m_line_end_position, m_widget->color_for(m_drawing_button), m_thickness); +} + +void LineTool::on_contextmenu(GContextMenuEvent& event) +{ + if (!m_context_menu) { + m_context_menu = make(); + m_context_menu->add_action(GAction::create("1", [this](auto&) { + m_thickness = 1; + })); + m_context_menu->add_action(GAction::create("2", [this](auto&) { + m_thickness = 2; + })); + m_context_menu->add_action(GAction::create("3", [this](auto&) { + m_thickness = 3; + })); + m_context_menu->add_action(GAction::create("4", [this](auto&) { + m_thickness = 4; + })); + } + m_context_menu->popup(event.screen_position()); +} diff --git a/Applications/PaintBrush/LineTool.h b/Applications/PaintBrush/LineTool.h new file mode 100644 index 0000000000..5e37ca5bfa --- /dev/null +++ b/Applications/PaintBrush/LineTool.h @@ -0,0 +1,27 @@ +#pragma once + +#include "Tool.h" +#include + +class GMenu; + +class LineTool final : public Tool { +public: + LineTool(); + virtual ~LineTool() override; + + virtual void on_mousedown(GMouseEvent&) override; + virtual void on_mousemove(GMouseEvent&) override; + virtual void on_mouseup(GMouseEvent&) override; + virtual void on_contextmenu(GContextMenuEvent&) override; + virtual void on_second_paint(GPaintEvent&) override; + +private: + virtual const char* class_name() const override { return "LineTool"; } + + GMouseButton m_drawing_button { GMouseButton::None }; + Point m_line_start_position; + Point m_line_end_position; + OwnPtr m_context_menu; + int m_thickness { 1 }; +}; diff --git a/Applications/PaintBrush/Makefile b/Applications/PaintBrush/Makefile index 2990169a00..dbdc6d8c3a 100644 --- a/Applications/PaintBrush/Makefile +++ b/Applications/PaintBrush/Makefile @@ -6,6 +6,7 @@ OBJS = \ ToolboxWidget.o \ Tool.o \ PenTool.o \ + LineTool.o \ EraseTool.o \ BucketTool.o \ ColorDialog.o \ diff --git a/Applications/PaintBrush/PaintableWidget.cpp b/Applications/PaintBrush/PaintableWidget.cpp index 1c1b6452d5..a4d3a35330 100644 --- a/Applications/PaintBrush/PaintableWidget.cpp +++ b/Applications/PaintBrush/PaintableWidget.cpp @@ -46,7 +46,16 @@ Tool* PaintableWidget::tool() return m_tool; } -Color PaintableWidget::color_for(const GMouseEvent& event) +Color PaintableWidget::color_for(GMouseButton button) const +{ + if (button == GMouseButton::Left) + return m_primary_color; + if (button == GMouseButton::Right) + return m_secondary_color; + ASSERT_NOT_REACHED(); +} + +Color PaintableWidget::color_for(const GMouseEvent& event) const { if (event.buttons() & GMouseButton::Left) return m_primary_color; @@ -80,6 +89,13 @@ void PaintableWidget::mousemove_event(GMouseEvent& event) GWidget::mousemove_event(event); } +void PaintableWidget::second_paint_event(GPaintEvent& event) +{ + if (m_tool) + m_tool->on_second_paint(event); + GWidget::second_paint_event(event); +} + void PaintableWidget::set_primary_color(Color color) { if (m_primary_color == color) diff --git a/Applications/PaintBrush/PaintableWidget.h b/Applications/PaintBrush/PaintableWidget.h index 9ee7904bdd..76dadb4052 100644 --- a/Applications/PaintBrush/PaintableWidget.h +++ b/Applications/PaintBrush/PaintableWidget.h @@ -20,7 +20,8 @@ public: void set_tool(Tool* tool); Tool* tool(); - Color color_for(const GMouseEvent&); + Color color_for(const GMouseEvent&) const; + Color color_for(GMouseButton) const; void set_bitmap(const GraphicsBitmap&); @@ -32,6 +33,7 @@ public: private: virtual void paint_event(GPaintEvent&) override; + virtual void second_paint_event(GPaintEvent&) override; virtual void mousedown_event(GMouseEvent&) override; virtual void mouseup_event(GMouseEvent&) override; virtual void mousemove_event(GMouseEvent&) override; diff --git a/Applications/PaintBrush/Tool.h b/Applications/PaintBrush/Tool.h index a57a79bc60..2d335a9051 100644 --- a/Applications/PaintBrush/Tool.h +++ b/Applications/PaintBrush/Tool.h @@ -9,10 +9,11 @@ public: virtual const char* class_name() const = 0; - virtual void on_mousedown(GMouseEvent&) { } - virtual void on_mousemove(GMouseEvent&) { } - virtual void on_mouseup(GMouseEvent&) { } - virtual void on_contextmenu(GContextMenuEvent&) { } + virtual void on_mousedown(GMouseEvent&) {} + virtual void on_mousemove(GMouseEvent&) {} + virtual void on_mouseup(GMouseEvent&) {} + virtual void on_contextmenu(GContextMenuEvent&) {} + virtual void on_second_paint(GPaintEvent&) {} void clear() { m_widget = nullptr; } void setup(PaintableWidget& widget) { m_widget = widget.make_weak_ptr(); } diff --git a/Applications/PaintBrush/ToolboxWidget.cpp b/Applications/PaintBrush/ToolboxWidget.cpp index 1ec7d32d4d..51c9fd0b0a 100644 --- a/Applications/PaintBrush/ToolboxWidget.cpp +++ b/Applications/PaintBrush/ToolboxWidget.cpp @@ -1,13 +1,14 @@ #include "ToolboxWidget.h" #include "BucketTool.h" -#include "SprayTool.h" +#include "EraseTool.h" +#include "LineTool.h" #include "PaintableWidget.h" #include "PenTool.h" #include "PickerTool.h" -#include "EraseTool.h" +#include "SprayTool.h" +#include #include #include -#include class ToolButton final : public GButton { C_OBJECT(ToolButton) @@ -69,6 +70,7 @@ ToolboxWidget::ToolboxWidget(GWidget* parent) add_tool("Spray", "spray", make()); add_tool("Color Picker", "picker", make()); add_tool("Erase", "eraser", make()); + add_tool("Line", "line", make()); } ToolboxWidget::~ToolboxWidget() diff --git a/Base/res/icons/paintbrush/line.png b/Base/res/icons/paintbrush/line.png new file mode 100644 index 0000000000..612f6cda1d Binary files /dev/null and b/Base/res/icons/paintbrush/line.png differ