PixelPaint: Have layers and images send out notifications on changes
We use this to automatically update the thumbnail in LayerListWidget when you draw into a layer. We also use it to repaint the ImageEditor when the image changes somehow. :^)
This commit is contained in:
parent
de85cd0907
commit
dc3de47b03
Notes:
sideshowbarker
2024-07-19 06:08:07 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/dc3de47b039
14 changed files with 53 additions and 12 deletions
|
@ -87,7 +87,7 @@ void BucketTool::on_mousedown(Layer& layer, GUI::MouseEvent& event, GUI::MouseEv
|
|||
|
||||
flood_fill(layer.bitmap(), event.position(), target_color, m_editor->color_for(event));
|
||||
|
||||
m_editor->update();
|
||||
layer.did_modify_bitmap(*m_editor->image());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ void EraseTool::on_mousedown(Layer& layer, GUI::MouseEvent& event, GUI::MouseEve
|
|||
Gfx::Rect r = build_rect(event.position(), layer.rect());
|
||||
GUI::Painter painter(layer.bitmap());
|
||||
painter.clear_rect(r, get_color());
|
||||
m_editor->update();
|
||||
layer.did_modify_bitmap(*m_editor->image());
|
||||
}
|
||||
|
||||
void EraseTool::on_mousemove(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
|
||||
|
@ -68,7 +68,7 @@ void EraseTool::on_mousemove(Layer& layer, GUI::MouseEvent& event, GUI::MouseEve
|
|||
Gfx::Rect r = build_rect(event.position(), layer.rect());
|
||||
GUI::Painter painter(layer.bitmap());
|
||||
painter.clear_rect(r, get_color());
|
||||
m_editor->update();
|
||||
layer.did_modify_bitmap(*m_editor->image());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -146,4 +146,19 @@ void Image::remove_client(ImageClient& client)
|
|||
m_clients.remove(&client);
|
||||
}
|
||||
|
||||
void Image::layer_did_modify_bitmap(Badge<Layer>, const Layer& layer)
|
||||
{
|
||||
auto layer_index = index_of(layer);
|
||||
for (auto* client : m_clients)
|
||||
client->image_did_modify_layer(layer_index);
|
||||
|
||||
did_change();
|
||||
}
|
||||
|
||||
void Image::did_change()
|
||||
{
|
||||
for (auto* client : m_clients)
|
||||
client->image_did_change();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,8 @@ class ImageClient {
|
|||
public:
|
||||
virtual void image_did_add_layer(size_t) { }
|
||||
virtual void image_did_remove_layer(size_t) { }
|
||||
virtual void image_did_update_layer(size_t) { }
|
||||
virtual void image_did_modify_layer(size_t) { }
|
||||
virtual void image_did_change() { }
|
||||
};
|
||||
|
||||
class Image : public RefCounted<Image> {
|
||||
|
@ -72,9 +73,13 @@ public:
|
|||
void add_client(ImageClient&);
|
||||
void remove_client(ImageClient&);
|
||||
|
||||
void layer_did_modify_bitmap(Badge<Layer>, const Layer&);
|
||||
|
||||
private:
|
||||
explicit Image(const Gfx::Size&);
|
||||
|
||||
void did_change();
|
||||
|
||||
size_t index_of(const Layer&) const;
|
||||
|
||||
Gfx::Size m_size;
|
||||
|
|
|
@ -353,4 +353,9 @@ void ImageEditor::relayout()
|
|||
update();
|
||||
}
|
||||
|
||||
void ImageEditor::image_did_change()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,16 +26,18 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Image.h"
|
||||
#include <LibGUI/Frame.h>
|
||||
#include <LibGfx/FloatPoint.h>
|
||||
|
||||
namespace PixelPaint {
|
||||
|
||||
class Image;
|
||||
class Layer;
|
||||
class Tool;
|
||||
|
||||
class ImageEditor final : public GUI::Frame {
|
||||
class ImageEditor final
|
||||
: public GUI::Frame
|
||||
, public ImageClient {
|
||||
C_OBJECT(ImageEditor);
|
||||
|
||||
public:
|
||||
|
@ -91,6 +93,8 @@ private:
|
|||
virtual void context_menu_event(GUI::ContextMenuEvent&) override;
|
||||
virtual void resize_event(GUI::ResizeEvent&) override;
|
||||
|
||||
virtual void image_did_change() override;
|
||||
|
||||
GUI::MouseEvent event_adjusted_for_layer(const GUI::MouseEvent&, const Layer&) const;
|
||||
GUI::MouseEvent event_with_pan_and_scale_applied(const GUI::MouseEvent&) const;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*/
|
||||
|
||||
#include "Layer.h"
|
||||
#include "Image.h"
|
||||
#include <LibGfx/Bitmap.h>
|
||||
|
||||
namespace PixelPaint {
|
||||
|
@ -46,4 +47,9 @@ Layer::Layer(const Gfx::Size& size, const String& name)
|
|||
m_bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::RGBA32, size);
|
||||
}
|
||||
|
||||
void Layer::did_modify_bitmap(Image& image)
|
||||
{
|
||||
image.layer_did_modify_bitmap({}, *this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
|
||||
namespace PixelPaint {
|
||||
|
||||
class Image;
|
||||
|
||||
class Layer : public RefCounted<Layer> {
|
||||
AK_MAKE_NONCOPYABLE(Layer);
|
||||
AK_MAKE_NONMOVABLE(Layer);
|
||||
|
@ -55,6 +57,8 @@ public:
|
|||
const String& name() const { return m_name; }
|
||||
void set_name(const String& name) { m_name = name; }
|
||||
|
||||
void did_modify_bitmap(Image&);
|
||||
|
||||
private:
|
||||
explicit Layer(const Gfx::Size&, const String& name);
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ void LayerListWidget::image_did_remove_layer(size_t layer_index)
|
|||
relayout_gadgets();
|
||||
}
|
||||
|
||||
void LayerListWidget::image_did_update_layer(size_t layer_index)
|
||||
void LayerListWidget::image_did_modify_layer(size_t layer_index)
|
||||
{
|
||||
update(m_gadgets[layer_index].rect);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ private:
|
|||
|
||||
virtual void image_did_add_layer(size_t) override;
|
||||
virtual void image_did_remove_layer(size_t) override;
|
||||
virtual void image_did_update_layer(size_t);
|
||||
virtual void image_did_modify_layer(size_t);
|
||||
|
||||
void relayout_gadgets();
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ void LineTool::on_mouseup(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&
|
|||
GUI::Painter painter(layer.bitmap());
|
||||
painter.draw_line(m_line_start_position, m_line_end_position, m_editor->color_for(m_drawing_button), m_thickness);
|
||||
m_drawing_button = GUI::MouseButton::None;
|
||||
m_editor->update();
|
||||
layer.did_modify_bitmap(*m_editor->image());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ void PenTool::on_mousedown(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent
|
|||
|
||||
GUI::Painter painter(layer.bitmap());
|
||||
painter.draw_line(event.position(), event.position(), m_editor->color_for(event), m_thickness);
|
||||
m_editor->update();
|
||||
layer.did_modify_bitmap(*m_editor->image());
|
||||
m_last_drawing_event_position = event.position();
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ void PenTool::on_mousemove(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent
|
|||
painter.draw_line(m_last_drawing_event_position, event.position(), m_editor->color_for(event), m_thickness);
|
||||
else
|
||||
painter.draw_line(event.position(), event.position(), m_editor->color_for(event), m_thickness);
|
||||
m_editor->update();
|
||||
layer.did_modify_bitmap(*m_editor->image());
|
||||
|
||||
m_last_drawing_event_position = event.position();
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ void RectangleTool::on_mouseup(Layer& layer, GUI::MouseEvent& event, GUI::MouseE
|
|||
auto rect = Gfx::Rect::from_two_points(m_rectangle_start_position, m_rectangle_end_position);
|
||||
draw_using(painter, rect);
|
||||
m_drawing_button = GUI::MouseButton::None;
|
||||
m_editor->update();
|
||||
layer.did_modify_bitmap(*m_editor->image());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,8 @@ void SprayTool::paint_it()
|
|||
continue;
|
||||
bitmap.set_pixel<Gfx::BitmapFormat::RGB32>(xpos, ypos, m_color);
|
||||
}
|
||||
|
||||
layer->did_modify_bitmap(*m_editor->image());
|
||||
}
|
||||
|
||||
void SprayTool::on_mousedown(Layer&, GUI::MouseEvent& event, GUI::MouseEvent&)
|
||||
|
|
Loading…
Add table
Reference in a new issue