Ver Fonte

PixelPaint: Pass raw mouse event to Tools and wrap them all in a struct

This commit adds a Tool::MouseEvent struct, which contains events that
may be needed by tools: layer-relative, image-relative and raw (editor-
relative) event.

The raw event is used by ZoomTool to properly pan the view. This fixes
a bug which caused image to snap out of sight.
Maciej Zygmanowski há 4 anos atrás
pai
commit
0224dc2882
28 ficheiros alterados com 186 adições e 127 exclusões
  1. 13 11
      Userland/Applications/PixelPaint/BrushTool.cpp
  2. 3 3
      Userland/Applications/PixelPaint/BrushTool.h
  3. 5 4
      Userland/Applications/PixelPaint/BucketTool.cpp
  4. 1 1
      Userland/Applications/PixelPaint/BucketTool.h
  5. 10 9
      Userland/Applications/PixelPaint/EllipseTool.cpp
  6. 3 3
      Userland/Applications/PixelPaint/EllipseTool.h
  7. 11 8
      Userland/Applications/PixelPaint/EraseTool.cpp
  8. 3 3
      Userland/Applications/PixelPaint/EraseTool.h
  9. 7 4
      Userland/Applications/PixelPaint/GuideTool.cpp
  10. 3 3
      Userland/Applications/PixelPaint/GuideTool.h
  11. 7 4
      Userland/Applications/PixelPaint/ImageEditor.cpp
  12. 7 4
      Userland/Applications/PixelPaint/LineTool.cpp
  13. 3 3
      Userland/Applications/PixelPaint/LineTool.h
  14. 10 6
      Userland/Applications/PixelPaint/MoveTool.cpp
  15. 3 3
      Userland/Applications/PixelPaint/MoveTool.h
  16. 17 14
      Userland/Applications/PixelPaint/PenTool.cpp
  17. 3 3
      Userland/Applications/PixelPaint/PenTool.h
  18. 6 5
      Userland/Applications/PixelPaint/PickerTool.cpp
  19. 1 1
      Userland/Applications/PixelPaint/PickerTool.h
  20. 6 3
      Userland/Applications/PixelPaint/RectangleSelectTool.cpp
  21. 3 3
      Userland/Applications/PixelPaint/RectangleSelectTool.h
  22. 10 9
      Userland/Applications/PixelPaint/RectangleTool.cpp
  23. 3 3
      Userland/Applications/PixelPaint/RectangleTool.h
  24. 7 6
      Userland/Applications/PixelPaint/SprayTool.cpp
  25. 3 3
      Userland/Applications/PixelPaint/SprayTool.h
  26. 32 3
      Userland/Applications/PixelPaint/Tool.h
  27. 5 4
      Userland/Applications/PixelPaint/ZoomTool.cpp
  28. 1 1
      Userland/Applications/PixelPaint/ZoomTool.h

+ 13 - 11
Userland/Applications/PixelPaint/BrushTool.cpp

@@ -25,35 +25,37 @@ BrushTool::~BrushTool()
 {
 }
 
