diff options
-rw-r--r-- | Applications/PaintBrush/EllipseTool.cpp | 106 | ||||
-rw-r--r-- | Applications/PaintBrush/EllipseTool.h | 36 | ||||
-rw-r--r-- | Applications/PaintBrush/Makefile | 1 | ||||
-rw-r--r-- | Applications/PaintBrush/ToolboxWidget.cpp | 2 | ||||
-rw-r--r-- | Base/res/icons/paintbrush/circle.png | bin | 0 -> 1005 bytes |
5 files changed, 145 insertions, 0 deletions
diff --git a/Applications/PaintBrush/EllipseTool.cpp b/Applications/PaintBrush/EllipseTool.cpp new file mode 100644 index 0000000000..9e87812f5e --- /dev/null +++ b/Applications/PaintBrush/EllipseTool.cpp @@ -0,0 +1,106 @@ +#include "EllipseTool.h" +#include "PaintableWidget.h" +#include <LibDraw/Rect.h> +#include <LibGUI/GAction.h> +#include <LibGUI/GMenu.h> +#include <LibGUI/GPainter.h> +#include <LibM/math.h> + +EllipseTool::EllipseTool() +{ +} + +EllipseTool::~EllipseTool() +{ +} + +void EllipseTool::draw_using(Painter& painter) +{ + auto ellipse_intersecting_rect = Rect::from_two_points(m_ellipse_start_position, m_ellipse_end_position); + switch (m_mode) { + case Mode::Outline: + painter.draw_ellipse_intersecting(ellipse_intersecting_rect, m_widget->color_for(m_drawing_button), m_thickness); + break; + default: + ASSERT_NOT_REACHED(); + } +} + +void EllipseTool::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_ellipse_start_position = event.position(); + m_ellipse_end_position = event.position(); + m_widget->update(); +} + +void EllipseTool::on_mouseup(GMouseEvent& event) +{ + if (event.button() == m_drawing_button) { + GPainter painter(m_widget->bitmap()); + draw_using(painter); + m_drawing_button = GMouseButton::None; + m_widget->update(); + } +} + +void EllipseTool::on_mousemove(GMouseEvent& event) +{ + if (m_drawing_button == GMouseButton::None) + return; + + if (!m_widget->rect().contains(event.position())) + return; + + m_ellipse_end_position = event.position(); + m_widget->update(); +} + +void EllipseTool::on_second_paint(GPaintEvent& event) +{ + if (m_drawing_button == GMouseButton::None) + return; + + GPainter painter(*m_widget); + painter.add_clip_rect(event.rect()); + draw_using(painter); +} + +void EllipseTool::on_keydown(GKeyEvent& event) +{ + if (event.key() == Key_Escape && m_drawing_button != GMouseButton::None) { + m_drawing_button = GMouseButton::None; + m_widget->update(); + event.accept(); + } +} + +void EllipseTool::on_contextmenu(GContextMenuEvent& event) +{ + if (!m_context_menu) { + m_context_menu = GMenu::construct(); + m_context_menu->add_action(GAction::create("Outline", [this](auto&) { + m_mode = Mode::Outline; + })); + m_context_menu->add_separator(); + 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/EllipseTool.h b/Applications/PaintBrush/EllipseTool.h new file mode 100644 index 0000000000..bc2f59782b --- /dev/null +++ b/Applications/PaintBrush/EllipseTool.h @@ -0,0 +1,36 @@ +#pragma once + +#include "Tool.h" +#include <LibDraw/Point.h> + +class GMenu; +class Painter; + +class EllipseTool final : public Tool { +public: + EllipseTool(); + virtual ~EllipseTool() 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; + virtual void on_keydown(GKeyEvent&) override; + +private: + enum class Mode { + Outline, + // FIXME: Add Mode::Fill + }; + + virtual const char* class_name() const override { return "EllipseTool"; } + void draw_using(Painter& painter); + + GMouseButton m_drawing_button { GMouseButton::None }; + Point m_ellipse_start_position; + Point m_ellipse_end_position; + RefPtr<GMenu> m_context_menu; + int m_thickness { 1 }; + Mode m_mode { Mode::Outline }; +}; diff --git a/Applications/PaintBrush/Makefile b/Applications/PaintBrush/Makefile index 0953e04f50..29534b135f 100644 --- a/Applications/PaintBrush/Makefile +++ b/Applications/PaintBrush/Makefile @@ -6,6 +6,7 @@ OBJS = \ PenTool.o \ LineTool.o \ RectangleTool.o \ + EllipseTool.o \ EraseTool.o \ BucketTool.o \ ColorDialog.o \ diff --git a/Applications/PaintBrush/ToolboxWidget.cpp b/Applications/PaintBrush/ToolboxWidget.cpp index a46a302838..9627a88b13 100644 --- a/Applications/PaintBrush/ToolboxWidget.cpp +++ b/Applications/PaintBrush/ToolboxWidget.cpp @@ -1,5 +1,6 @@ #include "ToolboxWidget.h" #include "BucketTool.h" +#include "EllipseTool.h" #include "EraseTool.h" #include "LineTool.h" #include "PaintableWidget.h" @@ -72,6 +73,7 @@ ToolboxWidget::ToolboxWidget(GWidget* parent) add_tool("Erase", "eraser", make<EraseTool>()); add_tool("Line", "line", make<LineTool>()); add_tool("Rectangle", "rectangle", make<RectangleTool>()); + add_tool("Ellipse", "circle", make<EllipseTool>()); } ToolboxWidget::~ToolboxWidget() diff --git a/Base/res/icons/paintbrush/circle.png b/Base/res/icons/paintbrush/circle.png Binary files differnew file mode 100644 index 0000000000..aa56e05083 --- /dev/null +++ b/Base/res/icons/paintbrush/circle.png |