From 6852b3afa1edd85fc0949720dc3bddec56f60cb0 Mon Sep 17 00:00:00 2001 From: Relintai Date: Tue, 15 Nov 2022 14:34:25 +0100 Subject: [PATCH] Added updated version of the methods in Action. --- modules/paint/actions/brighten_action.cpp | 35 ++++++++ modules/paint/actions/brush_action.cpp | 37 +++++++++ modules/paint/actions/bucket_action.cpp | 35 ++++++++ modules/paint/actions/bucket_action.h | 2 + modules/paint/actions/cut_action.cpp | 75 +++++++++++++++++ modules/paint/actions/cut_action.h | 3 + modules/paint/actions/darken_action.cpp | 34 ++++++++ modules/paint/actions/darken_action.h | 1 + modules/paint/actions/line_action.cpp | 56 +++++++++++++ modules/paint/actions/line_action.h | 3 + modules/paint/actions/multiline_action.cpp | 26 ++++++ modules/paint/actions/multiline_action.h | 2 +- modules/paint/actions/paint_action.cpp | 6 ++ modules/paint/actions/paste_cut_action.cpp | 49 +++++++++++ modules/paint/actions/paste_cut_action.h | 2 + modules/paint/actions/pencil_action.cpp | 34 +++++++- modules/paint/actions/pencil_action.h | 4 +- modules/paint/actions/rainbow_action.cpp | 43 ++++++++++ modules/paint/actions/rainbow_action.h | 2 + modules/paint/actions/rect_action.cpp | 63 ++++++++++++++ modules/paint/actions/rect_action.h | 3 + modules/paint/nodes/paint_canvas.cpp | 95 +++++++++++++++++++++- modules/paint/nodes/paint_canvas.h | 7 +- 23 files changed, 611 insertions(+), 6 deletions(-) diff --git a/modules/paint/actions/brighten_action.cpp b/modules/paint/actions/brighten_action.cpp index db8bb5b84..29172248f 100644 --- a/modules/paint/actions/brighten_action.cpp +++ b/modules/paint/actions/brighten_action.cpp @@ -28,6 +28,8 @@ SOFTWARE. #include "../deprecated/paint_canvas_layer.h" #include "../paint_utilities.h" +#include "../nodes/paint_canvas.h" + float BrightenAction::get_brighten_color() { return brighten_color; } @@ -68,6 +70,39 @@ void BrightenAction::do_action_old(PaintCanvasOld *canvas, const Array &data) { redo_colors.append(brightened_color); } } + +void BrightenAction::_do_action(const Array &data) { + PoolVector2iArray pixels = PaintUtilities::get_pixels_in_line(data[0], data[1]); + + for (int i = 0; i < pixels.size(); ++i) { + Vector2i pixel = pixels[i]; + + Color col = _paint_canvas->get_pixel_v(pixel); + + if (_paint_canvas->get_alpha_locked() && col.a < 0.00001) { + continue; + } + + Color brightened_color = col.lightened(brighten_color); + + if (undo_cells.contains(pixel)) { + _paint_canvas->set_pixel_v(pixel, brightened_color); + + redo_cells.append(pixel); + redo_colors.append(brightened_color); + continue; + } + + undo_colors.append(col); + undo_cells.append(pixel); + + _paint_canvas->set_pixel_v(pixel, brightened_color); + + redo_cells.append(pixel); + redo_colors.append(brightened_color); + } +} + BrightenAction::BrightenAction() { brighten_color = 0.1; } diff --git a/modules/paint/actions/brush_action.cpp b/modules/paint/actions/brush_action.cpp index b4bbc551d..cacc3a138 100644 --- a/modules/paint/actions/brush_action.cpp +++ b/modules/paint/actions/brush_action.cpp @@ -29,6 +29,8 @@ SOFTWARE. #include "../deprecated/paint_canvas_layer.h" #include "../paint_utilities.h" +#include "../nodes/paint_canvas.h" + void BrushAction::do_action_old(PaintCanvasOld *canvas, const Array &data) { PaintAction::do_action_old(canvas, data); @@ -66,6 +68,41 @@ void BrushAction::do_action_old(PaintCanvasOld *canvas, const Array &data) { } } +void BrushAction::_do_action(const Array &data) { + PoolVector2iArray pixels = PaintUtilities::get_pixels_in_line(data[0], data[1]); + int brush_type = data[3]; + int brush_size = data[4]; + PoolVector2iArray brush = BrushPrefabs::get_brush(static_cast(brush_type), brush_size); + Color tcolor = data[2]; + + for (int i = 0; i < pixels.size(); ++i) { + Vector2i pixel = pixels[i]; + + for (int j = 0; j < brush.size(); ++j) { + Vector2i off = brush[j]; + Vector2i p = pixel + off; + + if (undo_cells.contains(p)) { + continue; + } + + Color col = _paint_canvas->get_pixel_v(p); + + if (_paint_canvas->get_alpha_locked() && col.a < 0.00001) { + continue; + } + + undo_colors.append(col); + undo_cells.append(p); + + _paint_canvas->set_pixel_v(p, tcolor); + + redo_cells.append(p); + redo_colors.append(tcolor); + } + } +} + BrushAction::BrushAction() { } diff --git a/modules/paint/actions/bucket_action.cpp b/modules/paint/actions/bucket_action.cpp index 0334fdb60..950e5468c 100644 --- a/modules/paint/actions/bucket_action.cpp +++ b/modules/paint/actions/bucket_action.cpp @@ -28,6 +28,8 @@ SOFTWARE. #include "../deprecated/paint_canvas_layer.h" #include "../paint_utilities.h" +#include "../nodes/paint_canvas.h" + void BucketAction::do_action_old(PaintCanvasOld *canvas, const Array &data) { PaintAction::do_action_old(canvas, data); @@ -63,6 +65,39 @@ void BucketAction::do_action_old(PaintCanvasOld *canvas, const Array &data) { } } +void BucketAction::_do_action(const Array &data) { + Vector2i pos = data[0]; + + Color col = _paint_canvas->get_pixel_v(pos); + Color col2 = data[2]; + + if (col == col2) { + return; + } + + PoolVector2iArray pixels = _paint_canvas->select_same_color(pos.x, pos.y); + + for (int i = 0; i < pixels.size(); ++i) { + Vector2i pixel = pixels[i]; + + if (undo_cells.contains(pixel)) { + continue; + } + + if (_paint_canvas->get_alpha_locked() && col.a < 0.0001) { + continue; + } + + undo_cells.append(pixel); + undo_colors.append(col); + + _paint_canvas->set_pixel_v(pixel, col2); + + redo_cells.append(pixel); + redo_colors.append(col2); + } +} + BucketAction::BucketAction() { } diff --git a/modules/paint/actions/bucket_action.h b/modules/paint/actions/bucket_action.h index 111640443..948a78fb4 100644 --- a/modules/paint/actions/bucket_action.h +++ b/modules/paint/actions/bucket_action.h @@ -35,6 +35,8 @@ class BucketAction : public PaintAction { public: void do_action_old(PaintCanvasOld *canvas, const Array &data); + void _do_action(const Array &data); + BucketAction(); ~BucketAction(); diff --git a/modules/paint/actions/cut_action.cpp b/modules/paint/actions/cut_action.cpp index 2d1130e19..a5f1b7191 100644 --- a/modules/paint/actions/cut_action.cpp +++ b/modules/paint/actions/cut_action.cpp @@ -28,6 +28,8 @@ SOFTWARE. #include "../deprecated/paint_canvas_layer.h" #include "../paint_utilities.h" +#include "../nodes/paint_canvas.h" + Color CutAction::get_selection_color() { return selection_color; } @@ -135,6 +137,79 @@ void CutAction::commit_action_old(PaintCanvasOld *canvas) { } } +void CutAction::_do_action(const Array &data) { + if (!mouse_start_pos_set) { + mouse_start_pos = data[0]; + mouse_start_pos_set = true; + } + + mouse_end_pos = data[0]; + + preview_cells.clear(); + preview_colors.clear(); + _paint_canvas->clear_preview(); + + Vector2i p = mouse_start_pos; + Vector2i s = mouse_end_pos - mouse_start_pos; + + PoolVector2iArray pixels = PaintUtilities::get_pixels_in_line(p, p + Vector2i(s.x, 0)); + pixels.append_array(PaintUtilities::get_pixels_in_line(p, p + Vector2i(0, s.y))); + pixels.append_array(PaintUtilities::get_pixels_in_line(p + s, p + s + Vector2i(0, -s.y))); + pixels.append_array(PaintUtilities::get_pixels_in_line(p + s, p + s + Vector2i(-s.x, 0))); + + for (int i = 0; i < pixels.size(); ++i) { + Vector2i pixel = pixels[i]; + + _paint_canvas->set_preview_pixel_v(pixel, selection_color); + preview_cells.append(pixel); + preview_colors.append(selection_color); + } +} + +void CutAction::_commit_action() { + _paint_canvas->clear_preview(); + Vector2i p = mouse_start_pos; + Vector2i s = mouse_end_pos - mouse_start_pos; + + int ex = ABS(s.x) + 1; + int ey = ABS(s.y) + 1; + + for (int x = 0; x < ex; ++x) { + for (int y = 0; y < ey; ++y) { + int px = x; + int py = y; + + if (s.x < 0) { + px *= -1; + } + + if (s.y < 0) { + py *= -1; + } + + Vector2i pos = p + Vector2i(px, py); + + if (!_paint_canvas->validate_pixel_v(pos)) { + continue; + } + + Color color = _paint_canvas->get_pixel_v(pos); + + if (color.a < 0.0001) { + continue; + } + + redo_cells.append(pos); + redo_colors.append(color); + + _paint_canvas->set_pixel_v(pos, Color(1, 1, 1, 0)); + + undo_cells.append(pos); + undo_colors.append(Color(1, 1, 1, 0)); + } + } +} + CutAction::CutAction() { selection_color = Color(0.8, 0.8, 0.8, 0.5); mouse_start_pos_set = false; diff --git a/modules/paint/actions/cut_action.h b/modules/paint/actions/cut_action.h index 8ca36891c..c9862e6df 100644 --- a/modules/paint/actions/cut_action.h +++ b/modules/paint/actions/cut_action.h @@ -50,6 +50,9 @@ public: void do_action_old(PaintCanvasOld *canvas, const Array &data); void commit_action_old(PaintCanvasOld *canvas); + void _do_action(const Array &data); + void _commit_action(); + CutAction(); ~CutAction(); diff --git a/modules/paint/actions/darken_action.cpp b/modules/paint/actions/darken_action.cpp index 9086fd622..a62be27f6 100644 --- a/modules/paint/actions/darken_action.cpp +++ b/modules/paint/actions/darken_action.cpp @@ -28,6 +28,8 @@ SOFTWARE. #include "../deprecated/paint_canvas_layer.h" #include "../paint_utilities.h" +#include "../nodes/paint_canvas.h" + float DarkenAction::get_dark_factor() { return dark_factor; } @@ -69,6 +71,38 @@ void DarkenAction::do_action_old(PaintCanvasOld *canvas, const Array &data) { } } +void DarkenAction::_do_action(const Array &data) { + PoolVector2iArray pixels = PaintUtilities::get_pixels_in_line(data[0], data[1]); + + for (int i = 0; i < pixels.size(); ++i) { + Vector2i pixel = pixels[i]; + + if (!_paint_canvas->validate_pixel_v(pixel)) { + continue; + } + + Color col = _paint_canvas->get_pixel_v(pixel); + + if (_paint_canvas->get_alpha_locked() && col.a < 0.001) { + continue; + } + + Color darkened_color = col.darkened(dark_factor); + + _paint_canvas->set_pixel_v(pixel, darkened_color); + + redo_cells.append(pixel); + redo_colors.append(darkened_color); + + if (undo_cells.contains(pixel)) { + continue; + } + + undo_colors.append(col); + undo_cells.append(pixel); + } +} + DarkenAction::DarkenAction() { dark_factor = 0.1; } diff --git a/modules/paint/actions/darken_action.h b/modules/paint/actions/darken_action.h index f7a9e7335..793243187 100644 --- a/modules/paint/actions/darken_action.h +++ b/modules/paint/actions/darken_action.h @@ -37,6 +37,7 @@ public: void set_dark_factor(const float val); void do_action_old(PaintCanvasOld *canvas, const Array &data); + void _do_action(const Array &data); DarkenAction(); ~DarkenAction(); diff --git a/modules/paint/actions/line_action.cpp b/modules/paint/actions/line_action.cpp index e578c3bff..11eb05302 100644 --- a/modules/paint/actions/line_action.cpp +++ b/modules/paint/actions/line_action.cpp @@ -28,6 +28,8 @@ SOFTWARE. #include "../deprecated/paint_canvas_layer.h" #include "../paint_utilities.h" +#include "../nodes/paint_canvas.h" + Vector2i LineAction::get_mouse_start_pos() { return mouse_start_pos; } @@ -98,6 +100,60 @@ void LineAction::commit_action_old(PaintCanvasOld *canvas) { mouse_start_pos_set = false; } +void LineAction::_do_action(const Array &data) { + if (!mouse_start_pos_set) { + mouse_start_pos = data[0]; + mouse_start_pos_set = true; + } + + preview_cells.resize(0); + preview_colors.resize(0); + _paint_canvas->clear_preview(); + + PoolVector2iArray pixels = PaintUtilities::get_pixels_in_line(data[0], mouse_start_pos); + + for (int i = 0; i < pixels.size(); ++i) { + Vector2i pixel = pixels[i]; + + Color col = _paint_canvas->get_pixel_v(pixel); + + if (_paint_canvas->get_alpha_locked() && col.a < 0.00001) { + continue; + } + + Color nc = data[2]; + + _paint_canvas->set_preview_pixel_v(pixel, nc); + + preview_cells.append(pixel); + preview_colors.append(nc); + } +} + +void LineAction::_commit_action() { + _paint_canvas->clear_preview(); + + for (int i = 0; i < preview_cells.size(); ++i) { + Vector2i pc = preview_cells[i]; + + if (!_paint_canvas->validate_pixel_v(pc)) { + continue; + } + + Color pcol = preview_colors[i]; + + undo_cells.append(pc); + undo_colors.append(_paint_canvas->get_pixel_v(pc)); + + _paint_canvas->set_pixel_v(pc, pcol); + + redo_cells.append(pc); + redo_colors.append(pcol); + } + + mouse_start_pos_set = false; +} + bool LineAction::_can_commit() { return true; } diff --git a/modules/paint/actions/line_action.h b/modules/paint/actions/line_action.h index 9857c13d2..1124b16c7 100644 --- a/modules/paint/actions/line_action.h +++ b/modules/paint/actions/line_action.h @@ -41,6 +41,9 @@ public: void do_action_old(PaintCanvasOld *canvas, const Array &data); void commit_action_old(PaintCanvasOld *canvas); + + void _do_action(const Array &data); + void _commit_action(); bool _can_commit(); LineAction(); diff --git a/modules/paint/actions/multiline_action.cpp b/modules/paint/actions/multiline_action.cpp index aaff38e89..2554885f0 100644 --- a/modules/paint/actions/multiline_action.cpp +++ b/modules/paint/actions/multiline_action.cpp @@ -28,6 +28,8 @@ SOFTWARE. #include "../deprecated/paint_canvas_layer.h" #include "../paint_utilities.h" +#include "../nodes/paint_canvas.h" + bool MultiLineAction::_can_commit() { return false; } @@ -58,6 +60,30 @@ void MultiLineAction::do_action_old(PaintCanvasOld *canvas, const Array &data) { } } +void MultiLineAction::_do_action(const Array &data) { + PoolVector2iArray pixels = PaintUtilities::get_pixels_in_line(data[0], data[1]); + + for (int i = 0; i < pixels.size(); ++i) { + Vector2i pixel = pixels[i]; + + Color col = _paint_canvas->get_pixel_v(pixel); + + if (undo_cells.contains(pixel) || !_paint_canvas->validate_pixel_v(pixel) || (_paint_canvas->get_alpha_locked() && col.a < 0.0001)) { + continue; + } + + undo_colors.append(col); + undo_cells.append(pixel); + + Color tpx = data[2]; + + _paint_canvas->set_pixel_v(pixel, tpx); + + redo_cells.append(pixel); + redo_colors.append(tpx); + } +} + MultiLineAction::MultiLineAction() { } diff --git a/modules/paint/actions/multiline_action.h b/modules/paint/actions/multiline_action.h index 2b455642f..98f127c60 100644 --- a/modules/paint/actions/multiline_action.h +++ b/modules/paint/actions/multiline_action.h @@ -36,7 +36,7 @@ public: bool _can_commit(); void do_action_old(PaintCanvasOld *canvas, const Array &data); - //void commit_action_old(PaintCanvasOld *canvas); + void _do_action(const Array &data); MultiLineAction(); ~MultiLineAction(); diff --git a/modules/paint/actions/paint_action.cpp b/modules/paint/actions/paint_action.cpp index d6904ab95..f068f5fd9 100644 --- a/modules/paint/actions/paint_action.cpp +++ b/modules/paint/actions/paint_action.cpp @@ -374,8 +374,14 @@ void PaintAction::_commit_action() { } void PaintAction::_undo_action() { + for (int idx = 0; idx < undo_cells.size(); ++idx) { + _paint_canvas->set_pixel_v(undo_cells[idx], undo_colors[idx]); + } } void PaintAction::_redo_action() { + for (int idx = 0; idx < redo_cells.size(); ++idx) { + _paint_canvas->set_pixel_v(redo_cells[idx], redo_colors[idx]); + } } bool PaintAction::can_commit() { diff --git a/modules/paint/actions/paste_cut_action.cpp b/modules/paint/actions/paste_cut_action.cpp index 78bccb8ef..173432040 100644 --- a/modules/paint/actions/paste_cut_action.cpp +++ b/modules/paint/actions/paste_cut_action.cpp @@ -28,6 +28,8 @@ SOFTWARE. #include "../deprecated/paint_canvas_layer.h" #include "../paint_utilities.h" +#include "../nodes/paint_canvas.h" + //arr.append(cell_mouse_position); //arr.append(last_cell_mouse_position); //arr.append(_selection_cells); @@ -83,6 +85,53 @@ void PasteCutAction::do_action_old(PaintCanvasOld *canvas, const Array &data) { } } +void PasteCutAction::_do_action(const Array &data) { + PoolVector2iArray pixels = PaintUtilities::get_pixels_in_line(data[0], data[1]); + Vector2i cut_pos = data[4]; + Vector2i cut_size = data[5]; + + for (int i = 0; i < pixels.size(); ++i) { + Vector2i pixel_pos = pixels[i]; + + PoolVector2iArray cells = data[2]; + PoolColorArray colors = data[3]; + + for (int idx = 0; idx < cells.size(); ++idx) { + Vector2i pixel = cells[idx]; + Color color = colors[idx]; + pixel -= cut_pos + cut_size / 2; + pixel += pixel_pos; + + if (!_paint_canvas->validate_pixel_v(pixel)) { + continue; + } + + Color col = _paint_canvas->get_pixel_v(pixel); + + if (_paint_canvas->get_alpha_locked() && col.a < 0.0001) { + continue; + } + + int found = redo_cells.find(pixel); + if (found == -1) { + redo_cells.push_back(pixel); + redo_colors.push_back(color); + } else { + redo_colors[found] = color; + } + + found = undo_cells.find(pixel); + + if (found == -1) { + undo_colors.append(col); + undo_cells.append(pixel); + } + + _paint_canvas->set_pixel_v(pixel, color); + } + } +} + PasteCutAction::PasteCutAction() { } diff --git a/modules/paint/actions/paste_cut_action.h b/modules/paint/actions/paste_cut_action.h index 8bb5bd100..a1137db10 100644 --- a/modules/paint/actions/paste_cut_action.h +++ b/modules/paint/actions/paste_cut_action.h @@ -35,6 +35,8 @@ class PasteCutAction : public PaintAction { public: void do_action_old(PaintCanvasOld *canvas, const Array &data); + void _do_action(const Array &data); + PasteCutAction(); ~PasteCutAction(); diff --git a/modules/paint/actions/pencil_action.cpp b/modules/paint/actions/pencil_action.cpp index 80a8ceadf..d3876e1c5 100644 --- a/modules/paint/actions/pencil_action.cpp +++ b/modules/paint/actions/pencil_action.cpp @@ -29,6 +29,8 @@ SOFTWARE. #include "../paint_utilities.h" #include "core/string/print_string.h" +#include "../nodes/paint_canvas.h" + void PencilAction::do_action_old(PaintCanvasOld *canvas, const Array &data) { PaintAction::do_action_old(canvas, data); @@ -44,12 +46,12 @@ void PencilAction::do_action_old(PaintCanvasOld *canvas, const Array &data) { for (int j = 0; j < points.size(); ++j) { Vector2i p = points[j]; - _set_pixel(canvas, p, c); + _set_pixel_old(canvas, p, c); } } } -void PencilAction::_set_pixel(PaintCanvasOld *canvas, Vector2i pixel, Color color) { +void PencilAction::_set_pixel_old(PaintCanvasOld *canvas, Vector2i pixel, Color color) { undo_colors.append(canvas->get_pixel_v(pixel)); undo_cells.append(pixel); @@ -59,6 +61,34 @@ void PencilAction::_set_pixel(PaintCanvasOld *canvas, Vector2i pixel, Color colo redo_colors.append(color); } +void PencilAction::_do_action(const Array &data) { + Color c = data[2]; + + PoolVector2iArray pixels = PaintUtilities::get_pixels_in_line(data[0], data[1]); + + for (int i = 0; i < pixels.size(); ++i) { + Vector2i pixel = pixels[i]; + + PoolVector2iArray points = get_points(pixel); + + for (int j = 0; j < points.size(); ++j) { + Vector2i p = points[j]; + + _set_pixel(p, c); + } + } +} + +void PencilAction::_set_pixel(Vector2i pixel, Color color) { + undo_colors.append(_paint_canvas->get_pixel_v(pixel)); + undo_cells.append(pixel); + + _paint_canvas->set_pixel_v(pixel, color); + + redo_cells.append(pixel); + redo_colors.append(color); +} + PencilAction::PencilAction() { } diff --git a/modules/paint/actions/pencil_action.h b/modules/paint/actions/pencil_action.h index b86a4c609..29e5abbe9 100644 --- a/modules/paint/actions/pencil_action.h +++ b/modules/paint/actions/pencil_action.h @@ -34,8 +34,10 @@ class PencilAction : public PaintAction { public: void do_action_old(PaintCanvasOld *canvas, const Array &data); + void _set_pixel_old(PaintCanvasOld *canvas, Vector2i pixel, Color color); - void _set_pixel(PaintCanvasOld *canvas, Vector2i pixel, Color color); + void _do_action(const Array &data); + void _set_pixel(Vector2i pixel, Color color); PencilAction(); ~PencilAction(); diff --git a/modules/paint/actions/rainbow_action.cpp b/modules/paint/actions/rainbow_action.cpp index 2b94f3d76..775493e11 100644 --- a/modules/paint/actions/rainbow_action.cpp +++ b/modules/paint/actions/rainbow_action.cpp @@ -28,6 +28,8 @@ SOFTWARE. #include "../deprecated/paint_canvas_layer.h" #include "../paint_utilities.h" +#include "../nodes/paint_canvas.h" + void RainbowAction::do_action_old(PaintCanvasOld *canvas, const Array &data) { PaintAction::do_action_old(canvas, data); @@ -71,6 +73,47 @@ void RainbowAction::do_action_old(PaintCanvasOld *canvas, const Array &data) { } } +void RainbowAction::_do_action(const Array &data) { + PoolVector2iArray pixels = PaintUtilities::get_pixels_in_line(data[0], data[1]); + + for (int i = 0; i < pixels.size(); ++i) { + Vector2i pixel = pixels[i]; + + if (!_paint_canvas->validate_pixel_v(pixel)) { + continue; + } + + Color col = _paint_canvas->get_pixel_v(pixel); + + if (_paint_canvas->get_alpha_locked() && col.a < 0.0001) { + continue; + } + + if (undo_cells.contains(pixel)) { + Color color = PaintUtilities::random_color(); + _paint_canvas->set_pixel_v(pixel, color); + + int idx = redo_cells.find(pixel); + redo_cells.remove(idx); + redo_colors.remove(idx); + + redo_cells.append(pixel); + redo_colors.append(color); + + continue; + } + + undo_colors.append(col); + undo_cells.append(pixel); + + Color color = PaintUtilities::random_color(); + _paint_canvas->set_pixel_v(pixel, color); + + redo_cells.append(pixel); + redo_colors.append(color); + } +} + RainbowAction::RainbowAction() { } diff --git a/modules/paint/actions/rainbow_action.h b/modules/paint/actions/rainbow_action.h index 9eda39b2e..a3c66b58c 100644 --- a/modules/paint/actions/rainbow_action.h +++ b/modules/paint/actions/rainbow_action.h @@ -35,6 +35,8 @@ class RainbowAction : public PaintAction { public: void do_action_old(PaintCanvasOld *canvas, const Array &data); + void _do_action(const Array &data); + RainbowAction(); ~RainbowAction(); diff --git a/modules/paint/actions/rect_action.cpp b/modules/paint/actions/rect_action.cpp index 0ca7d881e..12ad62ff8 100644 --- a/modules/paint/actions/rect_action.cpp +++ b/modules/paint/actions/rect_action.cpp @@ -28,6 +28,8 @@ SOFTWARE. #include "../deprecated/paint_canvas_layer.h" #include "../paint_utilities.h" +#include "../nodes/paint_canvas.h" + Vector2i RectAction::get_mouse_start_pos() { return mouse_start_pos; } @@ -105,6 +107,67 @@ void RectAction::commit_action_old(PaintCanvasOld *canvas) { mouse_start_pos_set = false; } +void RectAction::_do_action(const Array &data) { + if (!mouse_start_pos_set) { + mouse_start_pos = data[0]; + //print("init:", mouse_start_pos) + mouse_start_pos_set = true; + } + + undo_cells.clear(); + undo_colors.clear(); + preview_cells.clear(); + preview_colors.clear(); + + _paint_canvas->clear_preview(); + + Vector2i p = mouse_start_pos; + Vector2i current_mouse_pos = data[0]; + Vector2i s = current_mouse_pos - mouse_start_pos; + + PoolVector2iArray pixels = PaintUtilities::get_pixels_in_line(p, p + Vector2i(s.x, 0)); + pixels.append_array(PaintUtilities::get_pixels_in_line(p, p + Vector2(0, s.y))); + pixels.append_array(PaintUtilities::get_pixels_in_line(p + s, p + s + Vector2(0, -s.y))); + pixels.append_array(PaintUtilities::get_pixels_in_line(p + s, p + s + Vector2(-s.x, 0))); + + for (int i = 0; i < pixels.size(); ++i) { + Vector2i pixel = pixels[i]; + + if (!_paint_canvas->validate_pixel_v(pixel)) { + continue; + } + + Color col = _paint_canvas->get_pixel_v(pixel); + + if (_paint_canvas->get_alpha_locked() && col.a < 0.00001) { + continue; + } + + Color tc = data[2]; + + _paint_canvas->set_preview_pixel_v(pixel, tc); + undo_cells.append(pixel); + undo_colors.append(col); + preview_cells.append(pixel); + preview_colors.append(tc); + } +} +void RectAction::_commit_action() { + _paint_canvas->clear_preview(); + + for (int idx = 0; idx < preview_cells.size(); ++idx) { + Vector2i pcell = preview_cells[idx]; + Color pcolor = preview_colors[idx]; + + _paint_canvas->set_pixel_v(pcell, pcolor); + + redo_cells.append(pcell); + redo_colors.append(pcolor); + } + + mouse_start_pos_set = false; +} + bool RectAction::_can_commit() { return true; } diff --git a/modules/paint/actions/rect_action.h b/modules/paint/actions/rect_action.h index 9ade547fe..fd6683417 100644 --- a/modules/paint/actions/rect_action.h +++ b/modules/paint/actions/rect_action.h @@ -41,6 +41,9 @@ public: void do_action_old(PaintCanvasOld *canvas, const Array &data); void commit_action_old(PaintCanvasOld *canvas); + + void _do_action(const Array &data); + void _commit_action(); bool _can_commit(); RectAction(); diff --git a/modules/paint/nodes/paint_canvas.cpp b/modules/paint/nodes/paint_canvas.cpp index 620bebc9d..628715607 100644 --- a/modules/paint/nodes/paint_canvas.cpp +++ b/modules/paint/nodes/paint_canvas.cpp @@ -1,5 +1,6 @@ #include "paint_canvas.h" +#include "../paint_utilities.h" #include "core/io/image.h" #include "scene/resources/texture.h" @@ -111,7 +112,13 @@ Color PaintCanvas::get_preview_pixel(const int x, const int y) { void PaintCanvas::clear() { _image->fill(Color(1.00, 1.00, 1.00, 0.00)); - update_textures(); + _image_texture->create_from_image(_image, 0); +} + +void PaintCanvas::clear_preview() { + _preview_image->fill(Color(1.00, 1.00, 1.00, 0.00)); + + _preview_image_texture->create_from_image(_preview_image, 0); } void PaintCanvas::update_textures() { @@ -121,6 +128,87 @@ void PaintCanvas::update_textures() { update(); } +PoolVector2iArray PaintCanvas::select_color(const int p_x, const int p_y) { + PoolVector2iArray same_color_pixels; + + Color color = get_pixel(p_x, p_y); + for (int x = 0; x < get_size().x; ++x) { + for (int y = 0; y < get_size().y; ++y) { + Color pixel_color = get_pixel(x, y); + + if (pixel_color == color) { + same_color_pixels.append(Vector2i(x, y)); + } + } + } + + return same_color_pixels; +} +PoolVector2iArray PaintCanvas::select_same_color(const int p_x, const int p_y) { + return get_neighbouring_pixels(p_x, p_y); +} + +// yoinked from +// https://www.geeksforgeeks.org/flood-fill-algorithm-implement-fill-paint/ +PoolVector2iArray PaintCanvas::get_neighbouring_pixels(const int pos_x, const int pos_y) { + PoolVector2iArray pixels; + + PoolIntArray to_check_queue; + PoolIntArray checked_queue; + + to_check_queue.append(PaintUtilities::to_1D(pos_x, pos_y, get_size().x)); + + Color color = get_pixel(pos_x, pos_y); + + while (!to_check_queue.empty()) { + int idx = to_check_queue[0]; + to_check_queue.remove(0); + Vector2i p = PaintUtilities::to_2D(idx, get_size().x); + + if (checked_queue.contains(idx)) { + continue; + } + + checked_queue.append(idx); + + if (get_pixel(p.x, p.y) != color) { + continue; + } + + // add to result + pixels.append(p); + + // check neighbours + int x = p.x - 1; + int y = p.y; + if (is_inside_canvas(x, y)) { + idx = PaintUtilities::to_1D(x, y, get_size().x); + to_check_queue.append(idx); + } + + x = p.x + 1; + if (is_inside_canvas(x, y)) { + idx = PaintUtilities::to_1D(x, y, get_size().x); + to_check_queue.append(idx); + } + + x = p.x; + y = p.y - 1; + if (is_inside_canvas(x, y)) { + idx = PaintUtilities::to_1D(x, y, get_size().x); + to_check_queue.append(idx); + } + + y = p.y + 1; + if (is_inside_canvas(x, y)) { + idx = PaintUtilities::to_1D(x, y, get_size().x); + to_check_queue.append(idx); + } + } + + return pixels; +} + PaintCanvas::PaintCanvas() { _symmetry_x = false; _symmetry_y = false; @@ -176,5 +264,10 @@ void PaintCanvas::_bind_methods() { ClassDB::bind_method(D_METHOD("validate_pixel_v", "pos"), &PaintCanvas::validate_pixel_v); ClassDB::bind_method(D_METHOD("clear"), &PaintCanvas::clear); + ClassDB::bind_method(D_METHOD("clear_preview"), &PaintCanvas::clear_preview); ClassDB::bind_method(D_METHOD("update_textures"), &PaintCanvas::update_textures); + + ClassDB::bind_method(D_METHOD("select_color", "x", "y"), &PaintCanvas::select_color); + ClassDB::bind_method(D_METHOD("select_same_color", "x", "y"), &PaintCanvas::select_same_color); + ClassDB::bind_method(D_METHOD("get_neighbouring_pixels", "x", "y"), &PaintCanvas::get_neighbouring_pixels); } diff --git a/modules/paint/nodes/paint_canvas.h b/modules/paint/nodes/paint_canvas.h index 6ebc8c0ab..a0f08edcf 100644 --- a/modules/paint/nodes/paint_canvas.h +++ b/modules/paint/nodes/paint_canvas.h @@ -36,12 +36,17 @@ public: Color get_preview_pixel_v(const Vector2i &pos); Color get_preview_pixel(const int x, const int y); - + bool validate_pixel_v(const Vector2i &pos) const; void clear(); + void clear_preview(); void update_textures(); + PoolVector2iArray select_color(const int p_x, const int p_y); + PoolVector2iArray select_same_color(const int p_x, const int p_y); + PoolVector2iArray get_neighbouring_pixels(const int pos_x, const int pos_y); + PaintCanvas(); ~PaintCanvas();