mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:37:45 +00:00
PaintBrush: Port all the existing toolbox tools to the Layer world :^)
Many tools are not working perfectly right yet, but we'll fix them!
This commit is contained in:
parent
7dd8f1b921
commit
83d24dcb1d
25 changed files with 302 additions and 199 deletions
|
@ -25,12 +25,16 @@
|
|||
*/
|
||||
|
||||
#include "BucketTool.h"
|
||||
#include "ImageEditor.h"
|
||||
#include "Layer.h"
|
||||
#include "PaintableWidget.h"
|
||||
#include <AK/Queue.h>
|
||||
#include <AK/SinglyLinkedList.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <stdio.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
BucketTool::BucketTool()
|
||||
{
|
||||
|
@ -74,15 +78,17 @@ static void flood_fill(Gfx::Bitmap& bitmap, const Gfx::Point& start_position, Co
|
|||
}
|
||||
}
|
||||
|
||||
void BucketTool::on_mousedown(GUI::MouseEvent& event)
|
||||
void BucketTool::on_mousedown(Layer& layer, GUI::MouseEvent& event)
|
||||
{
|
||||
if (!m_widget->rect().contains(event.position()))
|
||||
if (!layer.rect().contains(event.position()))
|
||||
return;
|
||||
|
||||
GUI::Painter painter(m_widget->bitmap());
|
||||
auto target_color = m_widget->bitmap().get_pixel(event.x(), event.y());
|
||||
GUI::Painter painter(layer.bitmap());
|
||||
auto target_color = layer.bitmap().get_pixel(event.x(), event.y());
|
||||
|
||||
flood_fill(m_widget->bitmap(), event.position(), target_color, m_widget->color_for(event));
|
||||
flood_fill(layer.bitmap(), event.position(), target_color, PaintableWidget::the().color_for(event));
|
||||
|
||||
m_editor->update();
|
||||
}
|
||||
|
||||
m_widget->update();
|
||||
}
|
||||
|
|
|
@ -28,13 +28,17 @@
|
|||
|
||||
#include "Tool.h"
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
class BucketTool final : public Tool {
|
||||
public:
|
||||
BucketTool();
|
||||
virtual ~BucketTool() override;
|
||||
|
||||
virtual void on_mousedown(GUI::MouseEvent&) override;
|
||||
virtual void on_mousedown(Layer&, GUI::MouseEvent&) override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "BucketTool"; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
*/
|
||||
|
||||
#include "EllipseTool.h"
|
||||
#include "ImageEditor.h"
|
||||
#include "Layer.h"
|
||||
#include "PaintableWidget.h"
|
||||
#include <LibGUI/Action.h>
|
||||
#include <LibGUI/Menu.h>
|
||||
|
@ -32,6 +34,8 @@
|
|||
#include <LibGfx/Rect.h>
|
||||
#include <LibM/math.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
EllipseTool::EllipseTool()
|
||||
{
|
||||
}
|
||||
|
@ -45,14 +49,14 @@ void EllipseTool::draw_using(GUI::Painter& painter)
|
|||
auto ellipse_intersecting_rect = Gfx::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);
|
||||
painter.draw_ellipse_intersecting(ellipse_intersecting_rect, PaintableWidget::the().color_for(m_drawing_button), m_thickness);
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
void EllipseTool::on_mousedown(GUI::MouseEvent& event)
|
||||
void EllipseTool::on_mousedown(Layer&, GUI::MouseEvent& event)
|
||||
{
|
||||
if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
|
||||
return;
|
||||
|
@ -63,29 +67,29 @@ void EllipseTool::on_mousedown(GUI::MouseEvent& event)
|
|||
m_drawing_button = event.button();
|
||||
m_ellipse_start_position = event.position();
|
||||
m_ellipse_end_position = event.position();
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
}
|
||||
|
||||
void EllipseTool::on_mouseup(GUI::MouseEvent& event)
|
||||
void EllipseTool::on_mouseup(Layer& layer, GUI::MouseEvent& event)
|
||||
{
|
||||
if (event.button() == m_drawing_button) {
|
||||
GUI::Painter painter(m_widget->bitmap());
|
||||
GUI::Painter painter(layer.bitmap());
|
||||
draw_using(painter);
|
||||
m_drawing_button = GUI::MouseButton::None;
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
}
|
||||
}
|
||||
|
||||
void EllipseTool::on_mousemove(GUI::MouseEvent& event)
|
||||
void EllipseTool::on_mousemove(Layer& layer, GUI::MouseEvent& event)
|
||||
{
|
||||
if (m_drawing_button == GUI::MouseButton::None)
|
||||
return;
|
||||
|
||||
if (!m_widget->rect().contains(event.position()))
|
||||
if (!layer.rect().contains(event.position()))
|
||||
return;
|
||||
|
||||
m_ellipse_end_position = event.position();
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
}
|
||||
|
||||
void EllipseTool::on_second_paint(GUI::PaintEvent& event)
|
||||
|
@ -93,7 +97,7 @@ void EllipseTool::on_second_paint(GUI::PaintEvent& event)
|
|||
if (m_drawing_button == GUI::MouseButton::None)
|
||||
return;
|
||||
|
||||
GUI::Painter painter(*m_widget);
|
||||
GUI::Painter painter(*m_editor);
|
||||
painter.add_clip_rect(event.rect());
|
||||
draw_using(painter);
|
||||
}
|
||||
|
@ -102,7 +106,7 @@ void EllipseTool::on_keydown(GUI::KeyEvent& event)
|
|||
{
|
||||
if (event.key() == Key_Escape && m_drawing_button != GUI::MouseButton::None) {
|
||||
m_drawing_button = GUI::MouseButton::None;
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
event.accept();
|
||||
}
|
||||
}
|
||||
|
@ -131,3 +135,5 @@ void EllipseTool::on_contextmenu(GUI::ContextMenuEvent& event)
|
|||
}
|
||||
m_context_menu->popup(event.screen_position());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,14 +30,16 @@
|
|||
#include <LibGfx/Point.h>
|
||||
#include <LibGUI/ActionGroup.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
class EllipseTool final : public Tool {
|
||||
public:
|
||||
EllipseTool();
|
||||
virtual ~EllipseTool() override;
|
||||
|
||||
virtual void on_mousedown(GUI::MouseEvent&) override;
|
||||
virtual void on_mousemove(GUI::MouseEvent&) override;
|
||||
virtual void on_mouseup(GUI::MouseEvent&) override;
|
||||
virtual void on_mousedown(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_mousemove(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_mouseup(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_contextmenu(GUI::ContextMenuEvent&) override;
|
||||
virtual void on_second_paint(GUI::PaintEvent&) override;
|
||||
virtual void on_keydown(GUI::KeyEvent&) override;
|
||||
|
@ -59,3 +61,5 @@ private:
|
|||
GUI::ActionGroup m_thickness_actions;
|
||||
Mode m_mode { Mode::Outline };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,12 +25,16 @@
|
|||
*/
|
||||
|
||||
#include "EraseTool.h"
|
||||
#include "ImageEditor.h"
|
||||
#include "Layer.h"
|
||||
#include "PaintableWidget.h"
|
||||
#include <LibGUI/Action.h>
|
||||
#include <LibGUI/Menu.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
EraseTool::EraseTool()
|
||||
{
|
||||
}
|
||||
|
@ -49,26 +53,26 @@ Gfx::Rect EraseTool::build_rect(const Gfx::Point& pos, const Gfx::Rect& widget_r
|
|||
return Gfx::Rect(ex - eraser_radius, ey - eraser_radius, eraser_size, eraser_size).intersected(widget_rect);
|
||||
}
|
||||
|
||||
void EraseTool::on_mousedown(GUI::MouseEvent& event)
|
||||
void EraseTool::on_mousedown(Layer& layer, GUI::MouseEvent& event)
|
||||
{
|
||||
if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
|
||||
return;
|
||||
Gfx::Rect r = build_rect(event.position(), m_widget->bitmap().rect());
|
||||
GUI::Painter painter(m_widget->bitmap());
|
||||
Gfx::Rect r = build_rect(event.position(), layer.rect());
|
||||
GUI::Painter painter(layer.bitmap());
|
||||
painter.clear_rect(r, get_color());
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
}
|
||||
|
||||
void EraseTool::on_mousemove(GUI::MouseEvent& event)
|
||||
void EraseTool::on_mousemove(Layer& layer, GUI::MouseEvent& event)
|
||||
{
|
||||
if (!m_widget->rect().contains(event.position()))
|
||||
if (!m_editor->rect().contains(event.position()))
|
||||
return;
|
||||
|
||||
if (event.buttons() & GUI::MouseButton::Left || event.buttons() & GUI::MouseButton::Right) {
|
||||
Gfx::Rect r = build_rect(event.position(), m_widget->bitmap().rect());
|
||||
GUI::Painter painter(m_widget->bitmap());
|
||||
Gfx::Rect r = build_rect(event.position(), layer.rect());
|
||||
GUI::Painter painter(layer.bitmap());
|
||||
painter.clear_rect(r, get_color());
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,6 +110,8 @@ void EraseTool::on_contextmenu(GUI::ContextMenuEvent& event)
|
|||
Color EraseTool::get_color() const
|
||||
{
|
||||
if (m_use_secondary_color)
|
||||
return m_widget->secondary_color();
|
||||
return PaintableWidget::the().secondary_color();
|
||||
return Color(255, 255, 255, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,18 +29,21 @@
|
|||
#include "Tool.h"
|
||||
#include <LibGUI/ActionGroup.h>
|
||||
#include <LibGfx/Point.h>
|
||||
#include <LibGfx/Forward.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
class EraseTool final : public Tool {
|
||||
public:
|
||||
EraseTool();
|
||||
virtual ~EraseTool() override;
|
||||
|
||||
virtual void on_mousedown(GUI::MouseEvent&) override;
|
||||
virtual void on_mousemove(GUI::MouseEvent&) override;
|
||||
virtual void on_mousedown(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_mousemove(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_contextmenu(GUI::ContextMenuEvent&) override;
|
||||
|
||||
private:
|
||||
Color get_color() const;
|
||||
Gfx::Color get_color() const;
|
||||
virtual const char* class_name() const override { return "EraseTool"; }
|
||||
Gfx::Rect build_rect(const Gfx::Point& pos, const Gfx::Rect& widget_rect);
|
||||
RefPtr<GUI::Menu> m_context_menu;
|
||||
|
@ -49,3 +52,5 @@ private:
|
|||
int m_thickness { 1 };
|
||||
GUI::ActionGroup m_thickness_actions;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "Image.h"
|
||||
#include "Layer.h"
|
||||
#include "LayerModel.h"
|
||||
#include "Tool.h"
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGfx/Palette.h>
|
||||
|
||||
|
@ -61,6 +62,43 @@ void ImageEditor::paint_event(GUI::PaintEvent& event)
|
|||
}
|
||||
}
|
||||
|
||||
static GUI::MouseEvent event_adjusted_for_layer(const GUI::MouseEvent& original_event, const Layer& layer)
|
||||
{
|
||||
auto position_in_active_layer_coordinates = original_event.position().translated(-layer.location());
|
||||
dbg() << "adjusted: " << position_in_active_layer_coordinates;
|
||||
return {
|
||||
static_cast<GUI::Event::Type>(original_event.type()),
|
||||
position_in_active_layer_coordinates, original_event.buttons(),
|
||||
original_event.button(),
|
||||
original_event.modifiers(),
|
||||
original_event.wheel_delta()
|
||||
};
|
||||
}
|
||||
|
||||
void ImageEditor::mousedown_event(GUI::MouseEvent& event)
|
||||
{
|
||||
if (!m_active_layer || !m_active_tool)
|
||||
return;
|
||||
auto layer_event = event_adjusted_for_layer(event, *m_active_layer);
|
||||
m_active_tool->on_mousedown(*m_active_layer, layer_event);
|
||||
}
|
||||
|
||||
void ImageEditor::mousemove_event(GUI::MouseEvent& event)
|
||||
{
|
||||
if (!m_active_layer || !m_active_tool)
|
||||
return;
|
||||
auto layer_event = event_adjusted_for_layer(event, *m_active_layer);
|
||||
m_active_tool->on_mousemove(*m_active_layer, layer_event);
|
||||
}
|
||||
|
||||
void ImageEditor::mouseup_event(GUI::MouseEvent& event)
|
||||
{
|
||||
if (!m_active_layer || !m_active_tool)
|
||||
return;
|
||||
auto layer_event = event_adjusted_for_layer(event, *m_active_layer);
|
||||
m_active_tool->on_mouseup(*m_active_layer, layer_event);
|
||||
}
|
||||
|
||||
void ImageEditor::set_active_layer(Layer* layer)
|
||||
{
|
||||
if (m_active_layer == layer)
|
||||
|
@ -69,4 +107,18 @@ void ImageEditor::set_active_layer(Layer* layer)
|
|||
update();
|
||||
}
|
||||
|
||||
void ImageEditor::set_active_tool(Tool* tool)
|
||||
{
|
||||
if (m_active_tool == tool)
|
||||
return;
|
||||
|
||||
if (m_active_tool)
|
||||
m_active_tool->clear();
|
||||
|
||||
m_active_tool = tool;
|
||||
|
||||
if (m_active_tool)
|
||||
m_active_tool->setup(*this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace PaintBrush {
|
|||
|
||||
class Image;
|
||||
class Layer;
|
||||
class Tool;
|
||||
|
||||
class ImageEditor final : public GUI::Frame {
|
||||
C_OBJECT(ImageEditor);
|
||||
|
@ -45,13 +46,21 @@ public:
|
|||
Layer* active_layer() { return m_active_layer; }
|
||||
void set_active_layer(Layer*);
|
||||
|
||||
Tool* active_tool() { return m_active_tool; }
|
||||
void set_active_tool(Tool*);
|
||||
|
||||
private:
|
||||
ImageEditor();
|
||||
|
||||
virtual void paint_event(GUI::PaintEvent&) override;
|
||||
virtual void mousedown_event(GUI::MouseEvent&) override;
|
||||
virtual void mousemove_event(GUI::MouseEvent&) override;
|
||||
virtual void mouseup_event(GUI::MouseEvent&) override;
|
||||
|
||||
RefPtr<Image> m_image;
|
||||
RefPtr<Layer> m_active_layer;
|
||||
|
||||
Tool* m_active_tool { nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,12 +25,16 @@
|
|||
*/
|
||||
|
||||
#include "LineTool.h"
|
||||
#include "ImageEditor.h"
|
||||
#include "Layer.h"
|
||||
#include "PaintableWidget.h"
|
||||
#include <LibGUI/Action.h>
|
||||
#include <LibGUI/Menu.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibM/math.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
static Gfx::Point constrain_line_angle(const Gfx::Point& start_pos, const Gfx::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.;
|
||||
|
@ -52,7 +56,7 @@ LineTool::~LineTool()
|
|||
{
|
||||
}
|
||||
|
||||
void LineTool::on_mousedown(GUI::MouseEvent& event)
|
||||
void LineTool::on_mousedown(Layer&, GUI::MouseEvent& event)
|
||||
{
|
||||
if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
|
||||
return;
|
||||
|
@ -63,25 +67,25 @@ void LineTool::on_mousedown(GUI::MouseEvent& event)
|
|||
m_drawing_button = event.button();
|
||||
m_line_start_position = event.position();
|
||||
m_line_end_position = event.position();
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
}
|
||||
|
||||
void LineTool::on_mouseup(GUI::MouseEvent& event)
|
||||
void LineTool::on_mouseup(Layer& layer, GUI::MouseEvent& event)
|
||||
{
|
||||
if (event.button() == m_drawing_button) {
|
||||
GUI::Painter painter(m_widget->bitmap());
|
||||
painter.draw_line(m_line_start_position, m_line_end_position, m_widget->color_for(m_drawing_button), m_thickness);
|
||||
GUI::Painter painter(layer.bitmap());
|
||||
painter.draw_line(m_line_start_position, m_line_end_position, PaintableWidget::the().color_for(m_drawing_button), m_thickness);
|
||||
m_drawing_button = GUI::MouseButton::None;
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LineTool::on_mousemove(GUI::MouseEvent& event)
|
||||
void LineTool::on_mousemove(Layer&, GUI::MouseEvent& event)
|
||||
{
|
||||
if (m_drawing_button == GUI::MouseButton::None)
|
||||
return;
|
||||
|
||||
if (!m_widget->rect().contains(event.position()))
|
||||
if (!m_editor->rect().contains(event.position()))
|
||||
return;
|
||||
|
||||
if (!m_constrain_angle) {
|
||||
|
@ -90,7 +94,7 @@ void LineTool::on_mousemove(GUI::MouseEvent& event)
|
|||
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_editor->update();
|
||||
}
|
||||
|
||||
void LineTool::on_second_paint(GUI::PaintEvent& event)
|
||||
|
@ -98,22 +102,26 @@ void LineTool::on_second_paint(GUI::PaintEvent& event)
|
|||
if (m_drawing_button == GUI::MouseButton::None)
|
||||
return;
|
||||
|
||||
(void)event;
|
||||
|
||||
#if 0
|
||||
GUI::Painter 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);
|
||||
painter.draw_line(m_line_start_position, m_line_end_position, m_editor->color_for(m_drawing_button), m_thickness);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LineTool::on_keydown(GUI::KeyEvent& event)
|
||||
{
|
||||
if (event.key() == Key_Escape && m_drawing_button != GUI::MouseButton::None) {
|
||||
m_drawing_button = GUI::MouseButton::None;
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
event.accept();
|
||||
}
|
||||
|
||||
if (event.key() == Key_Shift) {
|
||||
m_constrain_angle = true;
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
event.accept();
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +130,7 @@ void LineTool::on_keyup(GUI::KeyEvent& event)
|
|||
{
|
||||
if (event.key() == Key_Shift) {
|
||||
m_constrain_angle = false;
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
event.accept();
|
||||
}
|
||||
}
|
||||
|
@ -147,3 +155,5 @@ void LineTool::on_contextmenu(GUI::ContextMenuEvent& event)
|
|||
}
|
||||
m_context_menu->popup(event.screen_position());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,17 +27,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "Tool.h"
|
||||
#include <LibGfx/Point.h>
|
||||
#include <LibGUI/ActionGroup.h>
|
||||
#include <LibGfx/Point.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
class LineTool final : public Tool {
|
||||
public:
|
||||
LineTool();
|
||||
virtual ~LineTool() override;
|
||||
|
||||
virtual void on_mousedown(GUI::MouseEvent&) override;
|
||||
virtual void on_mousemove(GUI::MouseEvent&) override;
|
||||
virtual void on_mouseup(GUI::MouseEvent&) override;
|
||||
virtual void on_mousedown(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_mousemove(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_mouseup(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_contextmenu(GUI::ContextMenuEvent&) override;
|
||||
virtual void on_second_paint(GUI::PaintEvent&) override;
|
||||
virtual void on_keydown(GUI::KeyEvent&) override;
|
||||
|
@ -54,3 +56,5 @@ private:
|
|||
int m_thickness { 1 };
|
||||
bool m_constrain_angle { false };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -54,29 +54,6 @@ PaintableWidget::~PaintableWidget()
|
|||
{
|
||||
}
|
||||
|
||||
void PaintableWidget::paint_event(GUI::PaintEvent& event)
|
||||
{
|
||||
GUI::Painter painter(*this);
|
||||
|
||||
painter.add_clip_rect(event.rect());
|
||||
painter.fill_rect_with_checkerboard(m_bitmap->rect(), { 8, 8 }, palette().base().darkened(0.9), palette().base());
|
||||
painter.blit({ 0, 0 }, *m_bitmap, m_bitmap->rect());
|
||||
}
|
||||
|
||||
void PaintableWidget::set_tool(Tool* tool)
|
||||
{
|
||||
if (m_tool)
|
||||
m_tool->clear();
|
||||
m_tool = tool;
|
||||
if (m_tool)
|
||||
m_tool->setup(*this);
|
||||
}
|
||||
|
||||
Tool* PaintableWidget::tool()
|
||||
{
|
||||
return m_tool;
|
||||
}
|
||||
|
||||
Color PaintableWidget::color_for(GUI::MouseButton button) const
|
||||
{
|
||||
if (button == GUI::MouseButton::Left)
|
||||
|
@ -95,52 +72,6 @@ Color PaintableWidget::color_for(const GUI::MouseEvent& event) const
|
|||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
void PaintableWidget::mousedown_event(GUI::MouseEvent& event)
|
||||
{
|
||||
if (event.button() == GUI::MouseButton::Left || event.button() == GUI::MouseButton::Right) {
|
||||
if (m_tool)
|
||||
m_tool->on_mousedown(event);
|
||||
}
|
||||
GUI::Widget::mousedown_event(event);
|
||||
}
|
||||
|
||||
void PaintableWidget::mouseup_event(GUI::MouseEvent& event)
|
||||
{
|
||||
if (event.button() == GUI::MouseButton::Left || event.button() == GUI::MouseButton::Right) {
|
||||
if (m_tool)
|
||||
m_tool->on_mouseup(event);
|
||||
}
|
||||
GUI::Widget::mouseup_event(event);
|
||||
}
|
||||
|
||||
void PaintableWidget::mousemove_event(GUI::MouseEvent& event)
|
||||
{
|
||||
if (m_tool)
|
||||
m_tool->on_mousemove(event);
|
||||
GUI::Widget::mousemove_event(event);
|
||||
}
|
||||
|
||||
void PaintableWidget::second_paint_event(GUI::PaintEvent& event)
|
||||
{
|
||||
if (m_tool)
|
||||
m_tool->on_second_paint(event);
|
||||
GUI::Widget::second_paint_event(event);
|
||||
}
|
||||
|
||||
void PaintableWidget::keydown_event(GUI::KeyEvent& event)
|
||||
{
|
||||
if (m_tool)
|
||||
m_tool->on_keydown(event);
|
||||
GUI::Widget::keydown_event(event);
|
||||
}
|
||||
|
||||
void PaintableWidget::keyup_event(GUI::KeyEvent& event)
|
||||
{
|
||||
if (m_tool)
|
||||
m_tool->on_keyup(event);
|
||||
GUI::Widget::keyup_event(event);
|
||||
}
|
||||
|
||||
void PaintableWidget::set_primary_color(Color color)
|
||||
{
|
||||
if (m_primary_color == color)
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibGUI/Widget.h>
|
||||
class Tool;
|
||||
|
||||
class PaintableWidget final : public GUI::Widget {
|
||||
C_OBJECT(PaintableWidget)
|
||||
|
@ -42,9 +41,6 @@ public:
|
|||
void set_primary_color(Color);
|
||||
void set_secondary_color(Color);
|
||||
|
||||
void set_tool(Tool* tool);
|
||||
Tool* tool();
|
||||
|
||||
Color color_for(const GUI::MouseEvent&) const;
|
||||
Color color_for(GUI::MouseButton) const;
|
||||
|
||||
|
@ -59,19 +55,8 @@ public:
|
|||
private:
|
||||
PaintableWidget();
|
||||
|
||||
virtual bool accepts_focus() const override { return true; }
|
||||
virtual void paint_event(GUI::PaintEvent&) override;
|
||||
virtual void second_paint_event(GUI::PaintEvent&) override;
|
||||
virtual void mousedown_event(GUI::MouseEvent&) override;
|
||||
virtual void mouseup_event(GUI::MouseEvent&) override;
|
||||
virtual void mousemove_event(GUI::MouseEvent&) override;
|
||||
virtual void keydown_event(GUI::KeyEvent&) override;
|
||||
virtual void keyup_event(GUI::KeyEvent&) override;
|
||||
|
||||
RefPtr<Gfx::Bitmap> m_bitmap;
|
||||
|
||||
Color m_primary_color { Color::Black };
|
||||
Color m_secondary_color { Color::White };
|
||||
|
||||
Tool* m_tool { nullptr };
|
||||
};
|
||||
|
|
|
@ -25,11 +25,15 @@
|
|||
*/
|
||||
|
||||
#include "PenTool.h"
|
||||
#include "ImageEditor.h"
|
||||
#include "Layer.h"
|
||||
#include "PaintableWidget.h"
|
||||
#include <LibGUI/Action.h>
|
||||
#include <LibGUI/Menu.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
PenTool::PenTool()
|
||||
{
|
||||
}
|
||||
|
@ -38,36 +42,36 @@ PenTool::~PenTool()
|
|||
{
|
||||
}
|
||||
|
||||
void PenTool::on_mousedown(GUI::MouseEvent& event)
|
||||
void PenTool::on_mousedown(Layer& layer, GUI::MouseEvent& event)
|
||||
{
|
||||
if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
|
||||
return;
|
||||
|
||||
GUI::Painter painter(m_widget->bitmap());
|
||||
painter.draw_line(event.position(), event.position(), m_widget->color_for(event), m_thickness);
|
||||
m_widget->update();
|
||||
GUI::Painter painter(layer.bitmap());
|
||||
painter.draw_line(event.position(), event.position(), PaintableWidget::the().color_for(event), m_thickness);
|
||||
m_editor->update();
|
||||
m_last_drawing_event_position = event.position();
|
||||
}
|
||||
|
||||
void PenTool::on_mouseup(GUI::MouseEvent& event)
|
||||
void PenTool::on_mouseup(Layer&, GUI::MouseEvent& event)
|
||||
{
|
||||
if (event.button() == GUI::MouseButton::Left || event.button() == GUI::MouseButton::Right)
|
||||
m_last_drawing_event_position = { -1, -1 };
|
||||
}
|
||||
|
||||
void PenTool::on_mousemove(GUI::MouseEvent& event)
|
||||
void PenTool::on_mousemove(Layer& layer, GUI::MouseEvent& event)
|
||||
{
|
||||
if (!m_widget->rect().contains(event.position()))
|
||||
if (!layer.rect().contains(event.position()))
|
||||
return;
|
||||
|
||||
if (event.buttons() & GUI::MouseButton::Left || event.buttons() & GUI::MouseButton::Right) {
|
||||
GUI::Painter painter(m_widget->bitmap());
|
||||
GUI::Painter painter(layer.bitmap());
|
||||
|
||||
if (m_last_drawing_event_position != Gfx::Point(-1, -1))
|
||||
painter.draw_line(m_last_drawing_event_position, event.position(), m_widget->color_for(event), m_thickness);
|
||||
painter.draw_line(m_last_drawing_event_position, event.position(), PaintableWidget::the().color_for(event), m_thickness);
|
||||
else
|
||||
painter.draw_line(event.position(), event.position(), m_widget->color_for(event), m_thickness);
|
||||
m_widget->update();
|
||||
painter.draw_line(event.position(), event.position(), PaintableWidget::the().color_for(event), m_thickness);
|
||||
m_editor->update();
|
||||
|
||||
m_last_drawing_event_position = event.position();
|
||||
}
|
||||
|
@ -93,3 +97,5 @@ void PenTool::on_contextmenu(GUI::ContextMenuEvent& event)
|
|||
}
|
||||
m_context_menu->popup(event.screen_position());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,14 +30,16 @@
|
|||
#include <LibGfx/Point.h>
|
||||
#include <LibGUI/ActionGroup.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
class PenTool final : public Tool {
|
||||
public:
|
||||
PenTool();
|
||||
virtual ~PenTool() override;
|
||||
|
||||
virtual void on_mousedown(GUI::MouseEvent&) override;
|
||||
virtual void on_mousemove(GUI::MouseEvent&) override;
|
||||
virtual void on_mouseup(GUI::MouseEvent&) override;
|
||||
virtual void on_mousedown(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_mousemove(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_mouseup(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_contextmenu(GUI::ContextMenuEvent&) override;
|
||||
|
||||
private:
|
||||
|
@ -48,3 +50,5 @@ private:
|
|||
int m_thickness { 1 };
|
||||
GUI::ActionGroup m_thickness_actions;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,8 +25,12 @@
|
|||
*/
|
||||
|
||||
#include "PickerTool.h"
|
||||
#include "Layer.h"
|
||||
#include "PaintableWidget.h"
|
||||
#include <LibGfx/Bitmap.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
PickerTool::PickerTool()
|
||||
{
|
||||
}
|
||||
|
@ -35,14 +39,15 @@ PickerTool::~PickerTool()
|
|||
{
|
||||
}
|
||||
|
||||
void PickerTool::on_mousedown(GUI::MouseEvent& event)
|
||||
void PickerTool::on_mousedown(Layer& layer, GUI::MouseEvent& event)
|
||||
{
|
||||
ASSERT(m_widget);
|
||||
if (!m_widget->bitmap().rect().contains(event.position()))
|
||||
if (!layer.rect().contains(event.position()))
|
||||
return;
|
||||
auto color = m_widget->bitmap().get_pixel(event.position());
|
||||
auto color = layer.bitmap().get_pixel(event.position());
|
||||
if (event.button() == GUI::MouseButton::Left)
|
||||
m_widget->set_primary_color(color);
|
||||
PaintableWidget::the().set_primary_color(color);
|
||||
else if (event.button() == GUI::MouseButton::Right)
|
||||
m_widget->set_secondary_color(color);
|
||||
PaintableWidget::the().set_secondary_color(color);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,14 +28,18 @@
|
|||
|
||||
#include "Tool.h"
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
class PickerTool final : public Tool {
|
||||
public:
|
||||
PickerTool();
|
||||
virtual ~PickerTool() override;
|
||||
|
||||
virtual void on_mousedown(GUI::MouseEvent&) override;
|
||||
virtual void on_mousedown(Layer&, GUI::MouseEvent&) override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "PickerTool"; }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,13 +25,17 @@
|
|||
*/
|
||||
|
||||
#include "RectangleTool.h"
|
||||
#include "ImageEditor.h"
|
||||
#include "Layer.h"
|
||||
#include "PaintableWidget.h"
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibGUI/Action.h>
|
||||
#include <LibGUI/Menu.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibM/math.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
RectangleTool::RectangleTool()
|
||||
{
|
||||
}
|
||||
|
@ -45,20 +49,20 @@ void RectangleTool::draw_using(GUI::Painter& painter)
|
|||
auto rect_to_draw = Gfx::Rect::from_two_points(m_rectangle_start_position, m_rectangle_end_position);
|
||||
switch (m_mode) {
|
||||
case Mode::Fill:
|
||||
painter.fill_rect(rect_to_draw, m_widget->color_for(m_drawing_button));
|
||||
painter.fill_rect(rect_to_draw, PaintableWidget::the().color_for(m_drawing_button));
|
||||
break;
|
||||
case Mode::Outline:
|
||||
painter.draw_rect(rect_to_draw, m_widget->color_for(m_drawing_button));
|
||||
painter.draw_rect(rect_to_draw, PaintableWidget::the().color_for(m_drawing_button));
|
||||
break;
|
||||
case Mode::Gradient:
|
||||
painter.fill_rect_with_gradient(rect_to_draw, m_widget->primary_color(), m_widget->secondary_color());
|
||||
painter.fill_rect_with_gradient(rect_to_draw, PaintableWidget::the().primary_color(), PaintableWidget::the().secondary_color());
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
void RectangleTool::on_mousedown(GUI::MouseEvent& event)
|
||||
void RectangleTool::on_mousedown(Layer&, GUI::MouseEvent& event)
|
||||
{
|
||||
if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
|
||||
return;
|
||||
|
@ -69,29 +73,29 @@ void RectangleTool::on_mousedown(GUI::MouseEvent& event)
|
|||
m_drawing_button = event.button();
|
||||
m_rectangle_start_position = event.position();
|
||||
m_rectangle_end_position = event.position();
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
}
|
||||
|
||||
void RectangleTool::on_mouseup(GUI::MouseEvent& event)
|
||||
void RectangleTool::on_mouseup(Layer& layer, GUI::MouseEvent& event)
|
||||
{
|
||||
if (event.button() == m_drawing_button) {
|
||||
GUI::Painter painter(m_widget->bitmap());
|
||||
GUI::Painter painter(layer.bitmap());
|
||||
draw_using(painter);
|
||||
m_drawing_button = GUI::MouseButton::None;
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
}
|
||||
}
|
||||
|
||||
void RectangleTool::on_mousemove(GUI::MouseEvent& event)
|
||||
void RectangleTool::on_mousemove(Layer&, GUI::MouseEvent& event)
|
||||
{
|
||||
if (m_drawing_button == GUI::MouseButton::None)
|
||||
return;
|
||||
|
||||
if (!m_widget->rect().contains(event.position()))
|
||||
if (!m_editor->rect().contains(event.position()))
|
||||
return;
|
||||
|
||||
m_rectangle_end_position = event.position();
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
}
|
||||
|
||||
void RectangleTool::on_second_paint(GUI::PaintEvent& event)
|
||||
|
@ -99,16 +103,19 @@ void RectangleTool::on_second_paint(GUI::PaintEvent& event)
|
|||
if (m_drawing_button == GUI::MouseButton::None)
|
||||
return;
|
||||
|
||||
(void)event;
|
||||
#if 0
|
||||
GUI::Painter painter(*m_widget);
|
||||
painter.add_clip_rect(event.rect());
|
||||
draw_using(painter);
|
||||
#endif
|
||||
}
|
||||
|
||||
void RectangleTool::on_keydown(GUI::KeyEvent& event)
|
||||
{
|
||||
if (event.key() == Key_Escape && m_drawing_button != GUI::MouseButton::None) {
|
||||
m_drawing_button = GUI::MouseButton::None;
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
event.accept();
|
||||
}
|
||||
}
|
||||
|
@ -129,3 +136,5 @@ void RectangleTool::on_contextmenu(GUI::ContextMenuEvent& event)
|
|||
}
|
||||
m_context_menu->popup(event.screen_position());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,15 +28,18 @@
|
|||
|
||||
#include "Tool.h"
|
||||
#include <LibGfx/Point.h>
|
||||
#include <LibGUI/Forward.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
class RectangleTool final : public Tool {
|
||||
public:
|
||||
RectangleTool();
|
||||
virtual ~RectangleTool() override;
|
||||
|
||||
virtual void on_mousedown(GUI::MouseEvent&) override;
|
||||
virtual void on_mousemove(GUI::MouseEvent&) override;
|
||||
virtual void on_mouseup(GUI::MouseEvent&) override;
|
||||
virtual void on_mousedown(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_mousemove(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_mouseup(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_contextmenu(GUI::ContextMenuEvent&) override;
|
||||
virtual void on_second_paint(GUI::PaintEvent&) override;
|
||||
virtual void on_keydown(GUI::KeyEvent&) override;
|
||||
|
@ -57,3 +60,5 @@ private:
|
|||
RefPtr<GUI::Menu> m_context_menu;
|
||||
Mode m_mode { Mode::Outline };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,15 +25,19 @@
|
|||
*/
|
||||
|
||||
#include "SprayTool.h"
|
||||
#include "ImageEditor.h"
|
||||
#include "Layer.h"
|
||||
#include "PaintableWidget.h"
|
||||
#include <AK/Queue.h>
|
||||
#include <AK/SinglyLinkedList.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGUI/Action.h>
|
||||
#include <LibGUI/Menu.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <stdio.h>
|
||||
#include <LibM/math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
SprayTool::SprayTool()
|
||||
{
|
||||
|
@ -55,10 +59,14 @@ static double nrand()
|
|||
|
||||
void SprayTool::paint_it()
|
||||
{
|
||||
GUI::Painter painter(m_widget->bitmap());
|
||||
auto& bitmap = m_widget->bitmap();
|
||||
auto* layer = m_editor->active_layer();
|
||||
if (!layer)
|
||||
return;
|
||||
|
||||
auto& bitmap = layer->bitmap();
|
||||
GUI::Painter painter(bitmap);
|
||||
ASSERT(bitmap.bpp() == 32);
|
||||
m_widget->update();
|
||||
m_editor->update();
|
||||
const double minimal_radius = 10;
|
||||
const double base_radius = minimal_radius * m_thickness;
|
||||
for (int i = 0; i < 100 + (nrand() * 800); i++) {
|
||||
|
@ -74,18 +82,18 @@ void SprayTool::paint_it()
|
|||
}
|
||||
}
|
||||
|
||||
void SprayTool::on_mousedown(GUI::MouseEvent& event)
|
||||
void SprayTool::on_mousedown(Layer&, GUI::MouseEvent& event)
|
||||
{
|
||||
if (!m_widget->rect().contains(event.position()))
|
||||
if (!m_editor->rect().contains(event.position()))
|
||||
return;
|
||||
|
||||
m_color = m_widget->color_for(event);
|
||||
m_color = PaintableWidget::the().color_for(event);
|
||||
m_last_pos = event.position();
|
||||
m_timer->start();
|
||||
paint_it();
|
||||
}
|
||||
|
||||
void SprayTool::on_mousemove(GUI::MouseEvent& event)
|
||||
void SprayTool::on_mousemove(Layer&, GUI::MouseEvent& event)
|
||||
{
|
||||
m_last_pos = event.position();
|
||||
if (m_timer->is_active()) {
|
||||
|
@ -94,7 +102,7 @@ void SprayTool::on_mousemove(GUI::MouseEvent& event)
|
|||
}
|
||||
}
|
||||
|
||||
void SprayTool::on_mouseup(GUI::MouseEvent&)
|
||||
void SprayTool::on_mouseup(Layer&, GUI::MouseEvent&)
|
||||
{
|
||||
m_timer->stop();
|
||||
}
|
||||
|
@ -120,3 +128,4 @@ void SprayTool::on_contextmenu(GUI::ContextMenuEvent& event)
|
|||
m_context_menu->popup(event.screen_position());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,14 +31,16 @@
|
|||
#include <LibGUI/ActionGroup.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
class SprayTool final : public Tool {
|
||||
public:
|
||||
SprayTool();
|
||||
virtual ~SprayTool() override;
|
||||
|
||||
virtual void on_mousedown(GUI::MouseEvent&) override;
|
||||
virtual void on_mouseup(GUI::MouseEvent&) override;
|
||||
virtual void on_mousemove(GUI::MouseEvent&) override;
|
||||
virtual void on_mousedown(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_mouseup(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_mousemove(Layer&, GUI::MouseEvent&) override;
|
||||
virtual void on_contextmenu(GUI::ContextMenuEvent&) override;
|
||||
|
||||
private:
|
||||
|
@ -51,3 +53,5 @@ private:
|
|||
GUI::ActionGroup m_thickness_actions;
|
||||
int m_thickness { 1 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
*/
|
||||
|
||||
#include "Tool.h"
|
||||
#include "ImageEditor.h"
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
Tool::Tool()
|
||||
{
|
||||
|
@ -33,3 +36,10 @@ Tool::Tool()
|
|||
Tool::~Tool()
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::setup(ImageEditor& editor)
|
||||
{
|
||||
m_editor = editor.make_weak_ptr();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "PaintableWidget.h"
|
||||
#include <LibGUI/Event.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
class ImageEditor;
|
||||
class Layer;
|
||||
|
||||
class Tool {
|
||||
public:
|
||||
|
@ -34,18 +39,20 @@ public:
|
|||
|
||||
virtual const char* class_name() const = 0;
|
||||
|
||||
virtual void on_mousedown(GUI::MouseEvent&) {}
|
||||
virtual void on_mousemove(GUI::MouseEvent&) {}
|
||||
virtual void on_mouseup(GUI::MouseEvent&) {}
|
||||
virtual void on_mousedown(Layer&, GUI::MouseEvent&) {}
|
||||
virtual void on_mousemove(Layer&, GUI::MouseEvent&) {}
|
||||
virtual void on_mouseup(Layer&, GUI::MouseEvent&) {}
|
||||
virtual void on_contextmenu(GUI::ContextMenuEvent&) {}
|
||||
virtual void on_second_paint(GUI::PaintEvent&) {}
|
||||
virtual void on_keydown(GUI::KeyEvent&) {}
|
||||
virtual void on_keyup(GUI::KeyEvent&) {}
|
||||
|
||||
void clear() { m_widget = nullptr; }
|
||||
void setup(PaintableWidget& widget) { m_widget = widget.make_weak_ptr(); }
|
||||
void clear() { m_editor = nullptr; }
|
||||
void setup(ImageEditor&);
|
||||
|
||||
protected:
|
||||
Tool();
|
||||
WeakPtr<PaintableWidget> m_widget;
|
||||
WeakPtr<ImageEditor> m_editor;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include <LibGUI/BoxLayout.h>
|
||||
#include <LibGUI/Button.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
class ToolButton final : public GUI::Button {
|
||||
C_OBJECT(ToolButton)
|
||||
public:
|
||||
|
@ -82,11 +84,11 @@ ToolboxWidget::ToolboxWidget()
|
|||
|
||||
button.set_icon(Gfx::Bitmap::load_from_file(String::format("/res/icons/paintbrush/%s.png", icon_name.to_string().characters())));
|
||||
|
||||
button.on_checked = [button = &button](auto checked) {
|
||||
button.on_checked = [this, button = &button](auto checked) {
|
||||
if (checked)
|
||||
PaintableWidget::the().set_tool(&button->tool());
|
||||
on_tool_selection(&button->tool());
|
||||
else
|
||||
PaintableWidget::the().set_tool(nullptr);
|
||||
on_tool_selection(nullptr);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -103,3 +105,5 @@ ToolboxWidget::ToolboxWidget()
|
|||
ToolboxWidget::~ToolboxWidget()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,9 +28,19 @@
|
|||
|
||||
#include <LibGUI/Frame.h>
|
||||
|
||||
namespace PaintBrush {
|
||||
|
||||
class Tool;
|
||||
|
||||
class ToolboxWidget final : public GUI::Frame {
|
||||
C_OBJECT(ToolboxWidget)
|
||||
public:
|
||||
explicit ToolboxWidget();
|
||||
virtual ~ToolboxWidget() override;
|
||||
|
||||
Function<void(Tool*)> on_tool_selection;
|
||||
|
||||
private:
|
||||
explicit ToolboxWidget();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ int main(int argc, char** argv)
|
|||
horizontal_container.set_layout<GUI::HorizontalBoxLayout>();
|
||||
horizontal_container.layout()->set_spacing(0);
|
||||
|
||||
horizontal_container.add<ToolboxWidget>();
|
||||
auto& toolbox = horizontal_container.add<PaintBrush::ToolboxWidget>();
|
||||
|
||||
auto& vertical_container = horizontal_container.add<GUI::Widget>();
|
||||
vertical_container.set_layout<GUI::VerticalBoxLayout>();
|
||||
|
@ -76,6 +76,10 @@ int main(int argc, char** argv)
|
|||
auto& image_editor = vertical_container.add<PaintBrush::ImageEditor>();
|
||||
image_editor.set_focus(true);
|
||||
|
||||
toolbox.on_tool_selection = [&](auto* tool) {
|
||||
image_editor.set_active_tool(tool);
|
||||
};
|
||||
|
||||
auto& paintable_widget = vertical_container.add<PaintableWidget>();
|
||||
paintable_widget.set_size_policy(GUI::SizePolicy::Fixed, GUI::SizePolicy::Fixed);
|
||||
paintable_widget.set_preferred_size(0, 0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue