mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:57:45 +00:00
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
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));
|
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());
|
Gfx::Rect r = build_rect(event.position(), layer.rect());
|
||||||
GUI::Painter painter(layer.bitmap());
|
GUI::Painter painter(layer.bitmap());
|
||||||
painter.clear_rect(r, get_color());
|
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&)
|
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());
|
Gfx::Rect r = build_rect(event.position(), layer.rect());
|
||||||
GUI::Painter painter(layer.bitmap());
|
GUI::Painter painter(layer.bitmap());
|
||||||
painter.clear_rect(r, get_color());
|
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);
|
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:
|
public:
|
||||||
virtual void image_did_add_layer(size_t) { }
|
virtual void image_did_add_layer(size_t) { }
|
||||||
virtual void image_did_remove_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> {
|
class Image : public RefCounted<Image> {
|
||||||
|
@ -72,9 +73,13 @@ public:
|
||||||
void add_client(ImageClient&);
|
void add_client(ImageClient&);
|
||||||
void remove_client(ImageClient&);
|
void remove_client(ImageClient&);
|
||||||
|
|
||||||
|
void layer_did_modify_bitmap(Badge<Layer>, const Layer&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Image(const Gfx::Size&);
|
explicit Image(const Gfx::Size&);
|
||||||
|
|
||||||
|
void did_change();
|
||||||
|
|
||||||
size_t index_of(const Layer&) const;
|
size_t index_of(const Layer&) const;
|
||||||
|
|
||||||
Gfx::Size m_size;
|
Gfx::Size m_size;
|
||||||
|
|
|
@ -353,4 +353,9 @@ void ImageEditor::relayout()
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageEditor::image_did_change()
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,16 +26,18 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Image.h"
|
||||||
#include <LibGUI/Frame.h>
|
#include <LibGUI/Frame.h>
|
||||||
#include <LibGfx/FloatPoint.h>
|
#include <LibGfx/FloatPoint.h>
|
||||||
|
|
||||||
namespace PixelPaint {
|
namespace PixelPaint {
|
||||||
|
|
||||||
class Image;
|
|
||||||
class Layer;
|
class Layer;
|
||||||
class Tool;
|
class Tool;
|
||||||
|
|
||||||
class ImageEditor final : public GUI::Frame {
|
class ImageEditor final
|
||||||
|
: public GUI::Frame
|
||||||
|
, public ImageClient {
|
||||||
C_OBJECT(ImageEditor);
|
C_OBJECT(ImageEditor);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -91,6 +93,8 @@ private:
|
||||||
virtual void context_menu_event(GUI::ContextMenuEvent&) override;
|
virtual void context_menu_event(GUI::ContextMenuEvent&) override;
|
||||||
virtual void resize_event(GUI::ResizeEvent&) 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_adjusted_for_layer(const GUI::MouseEvent&, const Layer&) const;
|
||||||
GUI::MouseEvent event_with_pan_and_scale_applied(const GUI::MouseEvent&) const;
|
GUI::MouseEvent event_with_pan_and_scale_applied(const GUI::MouseEvent&) const;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Layer.h"
|
#include "Layer.h"
|
||||||
|
#include "Image.h"
|
||||||
#include <LibGfx/Bitmap.h>
|
#include <LibGfx/Bitmap.h>
|
||||||
|
|
||||||
namespace PixelPaint {
|
namespace PixelPaint {
|
||||||
|
@ -46,4 +47,9 @@ Layer::Layer(const Gfx::Size& size, const String& name)
|
||||||
m_bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::RGBA32, size);
|
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 {
|
namespace PixelPaint {
|
||||||
|
|
||||||
|
class Image;
|
||||||
|
|
||||||
class Layer : public RefCounted<Layer> {
|
class Layer : public RefCounted<Layer> {
|
||||||
AK_MAKE_NONCOPYABLE(Layer);
|
AK_MAKE_NONCOPYABLE(Layer);
|
||||||
AK_MAKE_NONMOVABLE(Layer);
|
AK_MAKE_NONMOVABLE(Layer);
|
||||||
|
@ -55,6 +57,8 @@ public:
|
||||||
const String& name() const { return m_name; }
|
const String& name() const { return m_name; }
|
||||||
void set_name(const String& name) { m_name = name; }
|
void set_name(const String& name) { m_name = name; }
|
||||||
|
|
||||||
|
void did_modify_bitmap(Image&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Layer(const Gfx::Size&, const String& name);
|
explicit Layer(const Gfx::Size&, const String& name);
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ void LayerListWidget::image_did_remove_layer(size_t layer_index)
|
||||||
relayout_gadgets();
|
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);
|
update(m_gadgets[layer_index].rect);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ private:
|
||||||
|
|
||||||
virtual void image_did_add_layer(size_t) override;
|
virtual void image_did_add_layer(size_t) override;
|
||||||
virtual void image_did_remove_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();
|
void relayout_gadgets();
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ void LineTool::on_mouseup(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&
|
||||||
GUI::Painter painter(layer.bitmap());
|
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);
|
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_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());
|
GUI::Painter painter(layer.bitmap());
|
||||||
painter.draw_line(event.position(), event.position(), m_editor->color_for(event), m_thickness);
|
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();
|
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);
|
painter.draw_line(m_last_drawing_event_position, event.position(), m_editor->color_for(event), m_thickness);
|
||||||
else
|
else
|
||||||
painter.draw_line(event.position(), event.position(), m_editor->color_for(event), m_thickness);
|
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();
|
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);
|
auto rect = Gfx::Rect::from_two_points(m_rectangle_start_position, m_rectangle_end_position);
|
||||||
draw_using(painter, rect);
|
draw_using(painter, rect);
|
||||||
m_drawing_button = GUI::MouseButton::None;
|
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;
|
continue;
|
||||||
bitmap.set_pixel<Gfx::BitmapFormat::RGB32>(xpos, ypos, m_color);
|
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&)
|
void SprayTool::on_mousedown(Layer&, GUI::MouseEvent& event, GUI::MouseEvent&)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue