Skip to content

Commit 4cecd79

Browse files
committed
PixelPaint: Draw the current editor selection as marching ants
This patch moves the marching ants painting code to Selection and unifies the timer mechanism so that all marching ants are synchronized which looks neat. :^)
1 parent 1b897ec commit 4cecd79

File tree

5 files changed

+51
-46
lines changed

5 files changed

+51
-46
lines changed

Userland/Applications/PixelPaint/ImageEditor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace PixelPaint {
2020

2121
ImageEditor::ImageEditor()
2222
: m_undo_stack(make<GUI::UndoStack>())
23+
, m_selection(*this)
2324
{
2425
set_focus_policy(GUI::FocusPolicy::StrongFocus);
2526
}

Userland/Applications/PixelPaint/RectangleSelectTool.cpp

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,14 @@
55
*/
66

77
#include "RectangleSelectTool.h"
8-
#include "Image.h"
98
#include "ImageEditor.h"
109
#include "Layer.h"
11-
#include <LibCore/Timer.h>
1210
#include <LibGUI/Painter.h>
1311

1412
namespace PixelPaint {
1513

16-
constexpr int marching_ant_length = 4;
17-
1814
RectangleSelectTool::RectangleSelectTool()
1915
{
20-
m_marching_ants_timer = Core::Timer::create_repeating(80, [this] {
21-
if (!m_editor)
22-
return;
23-
++m_marching_ants_offset;
24-
m_marching_ants_offset %= marching_ant_length;
25-
m_editor->update();
26-
});
27-
m_marching_ants_timer->start();
2816
}
2917

3018
RectangleSelectTool::~RectangleSelectTool()
@@ -63,33 +51,6 @@ void RectangleSelectTool::on_mouseup(Layer&, GUI::MouseEvent&, GUI::MouseEvent&
6351
m_editor->selection().set(rect_in_image);
6452
}
6553

66-
void RectangleSelectTool::draw_marching_ants(Gfx::Painter& painter, Gfx::IntRect const& rect) const
67-
{
68-
int offset = m_marching_ants_offset;
69-
70-
auto draw_pixel = [&](int x, int y) {
71-
if ((offset % marching_ant_length) != 0)
72-
painter.set_pixel(x, y, Color::Black);
73-
offset++;
74-
};
75-
76-
// Top line
77-
for (int x = rect.left(); x <= rect.right(); ++x)
78-
draw_pixel(x, rect.top());
79-
80-
// Right line
81-
for (int y = rect.top() + 1; y <= rect.bottom(); ++y)
82-
draw_pixel(rect.right(), y);
83-
84-
// Bottom line
85-
for (int x = rect.right() - 1; x >= rect.left(); --x)
86-
draw_pixel(x, rect.bottom());
87-
88-
// Left line
89-
for (int y = rect.bottom() - 1; y > rect.top(); --y)
90-
draw_pixel(rect.left(), y);
91-
}
92-
9354
void RectangleSelectTool::on_second_paint(Layer const&, GUI::PaintEvent& event)
9455
{
9556
if (!m_selecting)
@@ -101,7 +62,7 @@ void RectangleSelectTool::on_second_paint(Layer const&, GUI::PaintEvent& event)
10162
auto rect_in_image = Gfx::IntRect::from_two_points(m_selection_start, m_selection_end);
10263
auto rect_in_editor = m_editor->image_rect_to_editor_rect(rect_in_image);
10364

104-
draw_marching_ants(painter, rect_in_editor.to_type<int>());
65+
m_editor->selection().draw_marching_ants(painter, rect_in_editor.to_type<int>());
10566
}
10667

10768
}

Userland/Applications/PixelPaint/RectangleSelectTool.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,9 @@ class RectangleSelectTool final : public Tool {
2121
virtual void on_second_paint(Layer const&, GUI::PaintEvent&) override;
2222

2323
private:
24-
void draw_marching_ants(Gfx::Painter&, Gfx::IntRect const&) const;
25-
2624
bool m_selecting { false };
2725
Gfx::IntPoint m_selection_start;
2826
Gfx::IntPoint m_selection_end;
29-
RefPtr<Core::Timer> m_marching_ants_timer;
30-
int m_marching_ants_offset { 0 };
3127
};
3228

3329
}

Userland/Applications/PixelPaint/Selection.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,50 @@
1010

1111
namespace PixelPaint {
1212

13+
constexpr int marching_ant_length = 4;
14+
1315
void Selection::paint(Gfx::Painter& painter, ImageEditor const& editor)
1416
{
15-
painter.draw_rect(editor.image_rect_to_editor_rect(m_rect).to_type<int>(), Color::Magenta);
17+
draw_marching_ants(painter, editor.image_rect_to_editor_rect(m_rect).to_type<int>());
18+
}
19+
20+
Selection::Selection(ImageEditor& editor)
21+
: m_editor(editor)
22+
{
23+
m_marching_ants_timer = Core::Timer::create_repeating(80, [this] {
24+
++m_marching_ants_offset;
25+
m_marching_ants_offset %= marching_ant_length;
26+
if (!is_empty())
27+
m_editor.update();
28+
});
29+
m_marching_ants_timer->start();
30+
}
31+
32+
void Selection::draw_marching_ants(Gfx::Painter& painter, Gfx::IntRect const& rect) const
33+
{
34+
int offset = m_marching_ants_offset;
35+
36+
auto draw_pixel = [&](int x, int y) {
37+
if ((offset % marching_ant_length) != 0)
38+
painter.set_pixel(x, y, Color::Black);
39+
offset++;
40+
};
41+
42+
// Top line
43+
for (int x = rect.left(); x <= rect.right(); ++x)
44+
draw_pixel(x, rect.top());
45+
46+
// Right line
47+
for (int y = rect.top() + 1; y <= rect.bottom(); ++y)
48+
draw_pixel(rect.right(), y);
49+
50+
// Bottom line
51+
for (int x = rect.right() - 1; x >= rect.left(); --x)
52+
draw_pixel(x, rect.bottom());
53+
54+
// Left line
55+
for (int y = rect.bottom() - 1; y > rect.top(); --y)
56+
draw_pixel(rect.left(), y);
1657
}
1758

1859
}

Userland/Applications/PixelPaint/Selection.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#pragma once
88

9+
#include <LibCore/Timer.h>
910
#include <LibGfx/Rect.h>
1011

1112
namespace PixelPaint {
@@ -15,16 +16,21 @@ class ImageEditor;
1516
// Coordinates are image-relative.
1617
class Selection {
1718
public:
18-
Selection() { }
19+
explicit Selection(ImageEditor&);
1920

2021
bool is_empty() const { return m_rect.is_empty(); }
2122
void clear() { m_rect = {}; }
2223
void set(Gfx::IntRect const& rect) { m_rect = rect; }
2324

2425
void paint(Gfx::Painter&, ImageEditor const&);
2526

27+
void draw_marching_ants(Gfx::Painter&, Gfx::IntRect const&) const;
28+
2629
private:
30+
ImageEditor& m_editor;
2731
Gfx::IntRect m_rect;
32+
RefPtr<Core::Timer> m_marching_ants_timer;
33+
int m_marching_ants_offset { 0 };
2834
};
2935

3036
}

0 commit comments

Comments
 (0)