Ported the logic for PaintCanvas.

This commit is contained in:
Relintai 2022-04-17 00:17:05 +02:00
parent 3461d692d4
commit 5e368ec978
3 changed files with 385 additions and 362 deletions

View File

@ -25,6 +25,7 @@ SOFTWARE.
#include "paint_canvas.h" #include "paint_canvas.h"
#include "paint_canvas_outline.h" #include "paint_canvas_outline.h"
#include "paint_utilities.h"
#include "paint_visual_grid.h" #include "paint_visual_grid.h"
#include "scene/gui/control.h" #include "scene/gui/control.h"
#include "scene/gui/texture_rect.h" #include "scene/gui/texture_rect.h"
@ -32,51 +33,38 @@ SOFTWARE.
#include "paint_canvas_layer.h" #include "paint_canvas_layer.h"
void PaintCanvas::_enter_tree() { void PaintCanvas::_enter_tree() {
/* connect("mouse_entered", this, "_on_mouse_entered");
#------------------------------- connect("mouse_exited", this, "_on_mouse_exited");
# Set nodes
#-------------------------------
canvas = find_node("Canvas")
grid = find_node("Grid")
big_grid = find_node("BigGrid")
canvas_layers = find_node("CanvasLayers")
#------------------------------- //canvas_size = Vector2(int(rect_size.x / grid_size), int(rect_size.y / grid_size));
# setup layers and canvas //pixel_size = canvas_size;
#-------------------------------
connect("mouse_entered", self, "_on_mouse_entered")
connect("mouse_exited", self, "_on_mouse_exited")
#------------------------------- active_layer = add_new_layer("Layer1");
# setup layers and canvas preview_layer = add_new_layer("Preview");
#------------------------------- tool_layer = add_new_layer("Tool");
#canvas_size = Vector2(int(rect_size.x / grid_size), int(rect_size.y / grid_size))
#pixel_size = canvas_size
active_layer = add_new_layer("Layer1") set_process(true);
preview_layer = add_new_layer("Preview")
tool_layer = add_new_layer("Tool")
set_process(true)
*/
} }
void PaintCanvas::_process(float delta) { void PaintCanvas::_process(float delta) {
/* if (!is_visible_in_tree()) {
if not is_visible_in_tree(): return;
return }
var mouse_position = get_local_mouse_position()
var rect = Rect2(Vector2(0, 0), rect_size) Vector2 mouse_position = get_local_mouse_position();
mouse_in_region = rect.has_point(mouse_position) Rect2 rect = Rect2(Vector2(0, 0), get_size());
*/ mouse_in_region = rect.has_point(mouse_position);
} }
void PaintCanvas::_draw() { void PaintCanvas::_draw() {
/* for (int i = 0; i < layers.size(); ++i) {
for layer in layers: Ref<PaintCanvasLayer> layer = layers[i];
layer.update_texture()
preview_layer.update_texture() ERR_CONTINUE(!layer.is_valid());
tool_layer.update_texture()
*/ layer->update_texture();
}
preview_layer->update_texture();
tool_layer->update_texture();
} }
int PaintCanvas::get_pixel_size() const { int PaintCanvas::get_pixel_size() const {
@ -84,92 +72,100 @@ int PaintCanvas::get_pixel_size() const {
} }
void PaintCanvas::set_pixel_size(const int size) { void PaintCanvas::set_pixel_size(const int size) {
/* _pixel_size = size;
pixel_size = size set_grid_size(_grid_size);
set_grid_size(grid_size) set_big_grid_size(_big_grid_size);
set_big_grid_size(big_grid_size) set_canvas_width(_canvas_width);
set_canvas_width(canvas_width) set_canvas_height(_canvas_height);
set_canvas_height(canvas_height)
*/
} }
int PaintCanvas::get_grid_size() const { int PaintCanvas::get_grid_size() const {
return _grid_size; return _grid_size;
} }
void PaintCanvas::set_grid_size(const int size) { void PaintCanvas::set_grid_size(const int size) {
/* _grid_size = size;
grid_size = size
if not find_node("Grid"): if (grid) {
return int s = size * _pixel_size;
find_node("Grid").size = size * pixel_size grid->set_size(Size2(s, s));
*/ }
} }
int PaintCanvas::get_big_grid_size() const { int PaintCanvas::get_big_grid_size() const {
return _big_grid_size; return _big_grid_size;
} }
void PaintCanvas::set_big_grid_size(const int size) { void PaintCanvas::set_big_grid_size(const int size) {
/* _big_grid_size = size;
big_grid_size = size
if not find_node("BigGrid"): if (big_grid) {
return int s = size * _pixel_size;
find_node("BigGrid").size = size * pixel_size grid->set_size(Size2(s, s));
*/ }
} }
int PaintCanvas::get_canvas_width() const { int PaintCanvas::get_canvas_width() const {
return _canvas_width; return _canvas_width;
} }
void PaintCanvas::set_canvas_width(const int val) { void PaintCanvas::set_canvas_width(const int val) {
/* _canvas_width = val;
canvas_width = val
rect_size.x = canvas_width * pixel_size Size2 s = get_size();
*/ s.x = _canvas_width * _pixel_size;
set_size(s);
} }
int PaintCanvas::get_canvas_height() const { int PaintCanvas::get_canvas_height() const {
return _canvas_height; return _canvas_height;
} }
void PaintCanvas::set_canvas_height(const int val) { void PaintCanvas::set_canvas_height(const int val) {
/* _canvas_height = val;
canvas_height = val
rect_size.y = canvas_height * pixel_size Size2 s = get_size();
*/ s.x = _canvas_height * _pixel_size;
set_size(s);
} }
void PaintCanvas::toggle_alpha_locked(const String &layer_name) { void PaintCanvas::toggle_alpha_locked(const String &layer_name) {
/* Ref<PaintCanvasLayer> layer = find_layer_by_name(layer_name);
var layer = find_layer_by_name(layer_name)
layer.toggle_alpha_locked() if (layer.is_valid()) {
*/ layer->toggle_alpha_locked();
}
} }
bool PaintCanvas::is_alpha_locked() { bool PaintCanvas::is_alpha_locked() {
/* if (!active_layer.is_valid()) {
return active_layer.alpha_locked return false;
*/ }
return false;
return active_layer->alpha_locked;
} }
Rect2 PaintCanvas::get_content_margin() { Rect2 PaintCanvas::get_content_margin() {
/* Rect2 rect = Rect2(999999, 999999, -999999, -999999);
var rect = Rect2(999999, 999999, -999999, -999999)
preview_layer.image.get_used_rect() for (int i = 0; i < layers.size(); ++i) {
for layer in layers: Ref<PaintCanvasLayer> l = layers[i];
var r = layer.image.get_used_rect() ERR_CONTINUE(!l.is_valid());
if r.position.x < rect.position.x: Rect2 r = l->image->get_used_rect();
rect.position.x = r.position.x
if r.position.y < rect.position.y:
rect.position.y = r.position.y
if r.size.x > rect.size.x:
rect.size.x = r.size.x
if r.size.y > rect.size.y:
rect.size.y = r.size.y
return rect if (r.position.x < rect.position.x) {
*/ rect.position.x = r.position.x;
}
return Rect2(); if (r.position.y < rect.position.y) {
rect.position.y = r.position.y;
}
if (r.size.x > rect.size.x) {
rect.size.x = r.size.x;
}
if (r.size.y > rect.size.y) {
rect.size.y = r.size.y;
}
}
return rect;
} }
void PaintCanvas::crop_to_content() { void PaintCanvas::crop_to_content() {
/* /*
@ -189,347 +185,372 @@ void PaintCanvas::crop_to_content() {
# layer.resize(width, height) # layer.resize(width, height)
*/ */
} }
Node *PaintCanvas::get_active_layer() { Ref<PaintCanvasLayer> PaintCanvas::get_active_layer() {
/* return active_layer;
return active_layer
*/
return nullptr;
} }
Node *PaintCanvas::get_preview_layer() { Ref<PaintCanvasLayer> PaintCanvas::get_preview_layer() {
/* return preview_layer;
return preview_layer
*/
return nullptr;
} }
void PaintCanvas::clear_active_layer() { void PaintCanvas::clear_active_layer() {
/* if (active_layer.is_valid()) {
active_layer.clear() active_layer->clear();
*/ }
} }
void PaintCanvas::clear_preview_layer() { void PaintCanvas::clear_preview_layer() {
/* if (preview_layer.is_valid()) {
preview_layer.clear() preview_layer->clear();
*/ }
} }
void PaintCanvas::clear_layer(const String &layer_name) { void PaintCanvas::clear_layer(const String &layer_name) {
/* for (int i = 0; i < layers.size(); ++i) {
for layer in layers: Ref<PaintCanvasLayer> l = layers[i];
if layer.name == layer_name:
layer.clear()
break
*/
}
Node *PaintCanvas::remove_layer(const String &layer_name) {
/*
# change current layer if the active layer is removed
var del_layer = find_layer_by_name(layer_name)
del_layer.clear()
if del_layer == active_layer:
for layer in layers:
if layer == preview_layer or layer == active_layer or layer == tool_layer:
continue
active_layer = layer
break
layers.erase(del_layer)
return active_layer
*/
return nullptr;
}
Node *PaintCanvas::add_new_layer(const String &layer_name) {
/*
for layer in layers:
if layer.name == layer_name:
return
var layer = GELayer.new()
layer.name = layer_name
if layer_name == "Preview": ERR_CONTINUE(!l.is_valid());
layer.create($PreviewLayer, canvas_width, canvas_height)
elif layer_name == "Tool":
layer.create($ToolPreviewLayer, canvas_width, canvas_height)
else:
var texture_rect = TextureRect.new()
texture_rect.name = layer_name
canvas_layers.add_child(texture_rect, true)
texture_rect.expand = true
texture_rect.anchor_right = 1
texture_rect.anchor_bottom = 1
texture_rect.margin_right = 0
texture_rect.margin_bottom = 0
texture_rect.mouse_filter = Control.MOUSE_FILTER_IGNORE
layer.create(texture_rect, canvas_width, canvas_height)
layers.append(layer)
return layer if (l->name == layer_name) {
*/ l->clear();
return nullptr; return;
}
}
} }
Node *PaintCanvas::duplicate_layer(const String &layer_name, const String &new_layer_name) { Ref<PaintCanvasLayer> PaintCanvas::remove_layer(const String &layer_name) {
/* // change current layer if the active layer is removed
for layer in layers: Ref<PaintCanvasLayer> del_layer = find_layer_by_name(layer_name);
if layer.name == new_layer_name:
return
var dup_layer :GELayer = find_layer_by_name(layer_name) del_layer->clear();
var layer :GELayer = add_new_layer(new_layer_name)
layer.image.copy_from(dup_layer.image) if (del_layer == active_layer) {
return layer for (int i = 0; i < layers.size(); ++i) {
*/ Ref<PaintCanvasLayer> layer = layers[i];
return nullptr;
ERR_CONTINUE(!layer.is_valid());
if (layer == preview_layer or layer == active_layer or layer == tool_layer) {
continue;
}
active_layer = layer;
break;
}
}
layers.erase(del_layer);
return active_layer;
}
Ref<PaintCanvasLayer> PaintCanvas::add_new_layer(const String &layer_name) {
for (int i = 0; i < layers.size(); ++i) {
Ref<PaintCanvasLayer> layer = layers[i];
ERR_CONTINUE(!layer.is_valid());
if (layer->name == layer_name) {
return layer;
}
}
Ref<PaintCanvasLayer> layer;
layer.instance();
layer->name = layer_name;
if (layer_name == "Preview") {
layer->create(preview_layer_rect, _canvas_width, _canvas_height);
} else if (layer_name == "Tool") {
layer->create(tool_preview_layer_rect, _canvas_width, _canvas_height);
} else {
TextureRect *texture_rect = memnew(TextureRect);
texture_rect->set_name(layer_name);
canvas_layers->add_child(texture_rect, true);
texture_rect->set_expand(true);
texture_rect->set_anchors_and_margins_preset(Control::PRESET_WIDE);
texture_rect->set_margin(Margin::MARGIN_RIGHT, 0);
texture_rect->set_margin(Margin::MARGIN_BOTTOM, 0);
texture_rect->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
layer->create(texture_rect, _canvas_width, _canvas_height);
layers.push_back(layer);
}
return layer;
}
Ref<PaintCanvasLayer> PaintCanvas::duplicate_layer(const String &layer_name, const String &new_layer_name) {
for (int i = 0; i < layers.size(); ++i) {
Ref<PaintCanvasLayer> layer = layers[i];
ERR_CONTINUE(!layer.is_valid());
if (layer->name == new_layer_name) {
return layer;
}
}
Ref<PaintCanvasLayer> dup_layer = find_layer_by_name(layer_name);
Ref<PaintCanvasLayer> layer = add_new_layer(new_layer_name);
layer->image->copy_internals_from(dup_layer->image);
return layer;
} }
void PaintCanvas::toggle_layer_visibility(const String &layer_name) { void PaintCanvas::toggle_layer_visibility(const String &layer_name) {
/* for (int i = 0; i < layers.size(); ++i) {
for layer in layers: Ref<PaintCanvasLayer> layer = layers[i];
if layer.name == layer_name:
layer.visible = not layer.visible ERR_CONTINUE(!layer.is_valid());
*/
if (layer->name == layer_name) {
layer->set_visible(!layer->get_visible());
return;
}
}
} }
Node *PaintCanvas::find_layer_by_name(const String &layer_name) { Ref<PaintCanvasLayer> PaintCanvas::find_layer_by_name(const String &layer_name) {
/* for (int i = 0; i < layers.size(); ++i) {
for layer in layers: Ref<PaintCanvasLayer> layer = layers[i];
if layer.name == layer_name:
return layer ERR_CONTINUE(!layer.is_valid());
return null
*/ if (layer->name == layer_name) {
return nullptr; return layer;
}
}
return Ref<PaintCanvasLayer>();
} }
void PaintCanvas::toggle_lock_layer(const String &layer_name) { void PaintCanvas::toggle_lock_layer(const String &layer_name) {
/* find_layer_by_name(layer_name)->toggle_lock();
find_layer_by_name(layer_name).toggle_lock()
*/
} }
bool PaintCanvas::is_active_layer_locked() { bool PaintCanvas::is_active_layer_locked() {
/* return active_layer->locked;
return active_layer.locked
*/
return false;
} }
void PaintCanvas::move_layer_forward(const String &layer_name) { void PaintCanvas::move_layer_forward(const String &layer_name) {
/* TextureRect *layer = find_layer_by_name(layer_name)->texture_rect_ref;
var layer = find_layer_by_name(layer_name).texture_rect_ref int new_idx = MAX(layer->get_index() - 1, 0);
var new_idx = max(layer.get_index() - 1, 0) canvas_layers->move_child(layer, new_idx);
canvas_layers.move_child(layer, new_idx)
*/
} }
void PaintCanvas::move_layer_back(const String &layer_name) { void PaintCanvas::move_layer_back(const String &layer_name) {
/* TextureRect *layer = find_layer_by_name(layer_name)->texture_rect_ref;
var layer = find_layer_by_name(layer_name).texture_rect_ref canvas_layers->move_child(layer, layer->get_index() + 1);
canvas_layers.move_child(layer, layer.get_index() + 1)
*/
} }
void PaintCanvas::select_layer(const String &layer_name) { void PaintCanvas::select_layer(const String &layer_name) {
/* active_layer = find_layer_by_name(layer_name);
active_layer = find_layer_by_name(layer_name)
*/
} }
void PaintCanvas::_on_mouse_entered() { void PaintCanvas::_on_mouse_entered() {
/* mouse_on_top = true;
mouse_on_top = true
*/
} }
void PaintCanvas::_on_mouse_exited() { void PaintCanvas::_on_mouse_exited() {
/* mouse_on_top = false;
mouse_on_top = false
*/
} }
bool PaintCanvas::is_inside_canvas(const int x, const int y) { bool PaintCanvas::is_inside_canvas(const int x, const int y) {
/* if (x < 0 or y < 0) {
if x < 0 or y < 0: return false;
return false }
if x >= canvas_width or y >= canvas_height: if (x >= _canvas_width || y >= _canvas_height) {
return false return false;
return true }
*/
return false; return true;
} }
//Note: Arrays are always passed by reference. To get a copy of an array which //Note: Arrays are always passed by reference. To get a copy of an array which
// can be modified independently of the original array, use duplicate. // can be modified independently of the original array, use duplicate.
// (https://docs.godotengine.org/en/stable/classes/class_array.html) // (https://docs.godotengine.org/en/stable/classes/class_array.html)
void PaintCanvas::set_pixel_arr(const Array &pixels, const Color &color) { void PaintCanvas::set_pixel_arr(const PoolVector2iArray &pixels, const Color &color) {
/* PoolVector2iArray::Read r = pixels.read();
for pixel in pixels:
_set_pixel(active_layer, pixel.x, pixel.y, color) for (int i = 0; i < pixels.size(); ++i) {
*/ const Vector2i &pixel = r[i];
_set_pixel(active_layer, pixel.x, pixel.y, color);
}
} }
void PaintCanvas::set_pixel_v(const Vector2 &pos, const Color &color) { void PaintCanvas::set_pixel_v(const Vector2i &pos, const Color &color) {
/* set_pixel(pos.x, pos.y, color);
set_pixel(pos.x, pos.y, color)
*/
} }
void PaintCanvas::set_pixel(const int x, const int y, const Color &color) { void PaintCanvas::set_pixel(const int x, const int y, const Color &color) {
/* _set_pixel(active_layer, x, y, color);
_set_pixel(active_layer, x, y, color)
*/
} }
void PaintCanvas::_set_pixel_v(PaintCanvasLayer *layer, const Vector2 &v, const Color &color) { void PaintCanvas::_set_pixel_v(Ref<PaintCanvasLayer> layer, const Vector2i &v, const Color &color) {
/* _set_pixel(layer, v.x, v.y, color);
_set_pixel(layer, v.x, v.y, color)
*/
} }
void PaintCanvas::_set_pixel(PaintCanvasLayer *layer, const int x, const int y, const Color &color) { void PaintCanvas::_set_pixel(Ref<PaintCanvasLayer> layer, const int x, const int y, const Color &color) {
/* if (!is_inside_canvas(x, y)) {
if not is_inside_canvas(x, y): return;
return }
layer.set_pixel(x, y, color)
*/ layer->set_pixel(x, y, color);
} }
Color PaintCanvas::get_pixel_v(const Vector2 &pos) { Color PaintCanvas::get_pixel_v(const Vector2i &pos) {
/* return get_pixel(pos.x, pos.y);
return get_pixel(pos.x, pos.y)
*/
return Color();
} }
Color PaintCanvas::get_pixel(const int x, const int y) { Color PaintCanvas::get_pixel(const int x, const int y) {
/* if (active_layer.is_valid()) {
if active_layer: return active_layer->get_pixel(x, y);
return active_layer.get_pixel(x, y) }
return null
*/
return Color(); return Color();
} }
void PaintCanvas::set_preview_pixel_v(const Vector2 &pos, const Color &color) { void PaintCanvas::set_preview_pixel_v(const Vector2i &pos, const Color &color) {
/* set_preview_pixel(pos.x, pos.y, color);
set_preview_pixel(pos.x, pos.y, color)
*/
} }
void PaintCanvas::set_preview_pixel(const int x, const int y, const Color &color) { void PaintCanvas::set_preview_pixel(const int x, const int y, const Color &color) {
/* if (!is_inside_canvas(x, y)) {
if not is_inside_canvas(x, y): return;
return }
preview_layer.set_pixel(x, y, color)
*/ preview_layer->set_pixel(x, y, color);
} }
Color PaintCanvas::get_preview_pixel_v(const Vector2 &pos) { Color PaintCanvas::get_preview_pixel_v(const Vector2i &pos) {
/* return get_preview_pixel(pos.x, pos.y);
return get_preview_pixel(pos.x, pos.y)
*/
return Color();
} }
Color PaintCanvas::get_preview_pixel(const int x, const int y) { Color PaintCanvas::get_preview_pixel(const int x, const int y) {
/* if (!preview_layer.is_valid()) {
if not preview_layer: return Color();
return null }
return preview_layer.get_pixel(x, y)
*/ return preview_layer->get_pixel(x, y);
return Color();
} }
void PaintCanvas::toggle_grid() { void PaintCanvas::toggle_grid() {
/* grid->set_visible(!grid->is_visible());
$Grid.visible = not $Grid.visible
*/
} }
void PaintCanvas::show_grid() { void PaintCanvas::show_grid() {
/* grid->show();
$Grid.show()
*/
} }
void PaintCanvas::hide_grid() { void PaintCanvas::hide_grid() {
/* grid->hide();
$Grid.hide()
*/
} }
Array PaintCanvas::select_color(const int x, const int y) { PoolVector2iArray PaintCanvas::select_color(const int x, const int y) {
/* PoolVector2iArray same_color_pixels;
print("???")
var same_color_pixels = []
var color = get_pixel(x, y)
for x in range(active_layer.layer_width):
for y in range(active_layer.layer_height):
var pixel_color = active_layer.get_pixel(x, y)
if pixel_color == color:
same_color_pixels.append(color)
return same_color_pixels
*/
return Array();
}
Array PaintCanvas::select_same_color(const int x, const int y) {
/*
return get_neighbouring_pixels(x, y)
*/
return Array(); Color color = get_pixel(x, y);
for (int x = 0; x < active_layer->layer_width; ++x) {
for (int x = 0; x < active_layer->layer_height; ++x) {
Color pixel_color = active_layer->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 x, const int y) {
return get_neighbouring_pixels(x, y);
} }
// returns array of Vector2 // returns array of Vector2
// yoinked from // yoinked from
// https://www.geeksforgeeks.org/flood-fill-algorithm-implement-fill-paint/ // https://www.geeksforgeeks.org/flood-fill-algorithm-implement-fill-paint/
Array PaintCanvas::get_neighbouring_pixels(const int pos_x, const int pos_y) { PoolVector2iArray PaintCanvas::get_neighbouring_pixels(const int pos_x, const int pos_y) {
/* PoolVector2iArray pixels;
var pixels = []
var to_check_queue = [] PoolIntArray to_check_queue;
var checked_queue = [] PoolIntArray checked_queue;
to_check_queue.append(GEUtils.to_1D(pos_x, pos_y, canvas_width)) to_check_queue.append(PaintUtilities::to_1D(pos_x, pos_y, _canvas_width));
var color = get_pixel(pos_x, pos_y) Color color = get_pixel(pos_x, pos_y);
while not to_check_queue.empty(): while (!to_check_queue.empty()) {
var idx = to_check_queue.pop_front() int idx = to_check_queue[0];
var p = GEUtils.to_2D(idx, canvas_width) to_check_queue.remove(0);
Vector2i p = PaintUtilities::to_2D(idx, _canvas_width);
if idx in checked_queue: bool found = false;
continue PoolIntArray::Read r = checked_queue.read();
for (int i = 0; i < checked_queue.size(); ++i) {
if (r[i] == idx) {
found = true;
break;
}
}
r.release();
checked_queue.append(idx) if (!found) {
continue;
}
if get_pixel(p.x, p.y) != color: checked_queue.append(idx);
continue
# add to result if (get_pixel(p.x, p.y) != color) {
pixels.append(p) continue;
}
# check neighbours // add to result
var x = p.x - 1 pixels.append(p);
var y = p.y
if is_inside_canvas(x, y):
idx = GEUtils.to_1D(x, y, canvas_width)
to_check_queue.append(idx)
x = p.x + 1 // check neighbours
if is_inside_canvas(x, y): int x = p.x - 1;
idx = GEUtils.to_1D(x, y, canvas_width) int y = p.y;
to_check_queue.append(idx) if (is_inside_canvas(x, y)) {
idx = PaintUtilities::to_1D(x, y, _canvas_width);
to_check_queue.append(idx);
}
x = p.x x = p.x + 1;
y = p.y - 1 if (is_inside_canvas(x, y)) {
if is_inside_canvas(x, y): idx = PaintUtilities::to_1D(x, y, _canvas_width);
idx = GEUtils.to_1D(x, y, canvas_width) to_check_queue.append(idx);
to_check_queue.append(idx) }
y = p.y + 1 x = p.x;
if is_inside_canvas(x, y): y = p.y - 1;
idx = GEUtils.to_1D(x, y, canvas_width) if (is_inside_canvas(x, y)) {
to_check_queue.append(idx) idx = PaintUtilities::to_1D(x, y, _canvas_width);
to_check_queue.append(idx);
}
return pixels y = p.y + 1;
*/ if (is_inside_canvas(x, y)) {
return Array(); idx = PaintUtilities::to_1D(x, y, _canvas_width);
to_check_queue.append(idx);
}
}
return pixels;
} }
void PaintCanvas::resize(const int width, const int height) { void PaintCanvas::resize(int width, int height) {
/* if (width < 0) {
if width < 0: width = 1;
width = 1 }
if height < 0:
height = 1
set_canvas_width(width) if (height < 0) {
set_canvas_height(height) height = 1;
}
preview_layer.resize(width, height) set_canvas_width(width);
tool_layer.resize(width, height) set_canvas_height(height);
for layer in layers:
layer.resize(width, height) preview_layer->resize(width, height);
*/ tool_layer->resize(width, height);
for (int i = 0; i < layers.size(); ++i) {
Ref<PaintCanvasLayer> layer = layers[i];
ERR_CONTINUE(!layer.is_valid());
layer->resize(width, height);
}
}
void PaintCanvas::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
_enter_tree();
} break;
case NOTIFICATION_PROCESS: {
_process(get_process_delta_time());
} break;
case NOTIFICATION_DRAW: {
_draw();
} break;
}
} }
PaintCanvas::PaintCanvas() { PaintCanvas::PaintCanvas() {
@ -584,4 +605,6 @@ PaintCanvas::~PaintCanvas() {
} }
void PaintCanvas::_bind_methods() { void PaintCanvas::_bind_methods() {
ClassDB::bind_method(D_METHOD("_on_mouse_entered"), &PaintCanvas::_on_mouse_entered);
ClassDB::bind_method(D_METHOD("_on_mouse_exited"), &PaintCanvas::_on_mouse_exited);
} }

View File

@ -67,16 +67,16 @@ public:
Rect2 get_content_margin(); Rect2 get_content_margin();
void crop_to_content(); void crop_to_content();
Node *get_active_layer(); Ref<PaintCanvasLayer> get_active_layer();
Node *get_preview_layer(); Ref<PaintCanvasLayer> get_preview_layer();
void clear_active_layer(); void clear_active_layer();
void clear_preview_layer(); void clear_preview_layer();
void clear_layer(const String &layer_name); void clear_layer(const String &layer_name);
Node *remove_layer(const String &layer_name); Ref<PaintCanvasLayer> remove_layer(const String &layer_name);
Node *add_new_layer(const String &layer_name); Ref<PaintCanvasLayer> add_new_layer(const String &layer_name);
Node *duplicate_layer(const String &layer_name, const String &new_layer_name); Ref<PaintCanvasLayer> duplicate_layer(const String &layer_name, const String &new_layer_name);
void toggle_layer_visibility(const String &layer_name); void toggle_layer_visibility(const String &layer_name);
Node *find_layer_by_name(const String &layer_name); Ref<PaintCanvasLayer> find_layer_by_name(const String &layer_name);
void toggle_lock_layer(const String &layer_name); void toggle_lock_layer(const String &layer_name);
bool is_active_layer_locked(); bool is_active_layer_locked();
void move_layer_forward(const String &layer_name); void move_layer_forward(const String &layer_name);
@ -87,27 +87,27 @@ public:
void _on_mouse_exited(); void _on_mouse_exited();
bool is_inside_canvas(const int x, const int y); bool is_inside_canvas(const int x, const int y);
void set_pixel_arr(const Array &pixels, const Color &color); void set_pixel_arr(const PoolVector2iArray &pixels, const Color &color);
void set_pixel_v(const Vector2 &pos, const Color &color); void set_pixel_v(const Vector2i &pos, const Color &color);
void set_pixel(const int x, const int y, const Color &color); void set_pixel(const int x, const int y, const Color &color);
void _set_pixel_v(PaintCanvasLayer *layer, const Vector2 &v, const Color &color); void _set_pixel_v(Ref<PaintCanvasLayer> layer, const Vector2i &v, const Color &color);
void _set_pixel(PaintCanvasLayer *layer, const int x, const int y, const Color &color); void _set_pixel(Ref<PaintCanvasLayer> layer, const int x, const int y, const Color &color);
Color get_pixel_v(const Vector2 &pos); Color get_pixel_v(const Vector2i &pos);
Color get_pixel(const int x, const int y); Color get_pixel(const int x, const int y);
void set_preview_pixel_v(const Vector2 &pos, const Color &color); void set_preview_pixel_v(const Vector2i &pos, const Color &color);
void set_preview_pixel(const int x, const int y, const Color &color); void set_preview_pixel(const int x, const int y, const Color &color);
Color get_preview_pixel_v(const Vector2 &pos); Color get_preview_pixel_v(const Vector2i &pos);
Color get_preview_pixel(const int x, const int y); Color get_preview_pixel(const int x, const int y);
void toggle_grid(); void toggle_grid();
void show_grid(); void show_grid();
void hide_grid(); void hide_grid();
Array select_color(const int x, const int y); PoolVector2iArray select_color(const int x, const int y);
Array select_same_color(const int x, const int y); PoolVector2iArray select_same_color(const int x, const int y);
Array get_neighbouring_pixels(const int pos_x, const int pos_y); PoolVector2iArray get_neighbouring_pixels(const int pos_x, const int pos_y);
void resize(const int width, const int height); void resize(int width, int height);
PaintCanvas(); PaintCanvas();
~PaintCanvas(); ~PaintCanvas();
@ -136,6 +136,7 @@ public:
Array selected_pixels; Array selected_pixels;
protected: protected:
void _notification(int p_what);
static void _bind_methods(); static void _bind_methods();
int _pixel_size; int _pixel_size;

View File

@ -1055,7 +1055,6 @@ PaintWindow::PaintWindow() {
paint_canvas->set_h_size_flags(SIZE_EXPAND_FILL); paint_canvas->set_h_size_flags(SIZE_EXPAND_FILL);
paint_canvas->set_v_size_flags(SIZE_EXPAND_FILL); paint_canvas->set_v_size_flags(SIZE_EXPAND_FILL);
paint_canvas->set_size(Size2(256, 256)); paint_canvas->set_size(Size2(256, 256));
paint_canvas->set_position(Point2());
paint_canvas->set_anchors_and_margins_preset(Control::PRESET_CENTER); paint_canvas->set_anchors_and_margins_preset(Control::PRESET_CENTER);
paint_canvas_container->add_child(paint_canvas); paint_canvas_container->add_child(paint_canvas);
navbar->canvas = paint_canvas; navbar->canvas = paint_canvas;