From 0472063b96144b8fed7a0dc314e633e4ee8c4db9 Mon Sep 17 00:00:00 2001 From: Mustafa Quraish Date: Sun, 12 Sep 2021 16:15:03 -0400 Subject: [PATCH] PixelPaint: Add a marker for CloneTool's selected position Now we add a little marker to show the current sample position of the CloneTool. The current implementation for updating the cursor location is really dumb since it just updates the whole editor, but that's a yak on the stack to fix. --- .../Applications/PixelPaint/CloneTool.cpp | 37 +++++++++++++++++++ Userland/Applications/PixelPaint/CloneTool.h | 4 ++ 2 files changed, 41 insertions(+) diff --git a/Userland/Applications/PixelPaint/CloneTool.cpp b/Userland/Applications/PixelPaint/CloneTool.cpp index 43915c6541..6a68ca1890 100644 --- a/Userland/Applications/PixelPaint/CloneTool.cpp +++ b/Userland/Applications/PixelPaint/CloneTool.cpp @@ -52,12 +52,29 @@ void CloneTool::draw_line(Gfx::Bitmap& bitmap, Gfx::Color const& color, Gfx::Int BrushTool::draw_line(bitmap, color, start, end); } +void CloneTool::on_mousemove(Layer* layer, MouseEvent& event) +{ + auto& image_event = event.image_event(); + if (image_event.alt()) + return; + + if (m_cursor_offset.has_value()) { + m_sample_location = image_event.position() - m_cursor_offset.value(); + // FIXME: This is a really inefficient way to update the marker's location + m_editor->update(); + } + + BrushTool::on_mousemove(layer, event); +} + void CloneTool::on_mousedown(Layer* layer, MouseEvent& event) { auto& image_event = event.image_event(); if (image_event.alt()) { m_sample_location = image_event.position(); m_cursor_offset = {}; + // FIXME: This is a really dumb way to get the marker to show up + m_editor->update(); return; } @@ -70,6 +87,26 @@ void CloneTool::on_mousedown(Layer* layer, MouseEvent& event) BrushTool::on_mousedown(layer, event); } +void CloneTool::on_second_paint(Layer const*, GUI::PaintEvent& event) +{ + if (!m_sample_location.has_value()) + return; + + GUI::Painter painter(*m_editor); + painter.add_clip_rect(event.rect()); + + auto sample_pos = m_editor->image_position_to_editor_position(m_sample_location.value()); + // We don't want the marker to be a single pixel and hide the color. + auto offset = AK::max(2, size() / 2); + Gfx::IntRect rect = { + (int)sample_pos.x() - offset, + (int)sample_pos.y() - offset, + offset * 2, + offset * 2 + }; + painter.draw_ellipse_intersecting(rect, m_marker_color, 1); +} + void CloneTool::on_keydown(GUI::KeyEvent& event) { Tool::on_keydown(event); diff --git a/Userland/Applications/PixelPaint/CloneTool.h b/Userland/Applications/PixelPaint/CloneTool.h index 7e00eaa47f..280a96e627 100644 --- a/Userland/Applications/PixelPaint/CloneTool.h +++ b/Userland/Applications/PixelPaint/CloneTool.h @@ -22,6 +22,8 @@ protected: virtual void draw_line(Gfx::Bitmap& bitmap, Gfx::Color const& color, Gfx::IntPoint const& start, Gfx::IntPoint const& end) override; virtual void on_mousedown(Layer*, MouseEvent&) override; + virtual void on_mousemove(Layer*, MouseEvent&) override; + virtual void on_second_paint(Layer const*, GUI::PaintEvent&) override; virtual void on_keydown(GUI::KeyEvent&) override; virtual void on_keyup(GUI::KeyEvent&) override; @@ -31,6 +33,8 @@ private: Optional m_sample_location; Optional m_cursor_offset; bool m_is_selecting_location { false }; + + Gfx::Color m_marker_color { Gfx::Color::Green }; }; }