mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-02-20 14:44:21 +01:00
Ported the logic for PaintCanvas.
This commit is contained in:
parent
3461d692d4
commit
5e368ec978
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user