-void BrushTool::on_mousedown(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
+void BrushTool::on_mousedown(Layer& layer, MouseEvent& event)
 {
-    if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
+    auto& layer_event = event.layer_event();
+    if (layer_event.button() != GUI::MouseButton::Left && layer_event.button() != GUI::MouseButton::Right)
         return;
 
     const int first_draw_opacity = 10;
 
     for (int i = 0; i < first_draw_opacity; ++i)
-        draw_point(layer.bitmap(), m_editor->color_for(event), event.position());
+        draw_point(layer.bitmap(), m_editor->color_for(layer_event), layer_event.position());
 
-    layer.did_modify_bitmap(Gfx::IntRect::centered_on(event.position(), Gfx::IntSize { m_size * 2, m_size * 2 }));
-    m_last_position = event.position();
+    layer.did_modify_bitmap(Gfx::IntRect::centered_on(layer_event.position(), Gfx::IntSize { m_size * 2, m_size * 2 }));
+    m_last_position = layer_event.position();
 }
 
-void BrushTool::on_mousemove(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
+void BrushTool::on_mousemove(Layer& layer, MouseEvent& event)
 {
-    if (!(event.buttons() & GUI::MouseButton::Left || event.buttons() & GUI::MouseButton::Right))
+    auto& layer_event = event.layer_event();
+    if (!(layer_event.buttons() & GUI::MouseButton::Left || layer_event.buttons() & GUI::MouseButton::Right))
         return;
 
-    draw_line(layer.bitmap(), m_editor->color_for(event), m_last_position, event.position());
+    draw_line(layer.bitmap(), m_editor->color_for(layer_event), m_last_position, layer_event.position());
 
-    auto modified_rect = Gfx::IntRect::from_two_points(m_last_position, event.position()).inflated(m_size * 2, m_size * 2);
+    auto modified_rect = Gfx::IntRect::from_two_points(m_last_position, layer_event.position()).inflated(m_size * 2, m_size * 2);
 
     layer.did_modify_bitmap(modified_rect);
-    m_last_position = event.position();
+    m_last_position = layer_event.position();
     m_was_drawing = true;
 }
 
-void BrushTool::on_mouseup(Layer&, GUI::MouseEvent&, GUI::MouseEvent&)
+void BrushTool::on_mouseup(Layer&, MouseEvent&)
 {
     if (m_was_drawing) {
         m_editor->did_complete_action();

+ 3 - 3
Userland/Applications/PixelPaint/BrushTool.h

@@ -15,9 +15,9 @@ public:
     BrushTool();
     virtual ~BrushTool() override;
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mousemove(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mouseup(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
+    virtual void on_mousedown(Layer&, MouseEvent&) override;
+    virtual void on_mousemove(Layer&, MouseEvent&) override;
+    virtual void on_mouseup(Layer&, MouseEvent&) override;
     virtual GUI::Widget* get_properties_widget() override;
     virtual Gfx::StandardCursor cursor() override { return Gfx::StandardCursor::Crosshair; }
 

+ 5 - 4
Userland/Applications/PixelPaint/BucketTool.cpp

@@ -70,15 +70,16 @@ static void flood_fill(Gfx::Bitmap& bitmap, Gfx::IntPoint const& start_position,
     }
 }
 
-void BucketTool::on_mousedown(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
+void BucketTool::on_mousedown(Layer& layer, MouseEvent& event)
 {
-    if (!layer.rect().contains(event.position()))
+    auto& layer_event = event.layer_event();
+    if (!layer.rect().contains(layer_event.position()))
         return;
 
     GUI::Painter painter(layer.bitmap());
-    auto target_color = layer.bitmap().get_pixel(event.x(), event.y());
+    auto target_color = layer.bitmap().get_pixel(layer_event.x(), layer_event.y());
 
-    flood_fill(layer.bitmap(), event.position(), target_color, m_editor->color_for(event), m_threshold);
+    flood_fill(layer.bitmap(), layer_event.position(), target_color, m_editor->color_for(layer_event), m_threshold);
 
     layer.did_modify_bitmap();
     m_editor->did_complete_action();

+ 1 - 1
Userland/Applications/PixelPaint/BucketTool.h

@@ -15,7 +15,7 @@ public:
     BucketTool();
     virtual ~BucketTool() override;
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
+    virtual void on_mousedown(Layer&, MouseEvent&) override;
     virtual GUI::Widget* get_properties_widget() override;
 
 private:

+ 10 - 9
Userland/Applications/PixelPaint/EllipseTool.cpp

@@ -40,23 +40,24 @@ void EllipseTool::draw_using(GUI::Painter& painter, Gfx::IntRect const& ellipse_
     }
 }
 
-void EllipseTool::on_mousedown(Layer&, GUI::MouseEvent& event, GUI::MouseEvent&)
+void EllipseTool::on_mousedown(Layer&, MouseEvent& event)
 {
-    if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
+    auto& layer_event = event.layer_event();
+    if (layer_event.button() != GUI::MouseButton::Left && layer_event.button() != GUI::MouseButton::Right)
         return;
 
     if (m_drawing_button != GUI::MouseButton::None)
         return;
 
-    m_drawing_button = event.button();
-    m_ellipse_start_position = event.position();
-    m_ellipse_end_position = event.position();
+    m_drawing_button = layer_event.button();
+    m_ellipse_start_position = layer_event.position();
+    m_ellipse_end_position = layer_event.position();
     m_editor->update();
 }
 
-void EllipseTool::on_mouseup(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
+void EllipseTool::on_mouseup(Layer& layer, MouseEvent& event)
 {
-    if (event.button() == m_drawing_button) {
+    if (event.layer_event().button() == m_drawing_button) {
         GUI::Painter painter(layer.bitmap());
         draw_using(painter, Gfx::IntRect::from_two_points(m_ellipse_start_position, m_ellipse_end_position));
         m_drawing_button = GUI::MouseButton::None;
@@ -65,12 +66,12 @@ void EllipseTool::on_mouseup(Layer& layer, GUI::MouseEvent& event, GUI::MouseEve
     }
 }
 
-void EllipseTool::on_mousemove(Layer&, GUI::MouseEvent& event, GUI::MouseEvent&)
+void EllipseTool::on_mousemove(Layer&, MouseEvent& event)
 {
     if (m_drawing_button == GUI::MouseButton::None)
         return;
 
-    m_ellipse_end_position = event.position();
+    m_ellipse_end_position = event.layer_event().position();
     m_editor->update();
 }
 

+ 3 - 3
Userland/Applications/PixelPaint/EllipseTool.h

@@ -17,9 +17,9 @@ public:
     EllipseTool();
     virtual ~EllipseTool() override;
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mousemove(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mouseup(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
+    virtual void on_mousedown(Layer&, MouseEvent&) override;
+    virtual void on_mousemove(Layer&, MouseEvent&) override;
+    virtual void on_mouseup(Layer&, MouseEvent&) override;
     virtual void on_second_paint(Layer const&, GUI::PaintEvent&) override;
     virtual void on_keydown(GUI::KeyEvent&) override;
     virtual GUI::Widget* get_properties_widget() override;

+ 11 - 8
Userland/Applications/PixelPaint/EraseTool.cpp

@@ -35,29 +35,32 @@ Gfx::IntRect EraseTool::build_rect(Gfx::IntPoint const& pos, Gfx::IntRect const&
     return Gfx::IntRect(ex - eraser_radius, ey - eraser_radius, eraser_size, eraser_size).intersected(widget_rect);
 }
 
-void EraseTool::on_mousedown(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
+void EraseTool::on_mousedown(Layer& layer, MouseEvent& event)
 {
-    if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
+    auto& layer_event = event.layer_event();
+    if (layer_event.button() != GUI::MouseButton::Left && layer_event.button() != GUI::MouseButton::Right)
         return;
-    Gfx::IntRect r = build_rect(event.position(), layer.rect());
+    Gfx::IntRect r = build_rect(layer_event.position(), layer.rect());
     GUI::Painter painter(layer.bitmap());
     painter.clear_rect(r, get_color());
     layer.did_modify_bitmap(r.inflated(2, 2));
 }
 
-void EraseTool::on_mousemove(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
+void EraseTool::on_mousemove(Layer& layer, MouseEvent& event)
 {
-    if (event.buttons() & GUI::MouseButton::Left || event.buttons() & GUI::MouseButton::Right) {
-        Gfx::IntRect r = build_rect(event.position(), layer.rect());
+    auto& layer_event = event.layer_event();
+    if (layer_event.buttons() & GUI::MouseButton::Left || layer_event.buttons() & GUI::MouseButton::Right) {
+        Gfx::IntRect r = build_rect(layer_event.position(), layer.rect());
         GUI::Painter painter(layer.bitmap());
         painter.clear_rect(r, get_color());
         layer.did_modify_bitmap(r.inflated(2, 2));
     }
 }
 
-void EraseTool::on_mouseup(Layer&, GUI::MouseEvent& event, GUI::MouseEvent&)
+void EraseTool::on_mouseup(Layer&, MouseEvent& event)
 {
-    if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
+    auto& layer_event = event.layer_event();
+    if (layer_event.button() != GUI::MouseButton::Left && layer_event.button() != GUI::MouseButton::Right)
         return;
     m_editor->did_complete_action();
 }

+ 3 - 3
Userland/Applications/PixelPaint/EraseTool.h

@@ -18,9 +18,9 @@ public:
     EraseTool();
     virtual ~EraseTool() override;
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mousemove(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mouseup(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
+    virtual void on_mousedown(Layer&, MouseEvent& event) override;
+    virtual void on_mousemove(Layer&, MouseEvent& event) override;
+    virtual void on_mouseup(Layer&, MouseEvent& event) override;
     virtual GUI::Widget* get_properties_widget() override;
 
 private:

+ 7 - 4
Userland/Applications/PixelPaint/GuideTool.cpp

@@ -49,12 +49,14 @@ RefPtr<Guide> GuideTool::closest_guide(const Gfx::IntPoint& point)
     return nullptr;
 }
 
-void GuideTool::on_mousedown(Layer&, GUI::MouseEvent& mouse_event, GUI::MouseEvent& image_event)
+void GuideTool::on_mousedown(Layer&, MouseEvent& event)
 {
     if (!m_editor)
         return;
 
-    if (mouse_event.button() != GUI::MouseButton::Left)
+    auto& image_event = event.image_event();
+
+    if (image_event.button() != GUI::MouseButton::Left)
         return;
 
     m_editor->set_guide_visibility(true);
@@ -83,7 +85,7 @@ void GuideTool::on_mousedown(Layer&, GUI::MouseEvent& mouse_event, GUI::MouseEve
     }
 }
 
-void GuideTool::on_mouseup(Layer&, GUI::MouseEvent&, GUI::MouseEvent&)
+void GuideTool::on_mouseup(Layer&, MouseEvent&)
 {
     m_guide_origin = 0;
     m_event_origin = { 0, 0 };
@@ -102,11 +104,12 @@ void GuideTool::on_mouseup(Layer&, GUI::MouseEvent&, GUI::MouseEvent&)
     m_selected_guide = nullptr;
 }
 
-void GuideTool::on_mousemove(Layer&, GUI::MouseEvent&, GUI::MouseEvent& image_event)
+void GuideTool::on_mousemove(Layer&, MouseEvent& event)
 {
     if (!m_selected_guide)
         return;
 
+    auto& image_event = event.image_event();
     auto delta = image_event.position() - m_event_origin;
 
     auto relevant_offset = 0;

+ 3 - 3
Userland/Applications/PixelPaint/GuideTool.h

@@ -18,9 +18,9 @@ public:
 
     virtual ~GuideTool() override;
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mousemove(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mouseup(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
+    virtual void on_mousedown(Layer&, MouseEvent&) override;
+    virtual void on_mousemove(Layer&, MouseEvent&) override;
+    virtual void on_mouseup(Layer&, MouseEvent&) override;
     virtual void on_context_menu(Layer&, GUI::ContextMenuEvent&) override;
 
     virtual void on_tool_activation() override;

+ 7 - 4
Userland/Applications/PixelPaint/ImageEditor.cpp

@@ -199,7 +199,8 @@ void ImageEditor::mousedown_event(GUI::MouseEvent& event)
 
     auto layer_event = event_adjusted_for_layer(event, *m_active_layer);
     auto image_event = event_with_pan_and_scale_applied(event);
-    m_active_tool->on_mousedown(*m_active_layer, layer_event, image_event);
+    Tool::MouseEvent tool_event(Tool::MouseEvent::Action::MouseDown, layer_event, image_event, event);
+    m_active_tool->on_mousedown(*m_active_layer, tool_event);
 }
 
 void ImageEditor::mousemove_event(GUI::MouseEvent& event)
@@ -216,10 +217,11 @@ 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);
     auto image_event = event_with_pan_and_scale_applied(event);
-
-    m_active_tool->on_mousemove(*m_active_layer, layer_event, image_event);
+    Tool::MouseEvent tool_event(Tool::MouseEvent::Action::MouseDown, layer_event, image_event, event);
+    m_active_tool->on_mousemove(*m_active_layer, tool_event);
 
     if (on_image_mouse_position_change) {
         on_image_mouse_position_change(image_event.position());
@@ -234,7 +236,8 @@ void ImageEditor::mouseup_event(GUI::MouseEvent& event)
         return;
     auto layer_event = event_adjusted_for_layer(event, *m_active_layer);
     auto image_event = event_with_pan_and_scale_applied(event);
-    m_active_tool->on_mouseup(*m_active_layer, layer_event, image_event);
+    Tool::MouseEvent tool_event(Tool::MouseEvent::Action::MouseDown, layer_event, image_event, event);
+    m_active_tool->on_mouseup(*m_active_layer, tool_event);
 }
 
 void ImageEditor::mousewheel_event(GUI::MouseEvent& event)

+ 7 - 4
Userland/Applications/PixelPaint/LineTool.cpp

@@ -38,8 +38,9 @@ LineTool::~LineTool()
 {
 }
 
-void LineTool::on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent&)
+void LineTool::on_mousedown(Layer&, MouseEvent& event)
 {
+    auto& layer_event = event.layer_event();
     if (layer_event.button() != GUI::MouseButton::Left && layer_event.button() != GUI::MouseButton::Right)
         return;
 
@@ -54,9 +55,10 @@ void LineTool::on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEven
     m_editor->update();
 }
 
-void LineTool::on_mouseup(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
+void LineTool::on_mouseup(Layer& layer, MouseEvent& event)
 {
-    if (event.button() == m_drawing_button) {
+    auto& layer_event = event.layer_event();
+    if (layer_event.button() == m_drawing_button) {
         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;
@@ -65,8 +67,9 @@ void LineTool::on_mouseup(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&
     }
 }
 
-void LineTool::on_mousemove(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent&)
+void LineTool::on_mousemove(Layer&, MouseEvent& event)
 {
+    auto& layer_event = event.layer_event();
     if (m_drawing_button == GUI::MouseButton::None)
         return;
 

+ 3 - 3
Userland/Applications/PixelPaint/LineTool.h

@@ -17,9 +17,9 @@ public:
     LineTool();
     virtual ~LineTool() override;
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mousemove(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mouseup(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
+    virtual void on_mousedown(Layer&, MouseEvent&) override;
+    virtual void on_mousemove(Layer&, MouseEvent&) override;
+    virtual void on_mouseup(Layer&, MouseEvent&) override;
     virtual void on_second_paint(Layer const&, GUI::PaintEvent&) override;
     virtual void on_keydown(GUI::KeyEvent&) override;
     virtual GUI::Widget* get_properties_widget() override;

+ 10 - 6
Userland/Applications/PixelPaint/MoveTool.cpp

@@ -23,19 +23,22 @@ MoveTool::~MoveTool()
 {
 }
 
-void MoveTool::on_mousedown(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent& image_event)
+void MoveTool::on_mousedown(Layer& layer, MouseEvent& event)
 {
-    if (event.button() != GUI::MouseButton::Left)
+    auto& layer_event = event.layer_event();
+    auto& image_event = event.image_event();
+    if (layer_event.button() != GUI::MouseButton::Left)
         return;
-    if (!layer.rect().contains(event.position()))
+    if (!layer.rect().contains(layer_event.position()))
         return;
     m_layer_being_moved = layer;
     m_event_origin = image_event.position();
     m_layer_origin = layer.location();
 }
 
-void MoveTool::on_mousemove(Layer&, GUI::MouseEvent&, GUI::MouseEvent& image_event)
+void MoveTool::on_mousemove(Layer&, MouseEvent& event)
 {
+    auto& image_event = event.image_event();
     if (!m_layer_being_moved)
         return;
     auto delta = image_event.position() - m_event_origin;
@@ -43,9 +46,10 @@ void MoveTool::on_mousemove(Layer&, GUI::MouseEvent&, GUI::MouseEvent& image_eve
     m_editor->layers_did_change();
 }
 
-void MoveTool::on_mouseup(Layer&, GUI::MouseEvent& event, GUI::MouseEvent&)
+void MoveTool::on_mouseup(Layer&, MouseEvent& event)
 {
-    if (event.button() != GUI::MouseButton::Left)
+    auto& layer_event = event.layer_event();
+    if (layer_event.button() != GUI::MouseButton::Left)
         return;
     m_layer_being_moved = nullptr;
     m_editor->did_complete_action();

+ 3 - 3
Userland/Applications/PixelPaint/MoveTool.h

@@ -15,9 +15,9 @@ public:
     MoveTool();
     virtual ~MoveTool() override;
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mousemove(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mouseup(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
+    virtual void on_mousedown(Layer&, MouseEvent&) override;
+    virtual void on_mousemove(Layer&, MouseEvent&) override;
+    virtual void on_mouseup(Layer&, MouseEvent&) override;
     virtual void on_keydown(GUI::KeyEvent&) override;
     virtual Gfx::StandardCursor cursor() override { return Gfx::StandardCursor::Move; }
 

+ 17 - 14
Userland/Applications/PixelPaint/PenTool.cpp

@@ -24,43 +24,46 @@ PenTool::~PenTool()
 {
 }
 
-void PenTool::on_mousedown(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
+void PenTool::on_mousedown(Layer& layer, MouseEvent& event)
 {
-    if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
+    auto& layer_event = event.layer_event();
+    if (layer_event.button() != GUI::MouseButton::Left && layer_event.button() != GUI::MouseButton::Right)
         return;
 
     GUI::Painter painter(layer.bitmap());
-    painter.draw_line(event.position(), event.position(), m_editor->color_for(event), m_thickness);
-    layer.did_modify_bitmap(Gfx::IntRect::centered_on(event.position(), Gfx::IntSize { m_thickness + 2, m_thickness + 2 }));
-    m_last_drawing_event_position = event.position();
+    painter.draw_line(layer_event.position(), layer_event.position(), m_editor->color_for(layer_event), m_thickness);
+    layer.did_modify_bitmap(Gfx::IntRect::centered_on(layer_event.position(), Gfx::IntSize { m_thickness + 2, m_thickness + 2 }));
+    m_last_drawing_event_position = layer_event.position();
 }
 
-void PenTool::on_mouseup(Layer&, GUI::MouseEvent& event, GUI::MouseEvent&)
+void PenTool::on_mouseup(Layer&, MouseEvent& event)
 {
-    if (event.button() == GUI::MouseButton::Left || event.button() == GUI::MouseButton::Right) {
+    auto& layer_event = event.layer_event();
+    if (layer_event.button() == GUI::MouseButton::Left || layer_event.button() == GUI::MouseButton::Right) {
         m_last_drawing_event_position = { -1, -1 };
         m_editor->did_complete_action();
     }
 }
 
-void PenTool::on_mousemove(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
+void PenTool::on_mousemove(Layer& layer, MouseEvent& event)
 {
-    if (!(event.buttons() & GUI::MouseButton::Left || event.buttons() & GUI::MouseButton::Right))
+    auto& layer_event = event.layer_event();
+    if (!(layer_event.buttons() & GUI::MouseButton::Left || layer_event.buttons() & GUI::MouseButton::Right))
         return;
     GUI::Painter painter(layer.bitmap());
 
     Gfx::IntRect changed_rect;
     if (m_last_drawing_event_position != Gfx::IntPoint(-1, -1)) {
-        painter.draw_line(m_last_drawing_event_position, event.position(), m_editor->color_for(event), m_thickness);
-        changed_rect = Gfx::IntRect::from_two_points(m_last_drawing_event_position, event.position());
+        painter.draw_line(m_last_drawing_event_position, layer_event.position(), m_editor->color_for(layer_event), m_thickness);
+        changed_rect = Gfx::IntRect::from_two_points(m_last_drawing_event_position, layer_event.position());
     } else {
-        painter.draw_line(event.position(), event.position(), m_editor->color_for(event), m_thickness);
-        changed_rect = Gfx::IntRect::from_two_points(event.position(), event.position());
+        painter.draw_line(layer_event.position(), layer_event.position(), m_editor->color_for(layer_event), m_thickness);
+        changed_rect = Gfx::IntRect::from_two_points(layer_event.position(), layer_event.position());
     }
     changed_rect.inflate(m_thickness + 2, m_thickness + 2);
     layer.did_modify_bitmap(changed_rect);
 
-    m_last_drawing_event_position = event.position();
+    m_last_drawing_event_position = layer_event.position();
 }
 
 GUI::Widget* PenTool::get_properties_widget()

+ 3 - 3
Userland/Applications/PixelPaint/PenTool.h

@@ -17,9 +17,9 @@ public:
     PenTool();
     virtual ~PenTool() override;
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mousemove(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mouseup(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
+    virtual void on_mousedown(Layer&, MouseEvent&) override;
+    virtual void on_mousemove(Layer&, MouseEvent&) override;
+    virtual void on_mouseup(Layer&, MouseEvent&) override;
     virtual GUI::Widget* get_properties_widget() override;
     virtual Gfx::StandardCursor cursor() override { return Gfx::StandardCursor::Crosshair; }
 

+ 6 - 5
Userland/Applications/PixelPaint/PickerTool.cpp

@@ -18,14 +18,15 @@ PickerTool::~PickerTool()
 {
 }
 
-void PickerTool::on_mousedown(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
+void PickerTool::on_mousedown(Layer& layer, MouseEvent& event)
 {
-    if (!layer.rect().contains(event.position()))
+    auto& layer_event = event.layer_event();
+    if (!layer.rect().contains(layer_event.position()))
         return;
-    auto color = layer.bitmap().get_pixel(event.position());
-    if (event.button() == GUI::MouseButton::Left)
+    auto color = layer.bitmap().get_pixel(layer_event.position());
+    if (layer_event.button() == GUI::MouseButton::Left)
         m_editor->set_primary_color(color);
-    else if (event.button() == GUI::MouseButton::Right)
+    else if (layer_event.button() == GUI::MouseButton::Right)
         m_editor->set_secondary_color(color);
 }
 

+ 1 - 1
Userland/Applications/PixelPaint/PickerTool.h

@@ -15,7 +15,7 @@ public:
     PickerTool();
     virtual ~PickerTool() override;
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
+    virtual void on_mousedown(Layer&, MouseEvent&) override;
     virtual Gfx::StandardCursor cursor() override { return Gfx::StandardCursor::Crosshair; }
 };
 

+ 6 - 3
Userland/Applications/PixelPaint/RectangleSelectTool.cpp

@@ -26,8 +26,9 @@ RectangleSelectTool::~RectangleSelectTool()
 {
 }
 
-void RectangleSelectTool::on_mousedown(Layer&, GUI::MouseEvent&, GUI::MouseEvent& image_event)
+void RectangleSelectTool::on_mousedown(Layer&, MouseEvent& event)
 {
+    auto& image_event = event.image_event();
     if (image_event.button() != GUI::MouseButton::Left)
         return;
 
@@ -39,8 +40,9 @@ void RectangleSelectTool::on_mousedown(Layer&, GUI::MouseEvent&, GUI::MouseEvent
     m_editor->update();
 }
 
-void RectangleSelectTool::on_mousemove(Layer&, GUI::MouseEvent&, GUI::MouseEvent& image_event)
+void RectangleSelectTool::on_mousemove(Layer&, MouseEvent& event)
 {
+    auto& image_event = event.image_event();
     if (!m_selecting)
         return;
 
@@ -56,8 +58,9 @@ void RectangleSelectTool::on_mousemove(Layer&, GUI::MouseEvent&, GUI::MouseEvent
     m_editor->update();
 }
 
-void RectangleSelectTool::on_mouseup(Layer&, GUI::MouseEvent&, GUI::MouseEvent& image_event)
+void RectangleSelectTool::on_mouseup(Layer&, MouseEvent& event)
 {
+    auto& image_event = event.image_event();
     if (!m_selecting || image_event.button() != GUI::MouseButton::Left)
         return;
 

+ 3 - 3
Userland/Applications/PixelPaint/RectangleSelectTool.h

@@ -19,9 +19,9 @@ public:
     RectangleSelectTool();
     virtual ~RectangleSelectTool();
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent&, GUI::MouseEvent&) override;
-    virtual void on_mousemove(Layer&, GUI::MouseEvent&, GUI::MouseEvent&) override;
-    virtual void on_mouseup(Layer&, GUI::MouseEvent&, GUI::MouseEvent&) override;
+    virtual void on_mousedown(Layer&, MouseEvent& event) override;
+    virtual void on_mousemove(Layer&, MouseEvent& event) override;
+    virtual void on_mouseup(Layer&, MouseEvent& event) override;
     virtual void on_keydown(GUI::KeyEvent&) override;
     virtual void on_keyup(GUI::KeyEvent&) override;
     virtual void on_second_paint(Layer const&, GUI::PaintEvent&) override;

+ 10 - 9
Userland/Applications/PixelPaint/RectangleTool.cpp

@@ -42,23 +42,24 @@ void RectangleTool::draw_using(GUI::Painter& painter, Gfx::IntRect const& rect)
     }
 }
 
-void RectangleTool::on_mousedown(Layer&, GUI::MouseEvent& event, GUI::MouseEvent&)
+void RectangleTool::on_mousedown(Layer&, MouseEvent& event)
 {
-    if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
+    auto& layer_event = event.layer_event();
+    if (layer_event.button() != GUI::MouseButton::Left && layer_event.button() != GUI::MouseButton::Right)
         return;
 
     if (m_drawing_button != GUI::MouseButton::None)
         return;
 
-    m_drawing_button = event.button();
-    m_rectangle_start_position = event.position();
-    m_rectangle_end_position = event.position();
+    m_drawing_button = layer_event.button();
+    m_rectangle_start_position = layer_event.position();
+    m_rectangle_end_position = layer_event.position();
     m_editor->update();
 }
 
-void RectangleTool::on_mouseup(Layer& layer, GUI::MouseEvent& event, GUI::MouseEvent&)
+void RectangleTool::on_mouseup(Layer& layer, MouseEvent& event)
 {
-    if (event.button() == m_drawing_button) {
+    if (event.layer_event().button() == m_drawing_button) {
         GUI::Painter painter(layer.bitmap());
         auto rect = Gfx::IntRect::from_two_points(m_rectangle_start_position, m_rectangle_end_position);
         draw_using(painter, rect);
@@ -68,12 +69,12 @@ void RectangleTool::on_mouseup(Layer& layer, GUI::MouseEvent& event, GUI::MouseE
     }
 }
 
-void RectangleTool::on_mousemove(Layer&, GUI::MouseEvent& event, GUI::MouseEvent&)
+void RectangleTool::on_mousemove(Layer&, MouseEvent& event)
 {
     if (m_drawing_button == GUI::MouseButton::None)
         return;
 
-    m_rectangle_end_position = event.position();
+    m_rectangle_end_position = event.layer_event().position();
     m_editor->update();
 }
 

+ 3 - 3
Userland/Applications/PixelPaint/RectangleTool.h

@@ -17,9 +17,9 @@ public:
     RectangleTool();
     virtual ~RectangleTool() override;
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mousemove(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mouseup(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
+    virtual void on_mousedown(Layer&, MouseEvent&) override;
+    virtual void on_mousemove(Layer&, MouseEvent&) override;
+    virtual void on_mouseup(Layer&, MouseEvent&) override;
     virtual void on_second_paint(Layer const&, GUI::PaintEvent&) override;
     virtual void on_keydown(GUI::KeyEvent&) override;
     virtual GUI::Widget* get_properties_widget() override;

+ 7 - 6
Userland/Applications/PixelPaint/SprayTool.cpp

@@ -63,24 +63,25 @@ void SprayTool::paint_it()
     layer->did_modify_bitmap(Gfx::IntRect::centered_on(m_last_pos, Gfx::IntSize(base_radius * 2, base_radius * 2)));
 }
 
-void SprayTool::on_mousedown(Layer&, GUI::MouseEvent& event, GUI::MouseEvent&)
+void SprayTool::on_mousedown(Layer&, MouseEvent& event)
 {
-    m_color = m_editor->color_for(event);
-    m_last_pos = event.position();
+    auto& layer_event = event.layer_event();
+    m_color = m_editor->color_for(layer_event);
+    m_last_pos = layer_event.position();
     m_timer->start();
     paint_it();
 }
 
-void SprayTool::on_mousemove(Layer&, GUI::MouseEvent& event, GUI::MouseEvent&)
+void SprayTool::on_mousemove(Layer&, MouseEvent& event)
 {
-    m_last_pos = event.position();
+    m_last_pos = event.layer_event().position();
     if (m_timer->is_active()) {
         paint_it();
         m_timer->restart(m_timer->interval());
     }
 }
 
-void SprayTool::on_mouseup(Layer&, GUI::MouseEvent&, GUI::MouseEvent&)
+void SprayTool::on_mouseup(Layer&, MouseEvent&)
 {
     if (m_timer->is_active()) {
         m_timer->stop();

+ 3 - 3
Userland/Applications/PixelPaint/SprayTool.h

@@ -18,9 +18,9 @@ public:
     SprayTool();
     virtual ~SprayTool() override;
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mouseup(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
-    virtual void on_mousemove(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
+    virtual void on_mousedown(Layer&, MouseEvent&) override;
+    virtual void on_mouseup(Layer&, MouseEvent&) override;
+    virtual void on_mousemove(Layer&, MouseEvent&) override;
     virtual GUI::Widget* get_properties_widget() override;
     virtual Gfx::StandardCursor cursor() override { return Gfx::StandardCursor::Crosshair; }
 

+ 32 - 3
Userland/Applications/PixelPaint/Tool.h

@@ -19,9 +19,38 @@ class Tool {
 public:
     virtual ~Tool();
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent&, GUI::MouseEvent&) { }
-    virtual void on_mousemove(Layer&, GUI::MouseEvent&, GUI::MouseEvent&) { }
-    virtual void on_mouseup(Layer&, GUI::MouseEvent&, GUI::MouseEvent&) { }
+    class MouseEvent {
+    public:
+        enum class Action {
+            MouseDown,
+            MouseMove,
+            MouseUp
+        };
+
+        MouseEvent(Action action, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event, GUI::MouseEvent& raw_event)
+            : m_action(action)
+            , m_layer_event(layer_event)
+            , m_image_event(image_event)
+            , m_raw_event(raw_event)
+        {
+        }
+
+        Action action() const { return m_action; }
+        GUI::MouseEvent const& layer_event() const { return m_layer_event; }
+        GUI::MouseEvent const& image_event() const { return m_image_event; }
+        GUI::MouseEvent const& raw_event() const { return m_raw_event; }
+
+    private:
+        Action m_action;
+
+        GUI::MouseEvent& m_layer_event;
+        GUI::MouseEvent& m_image_event;
+        GUI::MouseEvent& m_raw_event;
+    };
+
+    virtual void on_mousedown(Layer&, MouseEvent&) { }
+    virtual void on_mousemove(Layer&, MouseEvent&) { }
+    virtual void on_mouseup(Layer&, MouseEvent&) { }
     virtual void on_context_menu(Layer&, GUI::ContextMenuEvent&) { }
     virtual void on_tool_button_contextmenu(GUI::ContextMenuEvent&) { }
     virtual void on_second_paint(Layer const&, GUI::PaintEvent&) { }

+ 5 - 4
Userland/Applications/PixelPaint/ZoomTool.cpp

@@ -20,13 +20,14 @@ ZoomTool::~ZoomTool()
 {
 }
 
-void ZoomTool::on_mousedown(Layer&, GUI::MouseEvent& event, GUI::MouseEvent&)
+void ZoomTool::on_mousedown(Layer&, MouseEvent& event)
 {
-    if (event.button() != GUI::MouseButton::Left && event.button() != GUI::MouseButton::Right)
+    auto& raw_event = event.raw_event();
+    if (raw_event.button() != GUI::MouseButton::Left && raw_event.button() != GUI::MouseButton::Right)
         return;
 
-    auto scale_factor = (event.button() == GUI::MouseButton::Left) ? m_sensitivity : -m_sensitivity;
-    m_editor->scale_centered_on_position(event.position(), scale_factor);
+    auto scale_factor = (raw_event.button() == GUI::MouseButton::Left) ? m_sensitivity : -m_sensitivity;
+    m_editor->scale_centered_on_position(raw_event.position(), scale_factor);
 }
 
 GUI::Widget* ZoomTool::get_properties_widget()

+ 1 - 1
Userland/Applications/PixelPaint/ZoomTool.h

@@ -17,7 +17,7 @@ public:
     ZoomTool();
     virtual ~ZoomTool() override;
 
-    virtual void on_mousedown(Layer&, GUI::MouseEvent& layer_event, GUI::MouseEvent& image_event) override;
+    virtual void on_mousedown(Layer&, MouseEvent&) override;
     virtual GUI::Widget* get_properties_widget() override;
 
 private: