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_outline.h"
#include "paint_utilities.h"
#include "paint_visual_grid.h"
#include "scene/gui/control.h"
#include "scene/gui/texture_rect.h"
@ -32,51 +33,38 @@ SOFTWARE.
#include "paint_canvas_layer.h"
void PaintCanvas::_enter_tree() {
/*
#-------------------------------
# Set nodes
#-------------------------------
canvas = find_node("Canvas")
grid = find_node("Grid")
big_grid = find_node("BigGrid")
canvas_layers = find_node("CanvasLayers")
connect("mouse_entered", this, "_on_mouse_entered");
connect("mouse_exited", this, "_on_mouse_exited");
#-------------------------------
# setup layers and canvas
#-------------------------------
connect("mouse_entered", self, "_on_mouse_entered")
connect("mouse_exited", self, "_on_mouse_exited")
//canvas_size = Vector2(int(rect_size.x / grid_size), int(rect_size.y / grid_size));
//pixel_size = canvas_size;
#-------------------------------
# setup layers and canvas
#-------------------------------
#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");
preview_layer = add_new_layer("Preview");
tool_layer = add_new_layer("Tool");
active_layer = add_new_layer("Layer1")
preview_layer = add_new_layer("Preview")
tool_layer = add_new_layer("Tool")
set_process(true)
*/
set_process(true);
}
void PaintCanvas::_process(float delta) {
/*
if not is_visible_in_tree():
return
var mouse_position = get_local_mouse_position()
var rect = Rect2(Vector2(0, 0), rect_size)
mouse_in_region = rect.has_point(mouse_position)
*/
if (!is_visible_in_tree()) {
return;
}
Vector2 mouse_position = get_local_mouse_position();
Rect2 rect = Rect2(Vector2(0, 0), get_size());
mouse_in_region = rect.has_point(mouse_position);
}
void PaintCanvas::_draw() {
/*
for layer in layers:
layer.update_texture()
for (int i = 0; i < layers.size(); ++i) {
Ref<PaintCanvasLayer> layer = layers[i];
preview_layer.update_texture()
tool_layer.update_texture()
*/
ERR_CONTINUE(!layer.is_valid());
layer->update_texture();
}
preview_layer->update_texture();
tool_layer->update_texture();
}
int PaintCanvas::get_pixel_size() const {
@ -84,92 +72,100 @@ int PaintCanvas::get_pixel_size() const {
}
void PaintCanvas::set_pixel_size(const int size) {
/*
pixel_size = size
set_grid_size(grid_size)
set_big_grid_size(big_grid_size)
set_canvas_width(canvas_width)
set_canvas_height(canvas_height)
*/
_pixel_size = size;
set_grid_size(_grid_size);
set_big_grid_size(_big_grid_size);
set_canvas_width(_canvas_width);
set_canvas_height(_canvas_height);
}
int PaintCanvas::get_grid_size() const {
return _grid_size;
}
void PaintCanvas::set_grid_size(const int size) {
/*
grid_size = size
if not find_node("Grid"):
return
find_node("Grid").size = size * pixel_size
*/
_grid_size = size;
if (grid) {
int s = size * _pixel_size;
grid->set_size(Size2(s, s));
}
}
int PaintCanvas::get_big_grid_size() const {
return _big_grid_size;
}
void PaintCanvas::set_big_grid_size(const int size) {
/*
big_grid_size = size
if not find_node("BigGrid"):
return
find_node("BigGrid").size = size * pixel_size
*/
_big_grid_size = size;
if (big_grid) {
int s = size * _pixel_size;
grid->set_size(Size2(s, s));
}
}
int PaintCanvas::get_canvas_width() const {
return _canvas_width;
}
void PaintCanvas::set_canvas_width(const int val) {
/*
canvas_width = val
rect_size.x = canvas_width * pixel_size
*/
_canvas_width = val;
Size2 s = get_size();
s.x = _canvas_width * _pixel_size;
set_size(s);
}
int PaintCanvas::get_canvas_height() const {
return _canvas_height;
}
void PaintCanvas::set_canvas_height(const int val) {
/*
canvas_height = val
rect_size.y = canvas_height * pixel_size
*/
_canvas_height = val;
Size2 s = get_size();
s.x = _canvas_height * _pixel_size;
set_size(s);
}
void PaintCanvas::toggle_alpha_locked(const String &layer_name) {
/*
var layer = find_layer_by_name(layer_name)
layer.toggle_alpha_locked()
*/
Ref<PaintCanvasLayer> layer = find_layer_by_name(layer_name);
if (layer.is_valid()) {
layer->toggle_alpha_locked();
}
}
bool PaintCanvas::is_alpha_locked() {
/*
return active_layer.alpha_locked
*/
return false;
if (!active_layer.is_valid()) {
return false;
}
return active_layer->alpha_locked;
}
Rect2 PaintCanvas::get_content_margin() {
/*
var rect = Rect2(999999, 999999, -999999, -999999)
Rect2 rect = Rect2(999999, 999999, -999999, -999999);
preview_layer.image.get_used_rect()
for layer in layers:
for (int i = 0; i < layers.size(); ++i) {
Ref<PaintCanvasLayer> l = layers[i];
var r = layer.image.get_used_rect()
ERR_CONTINUE(!l.is_valid());
if r.position.x < rect.position.x:
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
Rect2 r = l->image->get_used_rect();
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() {
/*
@ -189,347 +185,372 @@ void PaintCanvas::crop_to_content() {
# layer.resize(width, height)
*/
}
Node *PaintCanvas::get_active_layer() {
/*
return active_layer
*/
return nullptr;
Ref<PaintCanvasLayer> PaintCanvas::get_active_layer() {
return active_layer;
}
Node *PaintCanvas::get_preview_layer() {
/*
return preview_layer
*/
return nullptr;
Ref<PaintCanvasLayer> PaintCanvas::get_preview_layer() {
return preview_layer;
}
void PaintCanvas::clear_active_layer() {
/*
active_layer.clear()
*/
if (active_layer.is_valid()) {
active_layer->clear();
}
}
void PaintCanvas::clear_preview_layer() {
/*
preview_layer.clear()
*/
if (preview_layer.is_valid()) {
preview_layer->clear();
}
}
void PaintCanvas::clear_layer(const String &layer_name) {
/*
for layer in layers:
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
for (int i = 0; i < layers.size(); ++i) {
Ref<PaintCanvasLayer> l = layers[i];
if layer_name == "Preview":
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)
ERR_CONTINUE(!l.is_valid());
return layer
*/
return nullptr;
if (l->name == layer_name) {
l->clear();
return;
}
}
}
Node *PaintCanvas::duplicate_layer(const String &layer_name, const String &new_layer_name) {
/*
for layer in layers:
if layer.name == new_layer_name:
return
Ref<PaintCanvasLayer> PaintCanvas::remove_layer(const String &layer_name) {
// change current layer if the active layer is removed
Ref<PaintCanvasLayer> del_layer = find_layer_by_name(layer_name);
var dup_layer :GELayer = find_layer_by_name(layer_name)
var layer :GELayer = add_new_layer(new_layer_name)
layer.image.copy_from(dup_layer.image)
return layer
*/
return nullptr;
del_layer->clear();
if (del_layer == active_layer) {
for (int i = 0; i < layers.size(); ++i) {
Ref<PaintCanvasLayer> layer = layers[i];
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) {
/*
for layer in layers:
if layer.name == layer_name:
layer.visible = not layer.visible
*/
for (int i = 0; i < layers.size(); ++i) {
Ref<PaintCanvasLayer> layer = layers[i];
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) {
/*
for layer in layers:
if layer.name == layer_name:
return layer
return null
*/
return nullptr;
Ref<PaintCanvasLayer> PaintCanvas::find_layer_by_name(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;
}
}
return Ref<PaintCanvasLayer>();
}
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() {
/*
return active_layer.locked
*/
return false;
return active_layer->locked;
}
void PaintCanvas::move_layer_forward(const String &layer_name) {
/*
var layer = find_layer_by_name(layer_name).texture_rect_ref
var new_idx = max(layer.get_index() - 1, 0)
canvas_layers.move_child(layer, new_idx)
*/
TextureRect *layer = find_layer_by_name(layer_name)->texture_rect_ref;
int new_idx = MAX(layer->get_index() - 1, 0);
canvas_layers->move_child(layer, new_idx);
}
void PaintCanvas::move_layer_back(const String &layer_name) {
/*
var layer = find_layer_by_name(layer_name).texture_rect_ref
canvas_layers.move_child(layer, layer.get_index() + 1)
*/
TextureRect *layer = find_layer_by_name(layer_name)->texture_rect_ref;
canvas_layers->move_child(layer, layer->get_index() + 1);
}
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() {
/*
mouse_on_top = true
*/
mouse_on_top = true;
}
void PaintCanvas::_on_mouse_exited() {
/*
mouse_on_top = false
*/
mouse_on_top = false;
}
bool PaintCanvas::is_inside_canvas(const int x, const int y) {
/*
if x < 0 or y < 0:
return false
if x >= canvas_width or y >= canvas_height:
return false
return true
*/
return false;
if (x < 0 or y < 0) {
return false;
}
if (x >= _canvas_width || y >= _canvas_height) {
return false;
}
return true;
}
//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.
// (https://docs.godotengine.org/en/stable/classes/class_array.html)
void PaintCanvas::set_pixel_arr(const Array &pixels, const Color &color) {
/*
for pixel in pixels:
_set_pixel(active_layer, pixel.x, pixel.y, color)
*/
void PaintCanvas::set_pixel_arr(const PoolVector2iArray &pixels, const Color &color) {
PoolVector2iArray::Read r = pixels.read();
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) {
/*
set_pixel(pos.x, pos.y, color)
*/
void PaintCanvas::set_pixel_v(const Vector2i &pos, const Color &color) {
set_pixel(pos.x, pos.y, 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) {
/*
_set_pixel(layer, v.x, v.y, color)
*/
void PaintCanvas::_set_pixel_v(Ref<PaintCanvasLayer> layer, const Vector2i &v, const Color &color) {
_set_pixel(layer, v.x, v.y, color);
}
void PaintCanvas::_set_pixel(PaintCanvasLayer *layer, const int x, const int y, const Color &color) {
/*
if not is_inside_canvas(x, y):
return
layer.set_pixel(x, y, color)
*/
void PaintCanvas::_set_pixel(Ref<PaintCanvasLayer> layer, const int x, const int y, const Color &color) {
if (!is_inside_canvas(x, y)) {
return;
}
layer->set_pixel(x, y, color);
}
Color PaintCanvas::get_pixel_v(const Vector2 &pos) {
/*
return get_pixel(pos.x, pos.y)
*/
return Color();
Color PaintCanvas::get_pixel_v(const Vector2i &pos) {
return get_pixel(pos.x, pos.y);
}
Color PaintCanvas::get_pixel(const int x, const int y) {
/*
if active_layer:
return active_layer.get_pixel(x, y)
return null
*/
if (active_layer.is_valid()) {
return active_layer->get_pixel(x, y);
}
return Color();
}
void PaintCanvas::set_preview_pixel_v(const Vector2 &pos, const Color &color) {
/*
set_preview_pixel(pos.x, pos.y, color)
*/
void PaintCanvas::set_preview_pixel_v(const Vector2i &pos, const Color &color) {
set_preview_pixel(pos.x, pos.y, color);
}
void PaintCanvas::set_preview_pixel(const int x, const int y, const Color &color) {
/*
if not is_inside_canvas(x, y):
return
preview_layer.set_pixel(x, y, color)
*/
if (!is_inside_canvas(x, y)) {
return;
}
preview_layer->set_pixel(x, y, color);
}
Color PaintCanvas::get_preview_pixel_v(const Vector2 &pos) {
/*
return get_preview_pixel(pos.x, pos.y)
*/
return Color();
Color PaintCanvas::get_preview_pixel_v(const Vector2i &pos) {
return get_preview_pixel(pos.x, pos.y);
}
Color PaintCanvas::get_preview_pixel(const int x, const int y) {
/*
if not preview_layer:
return null
return preview_layer.get_pixel(x, y)
*/
return Color();
if (!preview_layer.is_valid()) {
return Color();
}
return preview_layer->get_pixel(x, y);
}
void PaintCanvas::toggle_grid() {
/*
$Grid.visible = not $Grid.visible
*/
grid->set_visible(!grid->is_visible());
}
void PaintCanvas::show_grid() {
/*
$Grid.show()
*/
grid->show();
}
void PaintCanvas::hide_grid() {
/*
$Grid.hide()
*/
grid->hide();
}
Array PaintCanvas::select_color(const int x, const int y) {
/*
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)
*/
PoolVector2iArray PaintCanvas::select_color(const int x, const int y) {
PoolVector2iArray same_color_pixels;
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
// yoinked from
// https://www.geeksforgeeks.org/flood-fill-algorithm-implement-fill-paint/
Array PaintCanvas::get_neighbouring_pixels(const int pos_x, const int pos_y) {
/*
var pixels = []
PoolVector2iArray PaintCanvas::get_neighbouring_pixels(const int pos_x, const int pos_y) {
PoolVector2iArray pixels;
var to_check_queue = []
var checked_queue = []
PoolIntArray to_check_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():
var idx = to_check_queue.pop_front()
var p = GEUtils.to_2D(idx, canvas_width)
while (!to_check_queue.empty()) {
int idx = to_check_queue[0];
to_check_queue.remove(0);
Vector2i p = PaintUtilities::to_2D(idx, _canvas_width);
if idx in checked_queue:
continue
bool found = false;
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:
continue
checked_queue.append(idx);
# add to result
pixels.append(p)
if (get_pixel(p.x, p.y) != color) {
continue;
}
# check neighbours
var x = p.x - 1
var y = p.y
if is_inside_canvas(x, y):
idx = GEUtils.to_1D(x, y, canvas_width)
to_check_queue.append(idx)
// add to result
pixels.append(p);
x = p.x + 1
if is_inside_canvas(x, y):
idx = GEUtils.to_1D(x, y, canvas_width)
to_check_queue.append(idx)
// check neighbours
int x = p.x - 1;
int y = p.y;
if (is_inside_canvas(x, y)) {
idx = PaintUtilities::to_1D(x, y, _canvas_width);
to_check_queue.append(idx);
}
x = p.x
y = p.y - 1
if is_inside_canvas(x, y):
idx = GEUtils.to_1D(x, y, canvas_width)
to_check_queue.append(idx)
x = p.x + 1;
if (is_inside_canvas(x, y)) {
idx = PaintUtilities::to_1D(x, y, _canvas_width);
to_check_queue.append(idx);
}
y = p.y + 1
if is_inside_canvas(x, y):
idx = GEUtils.to_1D(x, y, canvas_width)
to_check_queue.append(idx)
x = p.x;
y = p.y - 1;
if (is_inside_canvas(x, y)) {
idx = PaintUtilities::to_1D(x, y, _canvas_width);
to_check_queue.append(idx);
}
return pixels
*/
return Array();
y = p.y + 1;
if (is_inside_canvas(x, y)) {
idx = PaintUtilities::to_1D(x, y, _canvas_width);
to_check_queue.append(idx);
}
}
return pixels;
}
void PaintCanvas::resize(const int width, const int height) {
/*
if width < 0:
width = 1
if height < 0:
height = 1
void PaintCanvas::resize(int width, int height) {
if (width < 0) {
width = 1;
}
set_canvas_width(width)
set_canvas_height(height)
if (height < 0) {
height = 1;
}
preview_layer.resize(width, height)
tool_layer.resize(width, height)
for layer in layers:
layer.resize(width, height)
*/
set_canvas_width(width);
set_canvas_height(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() {
@ -584,4 +605,6 @@ PaintCanvas::~PaintCanvas() {
}
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();
void crop_to_content();
Node *get_active_layer();
Node *get_preview_layer();
Ref<PaintCanvasLayer> get_active_layer();
Ref<PaintCanvasLayer> get_preview_layer();
void clear_active_layer();
void clear_preview_layer();
void clear_layer(const String &layer_name);
Node *remove_layer(const String &layer_name);
Node *add_new_layer(const String &layer_name);
Node *duplicate_layer(const String &layer_name, const String &new_layer_name);
Ref<PaintCanvasLayer> remove_layer(const String &layer_name);
Ref<PaintCanvasLayer> add_new_layer(const String &layer_name);
Ref<PaintCanvasLayer> duplicate_layer(const String &layer_name, const String &new_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);
bool is_active_layer_locked();
void move_layer_forward(const String &layer_name);
@ -87,27 +87,27 @@ public:
void _on_mouse_exited();
bool is_inside_canvas(const int x, const int y);
void set_pixel_arr(const Array &pixels, const Color &color);
void set_pixel_v(const Vector2 &pos, const Color &color);
void set_pixel_arr(const PoolVector2iArray &pixels, 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_v(PaintCanvasLayer *layer, const Vector2 &v, const Color &color);
void _set_pixel(PaintCanvasLayer *layer, const int x, const int y, const Color &color);
Color get_pixel_v(const Vector2 &pos);
void _set_pixel_v(Ref<PaintCanvasLayer> layer, const Vector2i &v, const Color &color);
void _set_pixel(Ref<PaintCanvasLayer> layer, const int x, const int y, const Color &color);
Color get_pixel_v(const Vector2i &pos);
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);
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);
void toggle_grid();
void show_grid();
void hide_grid();
Array select_color(const int x, const int y);
Array select_same_color(const int x, const int y);
Array get_neighbouring_pixels(const int pos_x, const int pos_y);
PoolVector2iArray select_color(const int x, const int y);
PoolVector2iArray select_same_color(const int x, const int 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();
@ -136,6 +136,7 @@ public:
Array selected_pixels;
protected:
void _notification(int p_what);
static void _bind_methods();
int _pixel_size;

View File

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