mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-02-19 22:24:23 +01:00
Created the rest of the skeleton classes for the paint module, and moved the code into them.
This commit is contained in:
parent
a662e12c3c
commit
e70fb4a67e
@ -1,461 +0,0 @@
|
||||
extends Control
|
||||
class_name GECanvas
|
||||
tool
|
||||
|
||||
export var pixel_size: int = 16 setget set_pixel_size
|
||||
export(int, 1, 2500) var canvas_width = 48 setget set_canvas_width # == pixels
|
||||
export(int, 1, 2500) var canvas_height = 28 setget set_canvas_height # == pixels
|
||||
export var grid_size = 16 setget set_grid_size
|
||||
export var big_grid_size = 10 setget set_big_grid_size
|
||||
export var can_draw = true
|
||||
|
||||
var mouse_in_region
|
||||
var mouse_on_top
|
||||
|
||||
var layers : Array = [] # Key: layer_name, val: GELayer
|
||||
var active_layer: GELayer
|
||||
var preview_layer: GELayer
|
||||
var tool_layer: GELayer
|
||||
var canvas_layers: Control
|
||||
|
||||
var canvas
|
||||
var grid
|
||||
var big_grid
|
||||
var selected_pixels = []
|
||||
|
||||
var symmetry_x = false
|
||||
var symmetry_y = false
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
#-------------------------------
|
||||
# Set nodes
|
||||
#-------------------------------
|
||||
canvas = find_node("Canvas")
|
||||
grid = find_node("Grid")
|
||||
big_grid = find_node("BigGrid")
|
||||
canvas_layers = find_node("CanvasLayers")
|
||||
|
||||
#-------------------------------
|
||||
# setup layers and canvas
|
||||
#-------------------------------
|
||||
connect("mouse_entered", self, "_on_mouse_entered")
|
||||
connect("mouse_exited", self, "_on_mouse_exited")
|
||||
|
||||
#-------------------------------
|
||||
# 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")
|
||||
|
||||
set_process(true)
|
||||
|
||||
|
||||
func _process(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)
|
||||
|
||||
|
||||
func _draw():
|
||||
for layer in layers:
|
||||
layer.update_texture()
|
||||
|
||||
preview_layer.update_texture()
|
||||
tool_layer.update_texture()
|
||||
|
||||
|
||||
func resize(width: int, height: int):
|
||||
if width < 0:
|
||||
width = 1
|
||||
if height < 0:
|
||||
height = 1
|
||||
|
||||
set_canvas_width(width)
|
||||
set_canvas_height(height)
|
||||
|
||||
preview_layer.resize(width, height)
|
||||
tool_layer.resize(width, height)
|
||||
for layer in layers:
|
||||
layer.resize(width, height)
|
||||
|
||||
|
||||
#-------------------------------
|
||||
# Export
|
||||
#-------------------------------
|
||||
|
||||
func set_pixel_size(size: int):
|
||||
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)
|
||||
|
||||
|
||||
func set_grid_size(size):
|
||||
grid_size = size
|
||||
if not find_node("Grid"):
|
||||
return
|
||||
find_node("Grid").size = size * pixel_size
|
||||
|
||||
|
||||
func set_big_grid_size(size):
|
||||
big_grid_size = size
|
||||
if not find_node("BigGrid"):
|
||||
return
|
||||
find_node("BigGrid").size = size * pixel_size
|
||||
|
||||
|
||||
func set_canvas_width(val: int):
|
||||
canvas_width = val
|
||||
rect_size.x = canvas_width * pixel_size
|
||||
|
||||
|
||||
func set_canvas_height(val: int):
|
||||
canvas_height = val
|
||||
rect_size.y = canvas_height * pixel_size
|
||||
|
||||
|
||||
#-------------------------------
|
||||
# Layer
|
||||
#-------------------------------
|
||||
|
||||
|
||||
|
||||
func toggle_alpha_locked(layer_name: String):
|
||||
var layer = find_layer_by_name(layer_name)
|
||||
layer.toggle_alpha_locked()
|
||||
|
||||
|
||||
func is_alpha_locked() -> bool:
|
||||
return active_layer.alpha_locked
|
||||
|
||||
|
||||
func get_content_margin() -> Rect2:
|
||||
var rect = Rect2(999999, 999999, -999999, -999999)
|
||||
|
||||
preview_layer.image.get_used_rect()
|
||||
for layer in layers:
|
||||
|
||||
var r = layer.image.get_used_rect()
|
||||
|
||||
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
|
||||
|
||||
return rect
|
||||
|
||||
|
||||
func crop_to_content():
|
||||
var rect = get_content_margin()
|
||||
|
||||
#print(rect)
|
||||
|
||||
for layer in layers:
|
||||
layer.image
|
||||
|
||||
# set_canvas_width(rect.size.x)
|
||||
# set_canvas_height(rect.size.x)
|
||||
|
||||
# preview_layer.resize(width, height)
|
||||
# tool_layer.resize(width, height)
|
||||
# for layer in layers:
|
||||
# layer.resize(width, height)
|
||||
|
||||
|
||||
func get_active_layer():
|
||||
return active_layer
|
||||
|
||||
|
||||
func get_preview_layer():
|
||||
return preview_layer
|
||||
|
||||
|
||||
func clear_active_layer():
|
||||
active_layer.clear()
|
||||
|
||||
|
||||
func clear_preview_layer():
|
||||
preview_layer.clear()
|
||||
|
||||
|
||||
func clear_layer(layer_name: String):
|
||||
for layer in layers:
|
||||
if layer.name == layer_name:
|
||||
layer.clear()
|
||||
break
|
||||
|
||||
|
||||
func remove_layer(layer_name: String):
|
||||
# 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
|
||||
|
||||
|
||||
func add_new_layer(layer_name: String):
|
||||
for layer in layers:
|
||||
if layer.name == layer_name:
|
||||
return
|
||||
var layer = GELayer.new()
|
||||
layer.name = layer_name
|
||||
|
||||
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)
|
||||
|
||||
return layer
|
||||
|
||||
|
||||
func duplicate_layer(layer_name: String, new_layer_name: String):
|
||||
for layer in layers:
|
||||
if layer.name == new_layer_name:
|
||||
return
|
||||
|
||||
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
|
||||
|
||||
|
||||
func toggle_layer_visibility(layer_name: String):
|
||||
for layer in layers:
|
||||
if layer.name == layer_name:
|
||||
layer.visible = not layer.visible
|
||||
|
||||
|
||||
func find_layer_by_name(layer_name: String):
|
||||
for layer in layers:
|
||||
if layer.name == layer_name:
|
||||
return layer
|
||||
return null
|
||||
|
||||
|
||||
func toggle_lock_layer(layer_name: String):
|
||||
find_layer_by_name(layer_name).toggle_lock()
|
||||
|
||||
|
||||
func is_active_layer_locked() -> bool:
|
||||
return active_layer.locked
|
||||
|
||||
|
||||
func move_layer_forward(layer_name: String):
|
||||
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)
|
||||
|
||||
|
||||
func move_layer_back(layer_name: String):
|
||||
var layer = find_layer_by_name(layer_name).texture_rect_ref
|
||||
canvas_layers.move_child(layer, layer.get_index() + 1)
|
||||
|
||||
|
||||
func select_layer(layer_name: String):
|
||||
active_layer = find_layer_by_name(layer_name)
|
||||
|
||||
|
||||
#-------------------------------
|
||||
# Check
|
||||
#-------------------------------
|
||||
|
||||
func _on_mouse_entered():
|
||||
mouse_on_top = true
|
||||
|
||||
|
||||
func _on_mouse_exited():
|
||||
mouse_on_top = false
|
||||
|
||||
|
||||
func is_inside_canvas(x, y):
|
||||
if x < 0 or y < 0:
|
||||
return false
|
||||
if x >= canvas_width or y >= canvas_height:
|
||||
return false
|
||||
return true
|
||||
|
||||
|
||||
|
||||
#-------------------------------
|
||||
# Basic pixel-layer options
|
||||
#-------------------------------
|
||||
|
||||
|
||||
#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)
|
||||
func set_pixel_arr(pixels: Array, color: Color):
|
||||
for pixel in pixels:
|
||||
_set_pixel(active_layer, pixel.x, pixel.y, color)
|
||||
|
||||
|
||||
func set_pixel_v(pos: Vector2, color: Color):
|
||||
set_pixel(pos.x, pos.y, color)
|
||||
|
||||
|
||||
func set_pixel(x: int, y: int, color: Color):
|
||||
_set_pixel(active_layer, x, y, color)
|
||||
|
||||
|
||||
func _set_pixel_v(layer: GELayer, v: Vector2, color: Color):
|
||||
_set_pixel(layer, v.x, v.y, color)
|
||||
|
||||
|
||||
func _set_pixel(layer: GELayer, x: int, y: int, color: Color):
|
||||
if not is_inside_canvas(x, y):
|
||||
return
|
||||
layer.set_pixel(x, y, color)
|
||||
|
||||
|
||||
func get_pixel_v(pos: Vector2):
|
||||
return get_pixel(pos.x, pos.y)
|
||||
|
||||
|
||||
func get_pixel(x: int, y: int):
|
||||
if active_layer:
|
||||
return active_layer.get_pixel(x, y)
|
||||
return null
|
||||
|
||||
|
||||
func set_preview_pixel_v(pos: Vector2, color: Color):
|
||||
set_preview_pixel(pos.x, pos.y, color)
|
||||
|
||||
|
||||
func set_preview_pixel(x:int, y: int, color: Color):
|
||||
if not is_inside_canvas(x, y):
|
||||
return
|
||||
preview_layer.set_pixel(x, y, color)
|
||||
|
||||
|
||||
func get_preview_pixel_v(pos: Vector2):
|
||||
return get_preview_pixel(pos.x, pos.y)
|
||||
|
||||
|
||||
func get_preview_pixel(x: int, y: int):
|
||||
if not preview_layer:
|
||||
return null
|
||||
return preview_layer.get_pixel(x, y)
|
||||
|
||||
|
||||
|
||||
#-------------------------------
|
||||
# Grid
|
||||
#-------------------------------
|
||||
|
||||
|
||||
func toggle_grid():
|
||||
$Grid.visible = not $Grid.visible
|
||||
|
||||
|
||||
func show_grid():
|
||||
$Grid.show()
|
||||
|
||||
|
||||
func hide_grid():
|
||||
$Grid.hide()
|
||||
|
||||
|
||||
#-------------------------------
|
||||
# Handy tools
|
||||
#-------------------------------
|
||||
|
||||
|
||||
func select_color(x, 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
|
||||
|
||||
|
||||
func select_same_color(x, y):
|
||||
return get_neighbouring_pixels(x, y)
|
||||
|
||||
|
||||
# returns array of Vector2
|
||||
# yoinked from
|
||||
# https://www.geeksforgeeks.org/flood-fill-algorithm-implement-fill-paint/
|
||||
func get_neighbouring_pixels(pos_x: int, pos_y: int) -> Array:
|
||||
var pixels = []
|
||||
|
||||
var to_check_queue = []
|
||||
var checked_queue = []
|
||||
|
||||
to_check_queue.append(GEUtils.to_1D(pos_x, pos_y, canvas_width))
|
||||
|
||||
var 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)
|
||||
|
||||
if idx in checked_queue:
|
||||
continue
|
||||
|
||||
checked_queue.append(idx)
|
||||
|
||||
if get_pixel(p.x, p.y) != color:
|
||||
continue
|
||||
|
||||
# add to result
|
||||
pixels.append(p)
|
||||
|
||||
# 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)
|
||||
|
||||
x = p.x + 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 = GEUtils.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)
|
||||
|
||||
return pixels
|
||||
|
@ -1,34 +0,0 @@
|
||||
tool
|
||||
extends GridContainer
|
||||
|
||||
signal color_change_request
|
||||
|
||||
func _enter_tree():
|
||||
for child in get_children():
|
||||
child.set("custom_styles/normal", StyleBoxFlat.new())
|
||||
child.get("custom_styles/normal").set("bg_color", Color(randf(), randf(), randf()))
|
||||
for child in get_children():
|
||||
if child.is_connected("pressed", self, "change_color_to"):
|
||||
return
|
||||
child.connect("pressed", self, "change_color_to", [child.get("custom_styles/normal").bg_color])
|
||||
|
||||
|
||||
func change_color_to(color):
|
||||
emit_signal("color_change_request", color)
|
||||
|
||||
|
||||
func add_color_prefab(color: Color):
|
||||
var dup = get_child(0).duplicate()
|
||||
add_child(dup)
|
||||
move_child(dup, 0)
|
||||
dup.set("custom_styles/normal", StyleBoxFlat.new())
|
||||
dup.get("custom_styles/normal").set("bg_color", color)
|
||||
for child in get_children():
|
||||
if child.is_connected("pressed", self, "change_color_to"):
|
||||
return
|
||||
child.connect("pressed", self, "change_color_to", [child.get("custom_styles/normal").bg_color])
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
extends RichTextLabel
|
||||
tool
|
||||
|
||||
func _ready():
|
||||
pass
|
||||
|
||||
|
||||
func display_text(text):
|
||||
self.text = text
|
@ -1,834 +0,0 @@
|
||||
tool
|
||||
extends Control
|
||||
|
||||
enum Tools {
|
||||
PAINT,
|
||||
BRUSH,
|
||||
BUCKET,
|
||||
RAINBOW,
|
||||
LINE,
|
||||
RECT,
|
||||
DARKEN,
|
||||
BRIGHTEN
|
||||
COLORPICKER,
|
||||
CUT,
|
||||
PASTECUT,
|
||||
}
|
||||
|
||||
# Keyboard shortcuts
|
||||
const K_UNDO = KEY_Z
|
||||
const K_REDO = KEY_Y
|
||||
const K_PENCIL = KEY_Q
|
||||
const K_BRUSH = KEY_W
|
||||
const K_BUCKET = KEY_F
|
||||
const K_RAINBOW = KEY_R
|
||||
const K_LINE = KEY_L
|
||||
const K_DARK = KEY_D
|
||||
const K_BRIGHT = KEY_B
|
||||
const K_CUT = KEY_C
|
||||
const K_PICK = KEY_P
|
||||
|
||||
|
||||
var layer_buttons: Control
|
||||
var paint_canvas_container_node
|
||||
var paint_canvas: GECanvas
|
||||
var canvas_background: TextureRect
|
||||
var grids_node
|
||||
var colors_grid
|
||||
var selected_color = Color(1, 1, 1, 1) setget set_selected_color
|
||||
var util = preload("res://addons/Godoxel/Util.gd")
|
||||
var textinfo
|
||||
var allow_drawing = true
|
||||
|
||||
var mouse_in_region = false
|
||||
var mouse_on_top = false
|
||||
|
||||
|
||||
var _middle_mouse_pressed_pos = null
|
||||
var _middle_mouse_pressed_start_pos = null
|
||||
var _left_mouse_pressed_start_pos = Vector2()
|
||||
var _previous_tool
|
||||
var brush_mode
|
||||
|
||||
var _layer_button_ref = {}
|
||||
|
||||
var _total_added_layers = 1
|
||||
|
||||
var selected_brush_prefab = 0
|
||||
var _last_drawn_pixel = Vector2.ZERO
|
||||
var _last_preview_draw_cell_pos = Vector2.ZERO
|
||||
|
||||
var _selection_cells = []
|
||||
var _selection_colors = []
|
||||
|
||||
var _cut_pos = Vector2.ZERO
|
||||
var _cut_size = Vector2.ZERO
|
||||
|
||||
var _actions_history = [] # for undo
|
||||
var _redo_history = []
|
||||
var _current_action
|
||||
|
||||
var _last_mouse_pos_canvas_area = Vector2.ZERO
|
||||
|
||||
var _picked_color = false
|
||||
|
||||
var mouse_position = Vector2()
|
||||
var canvas_position = Vector2()
|
||||
var canvas_mouse_position = Vector2()
|
||||
var cell_mouse_position = Vector2()
|
||||
var cell_color = Color()
|
||||
|
||||
var last_mouse_position = Vector2()
|
||||
var last_canvas_position = Vector2()
|
||||
var last_canvas_mouse_position = Vector2()
|
||||
var last_cell_mouse_position = Vector2()
|
||||
var last_cell_color = Color()
|
||||
|
||||
const current_layer_highlight = Color(0.354706, 0.497302, 0.769531)
|
||||
const other_layer_highlight = Color(0.180392, 0.176471, 0.176471)
|
||||
const locked_layer_highlight = Color(0.098039, 0.094118, 0.094118)
|
||||
|
||||
var big_grid_pixels = 4 # 1 grid-box is big_grid_pixels big
|
||||
|
||||
|
||||
|
||||
func _ready():
|
||||
#--------------------
|
||||
#Setup nodes
|
||||
#--------------------
|
||||
|
||||
paint_canvas_container_node = find_node("PaintCanvasContainer")
|
||||
textinfo = find_node("DebugTextDisplay")
|
||||
selected_color = find_node("ColorPicker").color
|
||||
colors_grid = find_node("Colors")
|
||||
paint_canvas = paint_canvas_container_node.find_node("Canvas")
|
||||
layer_buttons = find_node("LayerButtons")
|
||||
canvas_background = find_node("CanvasBackground")
|
||||
|
||||
set_process(true)
|
||||
|
||||
#--------------------
|
||||
#connect nodes
|
||||
#--------------------
|
||||
if not colors_grid.is_connected("color_change_request", self, "change_color"):
|
||||
colors_grid.connect("color_change_request", self, "change_color")
|
||||
|
||||
if not is_connected("visibility_changed", self, "_on_Editor_visibility_changed"):
|
||||
connect("visibility_changed", self, "_on_Editor_visibility_changed")
|
||||
|
||||
find_node("CanvasBackground").material.set_shader_param(
|
||||
"pixel_size", 8 * pow(0.5, big_grid_pixels)/paint_canvas.pixel_size)
|
||||
|
||||
# ready
|
||||
|
||||
set_brush(Tools.PAINT)
|
||||
_layer_button_ref[layer_buttons.get_child(0).name] = layer_buttons.get_child(0) #ugly
|
||||
_connect_layer_buttons()
|
||||
highlight_layer(paint_canvas.get_active_layer().name)
|
||||
|
||||
find_node("BrushSizeLabel").text = str(int(find_node("BrushSize").value))
|
||||
|
||||
paint_canvas.update()
|
||||
|
||||
|
||||
func _input(event):
|
||||
if is_any_menu_open():
|
||||
return
|
||||
if not is_visible_in_tree():
|
||||
return
|
||||
if paint_canvas_container_node == null or paint_canvas == null:
|
||||
return
|
||||
|
||||
if event is InputEventKey and event.is_pressed() and not event.is_echo():
|
||||
_handle_shortcuts(event.scancode)
|
||||
|
||||
if is_mouse_in_canvas() and paint_canvas.mouse_on_top:
|
||||
_handle_zoom(event)
|
||||
|
||||
if paint_canvas.is_active_layer_locked():
|
||||
return
|
||||
|
||||
if brush_mode == Tools.CUT:
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == BUTTON_LEFT:
|
||||
if not event.pressed:
|
||||
commit_action()
|
||||
|
||||
if (paint_canvas.mouse_in_region and paint_canvas.mouse_on_top):
|
||||
if event is InputEventMouseButton:
|
||||
match brush_mode:
|
||||
Tools.BUCKET:
|
||||
if event.button_index == BUTTON_LEFT:
|
||||
if event.pressed:
|
||||
if _current_action == null:
|
||||
_current_action = get_action()
|
||||
do_action([cell_mouse_position, last_cell_mouse_position, selected_color])
|
||||
|
||||
Tools.COLORPICKER:
|
||||
if event.button_index == BUTTON_LEFT:
|
||||
if event.pressed:
|
||||
if paint_canvas.get_pixel(cell_mouse_position.x, cell_mouse_position.y).a == 0:
|
||||
return
|
||||
selected_color = paint_canvas.get_pixel(cell_mouse_position.x, cell_mouse_position.y)
|
||||
_picked_color = true
|
||||
find_node("Colors").add_color_prefab(selected_color)
|
||||
elif _picked_color:
|
||||
set_brush(_previous_tool)
|
||||
elif event.button_index == BUTTON_RIGHT:
|
||||
if event.pressed:
|
||||
set_brush(_previous_tool)
|
||||
|
||||
Tools.PASTECUT:
|
||||
if event.button_index == BUTTON_RIGHT:
|
||||
if event.pressed:
|
||||
commit_action()
|
||||
set_brush(Tools.PAINT)
|
||||
|
||||
|
||||
func _process(delta):
|
||||
if not is_visible_in_tree():
|
||||
return
|
||||
if paint_canvas_container_node == null or paint_canvas == null:
|
||||
return
|
||||
if is_any_menu_open():
|
||||
return
|
||||
|
||||
if is_mouse_in_canvas():
|
||||
_handle_scroll()
|
||||
|
||||
#Update commonly used variables
|
||||
var grid_size = paint_canvas.pixel_size
|
||||
mouse_position = get_global_mouse_position() #paint_canvas.get_local_mouse_position()
|
||||
canvas_position = paint_canvas.rect_global_position
|
||||
canvas_mouse_position = Vector2(mouse_position.x - canvas_position.x, mouse_position.y - canvas_position.y)
|
||||
|
||||
if is_mouse_in_canvas() && paint_canvas.mouse_on_top:
|
||||
cell_mouse_position = Vector2(
|
||||
floor(canvas_mouse_position.x / grid_size),
|
||||
floor(canvas_mouse_position.y / grid_size))
|
||||
cell_color = paint_canvas.get_pixel(cell_mouse_position.x, cell_mouse_position.y)
|
||||
|
||||
update_text_info()
|
||||
|
||||
# if not is_mouse_in_canvas():
|
||||
# paint_canvas.tool_layer.clear()
|
||||
# paint_canvas.update()
|
||||
# paint_canvas.tool_layer.update_texture()
|
||||
# else:
|
||||
if is_mouse_in_canvas() && paint_canvas.mouse_on_top:
|
||||
if not paint_canvas.is_active_layer_locked():
|
||||
if is_position_in_canvas(get_global_mouse_position()) or \
|
||||
is_position_in_canvas(_last_mouse_pos_canvas_area):
|
||||
brush_process()
|
||||
else:
|
||||
print(cell_mouse_position, " not in ", paint_canvas_container_node.rect_size)
|
||||
print("not in canvas")
|
||||
|
||||
_draw_tool_brush()
|
||||
|
||||
#Update last variables with the current variables
|
||||
last_mouse_position = mouse_position
|
||||
last_canvas_position = canvas_position
|
||||
last_canvas_mouse_position = canvas_mouse_position
|
||||
last_cell_mouse_position = cell_mouse_position
|
||||
last_cell_color = cell_color
|
||||
_last_mouse_pos_canvas_area = get_global_mouse_position() #paint_canvas_container_node.get_local_mouse_position()
|
||||
|
||||
|
||||
func _handle_shortcuts(scancode):
|
||||
match scancode:
|
||||
K_UNDO:
|
||||
undo_action()
|
||||
|
||||
K_REDO:
|
||||
redo_action()
|
||||
|
||||
K_PENCIL:
|
||||
set_brush(Tools.PAINT)
|
||||
|
||||
K_BRUSH:
|
||||
set_brush(Tools.BRUSH)
|
||||
|
||||
K_BUCKET:
|
||||
set_brush(Tools.BUCKET)
|
||||
|
||||
K_RAINBOW:
|
||||
set_brush(Tools.RAINBOW)
|
||||
|
||||
K_LINE:
|
||||
set_brush(Tools.LINE)
|
||||
|
||||
K_DARK:
|
||||
set_brush(Tools.DARKEN)
|
||||
|
||||
K_BRIGHT:
|
||||
set_brush(Tools.BRIGHTEN)
|
||||
|
||||
K_CUT:
|
||||
set_brush(Tools.CUT)
|
||||
|
||||
K_PICK:
|
||||
set_brush(Tools.COLORPICKER)
|
||||
|
||||
|
||||
func _draw_tool_brush():
|
||||
paint_canvas.tool_layer.clear()
|
||||
|
||||
match brush_mode:
|
||||
Tools.PASTECUT:
|
||||
for idx in range(_selection_cells.size()):
|
||||
var pixel = _selection_cells[idx]
|
||||
# if pixel.x < 0 or pixel.y < 0:
|
||||
# print(pixel)
|
||||
var color = _selection_colors[idx]
|
||||
pixel -= _cut_pos + _cut_size / 2
|
||||
pixel += cell_mouse_position
|
||||
paint_canvas._set_pixel_v(paint_canvas.tool_layer, pixel, color)
|
||||
Tools.BRUSH:
|
||||
var pixels = BrushPrefabs.get_brush(selected_brush_prefab, find_node("BrushSize").value)
|
||||
for pixel in pixels:
|
||||
|
||||
paint_canvas._set_pixel(paint_canvas.tool_layer,
|
||||
cell_mouse_position.x + pixel.x, cell_mouse_position.y + pixel.y, selected_color)
|
||||
|
||||
Tools.RAINBOW:
|
||||
paint_canvas._set_pixel(paint_canvas.tool_layer,
|
||||
cell_mouse_position.x, cell_mouse_position.y, Color(0.46875, 0.446777, 0.446777, 0.196078))
|
||||
|
||||
Tools.COLORPICKER:
|
||||
paint_canvas._set_pixel(paint_canvas.tool_layer,
|
||||
cell_mouse_position.x, cell_mouse_position.y, Color(0.866667, 0.847059, 0.847059, 0.196078))
|
||||
_:
|
||||
paint_canvas._set_pixel(paint_canvas.tool_layer,
|
||||
cell_mouse_position.x, cell_mouse_position.y, selected_color)
|
||||
|
||||
paint_canvas.update()
|
||||
#TODO add here brush prefab drawing
|
||||
paint_canvas.tool_layer.update_texture()
|
||||
|
||||
|
||||
func _handle_scroll():
|
||||
if Input.is_mouse_button_pressed(BUTTON_MIDDLE):
|
||||
if _middle_mouse_pressed_start_pos == null:
|
||||
_middle_mouse_pressed_start_pos = paint_canvas.rect_position
|
||||
_middle_mouse_pressed_pos = get_global_mouse_position()
|
||||
|
||||
paint_canvas.rect_position = _middle_mouse_pressed_start_pos
|
||||
paint_canvas.rect_position += get_global_mouse_position() - _middle_mouse_pressed_pos
|
||||
|
||||
elif _middle_mouse_pressed_start_pos != null:
|
||||
_middle_mouse_pressed_start_pos = null
|
||||
|
||||
|
||||
const max_zoom_out = 1
|
||||
const max_zoom_in = 50
|
||||
|
||||
func _handle_zoom(event):
|
||||
if not event is InputEventMouseButton:
|
||||
return
|
||||
if event.is_pressed():
|
||||
if event.button_index == BUTTON_WHEEL_UP:
|
||||
var px = min(paint_canvas.pixel_size * 2, max_zoom_in)
|
||||
if px == paint_canvas.pixel_size:
|
||||
return
|
||||
paint_canvas.set_pixel_size(px)
|
||||
find_node("CanvasBackground").material.set_shader_param(
|
||||
"pixel_size", 8 * pow(0.5, big_grid_pixels)/paint_canvas.pixel_size)
|
||||
paint_canvas.rect_position -= paint_canvas.get_local_mouse_position()
|
||||
paint_canvas.rect_position.x = clamp(paint_canvas.rect_position.x, -paint_canvas.rect_size.x * 0.8, rect_size.x)
|
||||
paint_canvas.rect_position.y = clamp(paint_canvas.rect_position.y, -paint_canvas.rect_size.y * 0.8, rect_size.y)
|
||||
elif event.button_index == BUTTON_WHEEL_DOWN:
|
||||
var px = max(paint_canvas.pixel_size / 2.0, max_zoom_out)
|
||||
if px == paint_canvas.pixel_size:
|
||||
return
|
||||
paint_canvas.set_pixel_size(px)
|
||||
find_node("CanvasBackground").material.set_shader_param(
|
||||
# 4 2 1
|
||||
"pixel_size", 8 * pow(0.5, big_grid_pixels)/paint_canvas.pixel_size)
|
||||
paint_canvas.rect_position += paint_canvas.get_local_mouse_position() / 2
|
||||
paint_canvas.rect_position.x = clamp(paint_canvas.rect_position.x, -paint_canvas.rect_size.x * 0.8, rect_size.x)
|
||||
paint_canvas.rect_position.y = clamp(paint_canvas.rect_position.y, -paint_canvas.rect_size.y * 0.8, rect_size.y)
|
||||
|
||||
|
||||
func _handle_cut():
|
||||
if Input.is_mouse_button_pressed(BUTTON_RIGHT):
|
||||
paint_canvas.clear_preview_layer()
|
||||
set_brush(_previous_tool)
|
||||
return
|
||||
|
||||
if Input.is_mouse_button_pressed(BUTTON_LEFT):
|
||||
for pixel_pos in GEUtils.get_pixels_in_line(cell_mouse_position, last_cell_mouse_position):
|
||||
for idx in range(_selection_cells.size()):
|
||||
var pixel = _selection_cells[idx]
|
||||
var color = _selection_colors[idx]
|
||||
pixel -= _cut_pos + _cut_size / 2
|
||||
pixel += pixel_pos
|
||||
paint_canvas.set_pixel_v(pixel, color)
|
||||
else:
|
||||
if _last_preview_draw_cell_pos == cell_mouse_position:
|
||||
return
|
||||
paint_canvas.clear_preview_layer()
|
||||
for idx in range(_selection_cells.size()):
|
||||
var pixel = _selection_cells[idx]
|
||||
var color = _selection_colors[idx]
|
||||
pixel -= _cut_pos + _cut_size / 2
|
||||
pixel += cell_mouse_position
|
||||
paint_canvas.set_preview_pixel_v(pixel, color)
|
||||
_last_preview_draw_cell_pos = cell_mouse_position
|
||||
|
||||
|
||||
func brush_process():
|
||||
if Input.is_mouse_button_pressed(BUTTON_LEFT):
|
||||
if _current_action == null:
|
||||
_current_action = get_action()
|
||||
if brush_mode == Tools.COLORPICKER:
|
||||
_current_action = null
|
||||
|
||||
match brush_mode:
|
||||
Tools.PAINT:
|
||||
do_action([cell_mouse_position, last_cell_mouse_position, selected_color])
|
||||
Tools.BRUSH:
|
||||
do_action([cell_mouse_position, last_cell_mouse_position, selected_color,
|
||||
selected_brush_prefab, find_node("BrushSize").value])
|
||||
Tools.LINE:
|
||||
do_action([cell_mouse_position, last_cell_mouse_position, selected_color])
|
||||
Tools.RECT:
|
||||
do_action([cell_mouse_position, last_cell_mouse_position, selected_color])
|
||||
Tools.DARKEN:
|
||||
do_action([cell_mouse_position, last_cell_mouse_position, selected_color])
|
||||
Tools.BRIGHTEN:
|
||||
do_action([cell_mouse_position, last_cell_mouse_position, selected_color])
|
||||
Tools.COLORPICKER:
|
||||
pass
|
||||
Tools.CUT:
|
||||
do_action([cell_mouse_position, last_cell_mouse_position, selected_color])
|
||||
Tools.PASTECUT:
|
||||
do_action([cell_mouse_position, last_cell_mouse_position,
|
||||
_selection_cells, _selection_colors,
|
||||
_cut_pos, _cut_size])
|
||||
Tools.RAINBOW:
|
||||
do_action([cell_mouse_position, last_cell_mouse_position])
|
||||
paint_canvas.update()
|
||||
|
||||
elif Input.is_mouse_button_pressed(BUTTON_RIGHT):
|
||||
paint_canvas.update()
|
||||
if _current_action == null:
|
||||
_current_action = get_action()
|
||||
|
||||
match brush_mode:
|
||||
Tools.PAINT:
|
||||
do_action([cell_mouse_position, last_cell_mouse_position, Color.transparent])
|
||||
Tools.BRUSH:
|
||||
do_action([cell_mouse_position, last_cell_mouse_position, Color.transparent,
|
||||
selected_brush_prefab, find_node("BrushSize").value])
|
||||
else:
|
||||
if _current_action and _current_action.can_commit():
|
||||
commit_action()
|
||||
paint_canvas.update()
|
||||
|
||||
|
||||
func update_text_info():
|
||||
var text = ""
|
||||
|
||||
var cell_color_text = cell_color
|
||||
cell_color_text = Color(0, 0, 0, 0)
|
||||
|
||||
text += \
|
||||
str("FPS %s\t" + \
|
||||
"Mouse Position %s\t" + \
|
||||
"Canvas Mouse Position %s \t" + \
|
||||
"Canvas Position %s\t\n" + \
|
||||
"Cell Position %s \t" + \
|
||||
"Cell Color %s\t") % [
|
||||
str(Engine.get_frames_per_second()),
|
||||
str(mouse_position),
|
||||
str(canvas_mouse_position),
|
||||
str(canvas_position),
|
||||
str(cell_mouse_position),
|
||||
str(cell_color_text),
|
||||
]
|
||||
|
||||
find_node("DebugTextDisplay").display_text(text)
|
||||
|
||||
|
||||
func _on_Save_pressed():
|
||||
get_node("SaveFileDialog").show()
|
||||
|
||||
|
||||
|
||||
#---------------------------------------
|
||||
# Actions
|
||||
#---------------------------------------
|
||||
|
||||
|
||||
func do_action(data: Array):
|
||||
if _current_action == null:
|
||||
#print("clear redo")
|
||||
_redo_history.clear()
|
||||
_current_action.do_action(paint_canvas, data)
|
||||
|
||||
|
||||
func commit_action():
|
||||
if not _current_action:
|
||||
return
|
||||
|
||||
#print("commit action")
|
||||
var commit_data = _current_action.commit_action(paint_canvas)
|
||||
var action = get_action()
|
||||
action.action_data = _current_action.action_data.duplicate(true)
|
||||
_actions_history.push_back(action)
|
||||
_redo_history.clear()
|
||||
|
||||
match brush_mode:
|
||||
Tools.CUT:
|
||||
_cut_pos = _current_action.mouse_start_pos
|
||||
_cut_size = _current_action.mouse_end_pos - _current_action.mouse_start_pos
|
||||
_selection_cells = _current_action.action_data.redo.cells.duplicate()
|
||||
_selection_colors = _current_action.action_data.redo.colors.duplicate()
|
||||
set_brush(Tools.PASTECUT)
|
||||
_:
|
||||
_current_action = null
|
||||
|
||||
|
||||
func redo_action():
|
||||
if _redo_history.empty():
|
||||
print("nothing to redo")
|
||||
return
|
||||
var action = _redo_history.pop_back()
|
||||
if not action:
|
||||
return
|
||||
_actions_history.append(action)
|
||||
action.redo_action(paint_canvas)
|
||||
paint_canvas.update()
|
||||
#print("redo action")
|
||||
|
||||
|
||||
func undo_action():
|
||||
var action = _actions_history.pop_back()
|
||||
if not action:
|
||||
return
|
||||
_redo_history.append(action)
|
||||
action.undo_action(paint_canvas)
|
||||
update()
|
||||
paint_canvas.update()
|
||||
#print("undo action")
|
||||
|
||||
|
||||
func get_action():
|
||||
match brush_mode:
|
||||
Tools.PAINT:
|
||||
return GEPencil.new()
|
||||
Tools.BRUSH:
|
||||
return GEBrush.new()
|
||||
Tools.LINE:
|
||||
return GELine.new()
|
||||
Tools.RAINBOW:
|
||||
return GERainbow.new()
|
||||
Tools.BUCKET:
|
||||
return GEBucket.new()
|
||||
Tools.RECT:
|
||||
return GERect.new()
|
||||
Tools.DARKEN:
|
||||
return GEDarken.new()
|
||||
Tools.BRIGHTEN:
|
||||
return GEBrighten.new()
|
||||
Tools.CUT:
|
||||
return GECut.new()
|
||||
Tools.PASTECUT:
|
||||
return GEPasteCut.new()
|
||||
_:
|
||||
#print("no tool!")
|
||||
return null
|
||||
|
||||
|
||||
############################################
|
||||
# Brushes
|
||||
############################################
|
||||
|
||||
|
||||
func set_selected_color(color):
|
||||
selected_color = color
|
||||
|
||||
|
||||
func set_brush(new_mode):
|
||||
if brush_mode == new_mode:
|
||||
return
|
||||
_previous_tool = brush_mode
|
||||
brush_mode = new_mode
|
||||
|
||||
_current_action = get_action()
|
||||
|
||||
match _previous_tool:
|
||||
Tools.CUT:
|
||||
paint_canvas.clear_preview_layer()
|
||||
Tools.PASTECUT:
|
||||
_selection_cells.clear()
|
||||
_selection_colors.clear()
|
||||
Tools.BUCKET:
|
||||
_current_action = null
|
||||
#print("Selected: ", Tools.keys()[brush_mode])
|
||||
|
||||
|
||||
func change_color(new_color):
|
||||
if new_color.a == 0:
|
||||
return
|
||||
selected_color = new_color
|
||||
find_node("ColorPicker").color = selected_color
|
||||
|
||||
|
||||
func _on_ColorPicker_color_changed(color):
|
||||
selected_color = color
|
||||
|
||||
|
||||
func _on_PaintTool_pressed():
|
||||
set_brush(Tools.PAINT)
|
||||
|
||||
|
||||
func _on_BucketTool_pressed():
|
||||
set_brush(Tools.BUCKET)
|
||||
|
||||
|
||||
func _on_RainbowTool_pressed():
|
||||
set_brush(Tools.RAINBOW)
|
||||
|
||||
|
||||
func _on_BrushTool_pressed():
|
||||
set_brush(Tools.BRUSH)
|
||||
|
||||
|
||||
func _on_LineTool_pressed():
|
||||
set_brush(Tools.LINE)
|
||||
|
||||
|
||||
func _on_RectTool_pressed():
|
||||
set_brush(Tools.RECT)
|
||||
|
||||
|
||||
func _on_DarkenTool_pressed():
|
||||
set_brush(Tools.DARKEN)
|
||||
|
||||
|
||||
func _on_BrightenTool_pressed():
|
||||
set_brush(Tools.BRIGHTEN)
|
||||
|
||||
|
||||
func _on_ColorPickerTool_pressed():
|
||||
set_brush(Tools.COLORPICKER)
|
||||
|
||||
|
||||
func _on_CutTool_pressed():
|
||||
set_brush(Tools.CUT)
|
||||
|
||||
|
||||
func _on_Editor_visibility_changed():
|
||||
pause_mode = not visible
|
||||
|
||||
|
||||
|
||||
############################################
|
||||
# Layer
|
||||
############################################
|
||||
|
||||
func highlight_layer(layer_name: String):
|
||||
for button in layer_buttons.get_children():
|
||||
if paint_canvas.find_layer_by_name(button.name).locked:
|
||||
button.get("custom_styles/panel").set("bg_color", locked_layer_highlight)
|
||||
elif button.name == layer_name:
|
||||
button.get("custom_styles/panel").set("bg_color", current_layer_highlight)
|
||||
else:
|
||||
button.get("custom_styles/panel").set("bg_color", other_layer_highlight)
|
||||
|
||||
|
||||
func toggle_layer_visibility(button, layer_name: String):
|
||||
#print("toggling: ", layer_name)
|
||||
paint_canvas.toggle_layer_visibility(layer_name)
|
||||
|
||||
|
||||
func select_layer(layer_name: String):
|
||||
#print("select layer: ", layer_name)
|
||||
paint_canvas.select_layer(layer_name)
|
||||
highlight_layer(layer_name)
|
||||
|
||||
|
||||
func lock_layer(button, layer_name: String):
|
||||
paint_canvas.toggle_lock_layer(layer_name)
|
||||
highlight_layer(paint_canvas.get_active_layer().name)
|
||||
|
||||
|
||||
func add_new_layer():
|
||||
var new_layer_button = layer_buttons.get_child(0).duplicate()
|
||||
new_layer_button.set("custom_styles/panel", layer_buttons.get_child(0).get("custom_styles/panel").duplicate())
|
||||
layer_buttons.add_child_below_node(
|
||||
layer_buttons.get_child(layer_buttons.get_child_count() - 1), new_layer_button, true)
|
||||
_total_added_layers += 1
|
||||
new_layer_button.find_node("Select").text = "Layer " + str(_total_added_layers)
|
||||
_layer_button_ref[new_layer_button.name] = new_layer_button
|
||||
_connect_layer_buttons()
|
||||
|
||||
var layer: GELayer = paint_canvas.add_new_layer(new_layer_button.name)
|
||||
|
||||
highlight_layer(paint_canvas.get_active_layer().name)
|
||||
#print("added layer: ", layer.name)
|
||||
return layer
|
||||
|
||||
|
||||
func remove_active_layer():
|
||||
if layer_buttons.get_child_count() <= 1:
|
||||
return
|
||||
var layer_name = paint_canvas.active_layer.name
|
||||
paint_canvas.remove_layer(layer_name)
|
||||
layer_buttons.remove_child(_layer_button_ref[layer_name])
|
||||
_layer_button_ref[layer_name].queue_free()
|
||||
_layer_button_ref.erase(layer_name)
|
||||
|
||||
highlight_layer(paint_canvas.get_active_layer().name)
|
||||
|
||||
|
||||
func duplicate_active_layer():
|
||||
var new_layer_button = layer_buttons.get_child(0).duplicate()
|
||||
new_layer_button.set("custom_styles/panel", layer_buttons.get_child(0).get("custom_styles/panel").duplicate())
|
||||
layer_buttons.add_child_below_node(
|
||||
layer_buttons.get_child(layer_buttons.get_child_count() - 1), new_layer_button, true)
|
||||
|
||||
_total_added_layers += 1 # for keeping track...
|
||||
new_layer_button.find_node("Select").text = "Layer " + str(_total_added_layers)
|
||||
|
||||
var new_layer = paint_canvas.duplicate_layer(paint_canvas.active_layer.name, new_layer_button.name)
|
||||
new_layer.update_texture()
|
||||
_layer_button_ref[new_layer.name] = new_layer_button
|
||||
|
||||
new_layer_button.find_node("Select").connect("pressed", self, "select_layer", [new_layer_button.name])
|
||||
new_layer_button.find_node("Visible").connect("pressed", self, "toggle_layer_visibility",
|
||||
[new_layer_button.find_node("Visible"), new_layer_button.name])
|
||||
new_layer_button.find_node("Up").connect("pressed", self, "move_down", [new_layer_button])
|
||||
new_layer_button.find_node("Down").connect("pressed", self, "move_up", [new_layer_button])
|
||||
new_layer_button.find_node("Lock").connect("pressed", self, "lock_layer", [new_layer_button, new_layer_button.name])
|
||||
|
||||
# update highlight
|
||||
highlight_layer(paint_canvas.get_active_layer().name)
|
||||
#print("added layer: ", new_layer.name, " (total:", layer_buttons.get_child_count(), ")")
|
||||
|
||||
|
||||
func move_up(layer_btn):
|
||||
var new_idx = min(layer_btn.get_index() + 1, layer_buttons.get_child_count())
|
||||
#print("move_up: ", layer_btn.name, " from ", layer_btn.get_index(), " to ", new_idx)
|
||||
layer_buttons.move_child(layer_btn, new_idx)
|
||||
paint_canvas.move_layer_back(layer_btn.name)
|
||||
|
||||
|
||||
func move_down(layer_btn):
|
||||
var new_idx = max(layer_btn.get_index() - 1, 0)
|
||||
#print("move_down: ", layer_btn.name, " from ", layer_btn.get_index(), " to ", new_idx)
|
||||
layer_buttons.move_child(layer_btn, new_idx)
|
||||
paint_canvas.move_layer_forward(layer_btn.name)
|
||||
|
||||
|
||||
func _connect_layer_buttons():
|
||||
for layer_btn in layer_buttons.get_children():
|
||||
if layer_btn.find_node("Select").is_connected("pressed", self, "select_layer"):
|
||||
continue
|
||||
layer_btn.find_node("Select").connect("pressed", self, "select_layer", [layer_btn.name])
|
||||
layer_btn.find_node("Visible").connect("pressed", self, "toggle_layer_visibility",
|
||||
[layer_btn.find_node("Visible"), layer_btn.name])
|
||||
layer_btn.find_node("Up").connect("pressed", self, "move_down", [layer_btn])
|
||||
layer_btn.find_node("Down").connect("pressed", self, "move_up", [layer_btn])
|
||||
layer_btn.find_node("Lock").connect("pressed", self, "lock_layer",
|
||||
[layer_btn, layer_btn.name])
|
||||
|
||||
|
||||
func _on_Button_pressed():
|
||||
add_new_layer()
|
||||
|
||||
|
||||
func _on_PaintCanvasContainer_mouse_entered():
|
||||
if mouse_on_top == true:
|
||||
return
|
||||
mouse_on_top = true
|
||||
paint_canvas.tool_layer.clear()
|
||||
paint_canvas.update()
|
||||
paint_canvas.tool_layer.update_texture()
|
||||
|
||||
|
||||
func _on_PaintCanvasContainer_mouse_exited():
|
||||
if mouse_on_top == false:
|
||||
return
|
||||
mouse_on_top = false
|
||||
paint_canvas.tool_layer.clear()
|
||||
paint_canvas.update()
|
||||
paint_canvas.tool_layer.update_texture()
|
||||
|
||||
|
||||
func _on_ColorPicker_popup_closed():
|
||||
find_node("Colors").add_color_prefab(find_node("ColorPicker").color)
|
||||
|
||||
|
||||
############################################
|
||||
# MISC
|
||||
############################################
|
||||
|
||||
func is_position_in_canvas(pos):
|
||||
if Rect2(paint_canvas_container_node.rect_global_position,
|
||||
paint_canvas_container_node.rect_global_position + paint_canvas_container_node.rect_size).has_point(pos):
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func is_mouse_in_canvas() -> bool:
|
||||
if is_position_in_canvas(get_global_mouse_position()):
|
||||
return true #mouse_on_top # check if mouse is inside canvas
|
||||
else:
|
||||
return false
|
||||
|
||||
|
||||
func is_any_menu_open() -> bool:
|
||||
return $ChangeCanvasSize.visible or \
|
||||
$ChangeGridSizeDialog.visible or \
|
||||
$Settings.visible or \
|
||||
$LoadFileDialog.visible or \
|
||||
$SaveFileDialog.visible or \
|
||||
find_node("Navbar").is_any_menu_open()
|
||||
|
||||
|
||||
|
||||
func _on_LockAlpha_pressed():
|
||||
var checked = find_node("LockAlpha").pressed
|
||||
paint_canvas.active_layer.toggle_alpha_locked()
|
||||
for i in range(find_node("Layer").get_popup().get_item_count()):
|
||||
if find_node("Layer").get_popup().get_item_text(i) == "Toggle Alpha Locked":
|
||||
find_node("Layer").get_popup().set_item_checked(i, not find_node("Layer").get_popup().is_item_checked(i))
|
||||
|
||||
|
||||
func _on_BrushRect_pressed():
|
||||
if brush_mode != Tools.BRUSH:
|
||||
set_brush(Tools.BRUSH)
|
||||
selected_brush_prefab = BrushPrefabs.Type.RECT
|
||||
|
||||
|
||||
func _on_BrushCircle_pressed():
|
||||
if brush_mode != Tools.BRUSH:
|
||||
set_brush(Tools.BRUSH)
|
||||
selected_brush_prefab = BrushPrefabs.Type.CIRCLE
|
||||
|
||||
|
||||
func _on_BrushVLine_pressed():
|
||||
if brush_mode != Tools.BRUSH:
|
||||
set_brush(Tools.BRUSH)
|
||||
selected_brush_prefab = BrushPrefabs.Type.V_LINE
|
||||
|
||||
|
||||
func _on_BrushHLine_pressed():
|
||||
if brush_mode != Tools.BRUSH:
|
||||
set_brush(Tools.BRUSH)
|
||||
selected_brush_prefab = BrushPrefabs.Type.H_LINE
|
||||
|
||||
|
||||
func _on_BrushSize_value_changed(value: float):
|
||||
find_node("BrushSizeLabel").text = str(int(value))
|
||||
|
||||
|
||||
func _on_XSymmetry_pressed():
|
||||
paint_canvas.symmetry_x = not paint_canvas.symmetry_x
|
||||
|
||||
|
||||
func _on_YSymmetry_pressed():
|
||||
paint_canvas.symmetry_y = not paint_canvas.symmetry_y
|
File diff suppressed because one or more lines are too long
@ -1,98 +0,0 @@
|
||||
extends Reference
|
||||
class_name GELayer
|
||||
|
||||
|
||||
var name
|
||||
var layer_width
|
||||
var layer_height
|
||||
var visible = true setget set_visible
|
||||
var locked = false
|
||||
var alpha_locked = false
|
||||
|
||||
var texture: ImageTexture
|
||||
var image: Image
|
||||
var texture_rect_ref
|
||||
|
||||
|
||||
func _init():
|
||||
texture = ImageTexture.new()
|
||||
|
||||
|
||||
func create(texture_rect_ref, width: int, height: int):
|
||||
self.texture_rect_ref = texture_rect_ref
|
||||
|
||||
layer_width = width
|
||||
layer_height = height
|
||||
|
||||
image = Image.new()
|
||||
image.create(width, height, false, Image.FORMAT_RGBA8)
|
||||
image.fill(Color.transparent)
|
||||
update_texture()
|
||||
|
||||
|
||||
func resize(width: int, height: int):
|
||||
var pixel_colors = []
|
||||
var prev_width = layer_width
|
||||
var prev_height = layer_height
|
||||
|
||||
image.lock()
|
||||
for y in range(prev_height):
|
||||
for x in range(prev_width):
|
||||
pixel_colors.append(image.get_pixel(x, y))
|
||||
image.unlock()
|
||||
|
||||
layer_width = width
|
||||
layer_height = height
|
||||
|
||||
image.create(width, height, false, Image.FORMAT_RGBA8)
|
||||
|
||||
image.lock()
|
||||
for x in range(prev_width):
|
||||
for y in range(prev_height):
|
||||
if x >= width or y >= height:
|
||||
continue
|
||||
image.set_pixel(x, y, pixel_colors[GEUtils.to_1D(x, y, prev_width)])
|
||||
image.unlock()
|
||||
|
||||
update_texture()
|
||||
|
||||
|
||||
func set_pixel(x, y, color):
|
||||
image.lock()
|
||||
image.set_pixel(x, y, color)
|
||||
image.unlock()
|
||||
|
||||
|
||||
func get_pixel(x: int, y: int):
|
||||
if x < 0 or y < 0 or x >= image.get_width() or y >= image.get_height():
|
||||
return null
|
||||
image.lock()
|
||||
var pixel = image.get_pixel(x, y)
|
||||
image.unlock()
|
||||
return pixel
|
||||
|
||||
|
||||
func clear():
|
||||
image.fill(Color.transparent)
|
||||
update_texture()
|
||||
|
||||
|
||||
func update_texture():
|
||||
texture.create_from_image(image, 0)
|
||||
texture_rect_ref.texture = texture
|
||||
texture_rect_ref.margin_right = 0
|
||||
texture_rect_ref.margin_bottom = 0
|
||||
|
||||
|
||||
func set_visible(vis: bool):
|
||||
visible = vis
|
||||
texture_rect_ref.visible = visible
|
||||
|
||||
|
||||
func toggle_lock():
|
||||
locked = not locked
|
||||
|
||||
|
||||
func toggle_alpha_locked():
|
||||
alpha_locked = not alpha_locked
|
||||
|
@ -1,13 +0,0 @@
|
||||
tool
|
||||
extends MenuButton
|
||||
|
||||
var popup = get_popup()
|
||||
signal item_pressed
|
||||
|
||||
func _ready():
|
||||
popup.connect("id_pressed", self, "id_pressed")
|
||||
|
||||
func id_pressed(id):
|
||||
emit_signal("item_pressed", name, popup.get_item_text(id), id)
|
||||
|
||||
|
@ -1,106 +0,0 @@
|
||||
tool
|
||||
extends Control
|
||||
|
||||
var editor
|
||||
var paint_canvas
|
||||
|
||||
func _ready():
|
||||
editor = owner
|
||||
paint_canvas = editor.find_node("PaintCanvas")
|
||||
|
||||
for i in get_node("Buttons").get_children():
|
||||
i.connect("item_pressed", self, "button_pressed")
|
||||
|
||||
|
||||
func button_pressed(button_name, button_item, id):
|
||||
# print("pressed: ", button_name)
|
||||
# print("pressed item is: '%s'" % button_item)
|
||||
|
||||
match button_name:
|
||||
"File":
|
||||
handle_file_menu(button_item, id)
|
||||
"Edit":
|
||||
handle_edit_menu(button_item, id)
|
||||
"Canvas":
|
||||
handle_canvas_menu(button_item, id)
|
||||
"Layer":
|
||||
handle_layer_menu(button_item, id)
|
||||
"Grid":
|
||||
handle_grid_menu(button_item, id)
|
||||
"Magic":
|
||||
handle_magic_menu(button_item, id)
|
||||
"Editor":
|
||||
handle_editor_menu(button_item, id)
|
||||
|
||||
|
||||
func handle_file_menu(pressed_item: String, id):
|
||||
match pressed_item:
|
||||
"Save":
|
||||
owner.get_node("SaveFileDialog").show()
|
||||
"Load":
|
||||
owner.get_node("LoadFileDialog").show()
|
||||
"New":
|
||||
owner.get_node("ConfirmationDialog").show()
|
||||
|
||||
|
||||
func handle_edit_menu(pressed_item: String, id):
|
||||
match pressed_item:
|
||||
"Add Layer":
|
||||
editor.add_new_layer()
|
||||
|
||||
|
||||
func handle_canvas_menu(pressed_item: String, id):
|
||||
match pressed_item:
|
||||
"Change Size":
|
||||
owner.get_node("ChangeCanvasSize").show()
|
||||
"Crop To Content":
|
||||
owner.paint_canvas.crop_to_content()
|
||||
|
||||
|
||||
func handle_layer_menu(pressed_item: String, id):
|
||||
match pressed_item:
|
||||
"Add Layer":
|
||||
editor.add_new_layer()
|
||||
"Delete Layer":
|
||||
editor.remove_active_layer()
|
||||
"Duplicate Layer":
|
||||
editor.duplicate_active_layer()
|
||||
"Clear Layer":
|
||||
owner.paint_canvas.clear_active_layer()
|
||||
"Toggle Alpha Locked":
|
||||
owner.paint_canvas.active_layer.toggle_alpha_locked()
|
||||
$Buttons/Layer.get_popup().set_item_checked(id, not $Buttons/Layer.get_popup().is_item_checked(id))
|
||||
owner.find_node("LockAlpha").pressed = $Buttons/Layer.get_popup().is_item_checked(id)
|
||||
|
||||
|
||||
func handle_grid_menu(pressed_item: String, id):
|
||||
match pressed_item:
|
||||
"Change Grid Size":
|
||||
owner.get_node("ChangeGridSizeDialog").show()
|
||||
"Toggle Grid":
|
||||
owner.paint_canvas.toggle_grid()
|
||||
|
||||
|
||||
func handle_magic_menu(pressed_item: String, id):
|
||||
match pressed_item:
|
||||
"Add Layer":
|
||||
editor.add_new_layer()
|
||||
|
||||
|
||||
func handle_editor_menu(pressed_item: String, id):
|
||||
match pressed_item:
|
||||
"Settings":
|
||||
owner.get_node("Settings").show()
|
||||
"Toggle Grid":
|
||||
var grids_node = owner.find_node("Grids")
|
||||
grids_node.visible = !grids_node.visible
|
||||
"Reset Canvas Position":
|
||||
owner.paint_canvas_node.rect_position = Vector2(0, 0)
|
||||
|
||||
|
||||
func is_any_menu_open() -> bool:
|
||||
for child in $Buttons.get_children():
|
||||
if child.get_popup().visible:
|
||||
return true
|
||||
return false
|
||||
|
@ -1,2 +0,0 @@
|
||||
tool
|
||||
extends Control
|
@ -1,72 +0,0 @@
|
||||
tool
|
||||
extends FileDialog
|
||||
|
||||
#var canvas
|
||||
|
||||
var file_path = ""
|
||||
|
||||
|
||||
#func _enter_tree():
|
||||
#canvas = get_parent().find_node("Canvas")
|
||||
#canvas = get_parent().paint_canvas
|
||||
|
||||
|
||||
func _ready():
|
||||
# warning-ignore:return_value_discarded
|
||||
get_line_edit().connect("text_entered", self, "_on_LineEdit_text_entered")
|
||||
invalidate()
|
||||
clear_filters()
|
||||
add_filter("*.png ; PNG Images")
|
||||
|
||||
|
||||
func _on_SaveFileDialog_file_selected(path):
|
||||
#print("selected file: ", path)
|
||||
file_path = path
|
||||
save_file()
|
||||
|
||||
|
||||
# warning-ignore:unused_argument
|
||||
func _on_LineEdit_text_entered(text):
|
||||
return
|
||||
# print("text entered: ", text)
|
||||
|
||||
|
||||
func _on_SaveFileDialog_confirmed():
|
||||
return
|
||||
# print("confirmed: ", current_path)
|
||||
|
||||
|
||||
func save_file():
|
||||
var image = Image.new()
|
||||
var canvas = get_parent().paint_canvas
|
||||
image.create(canvas.canvas_width, canvas.canvas_height, true, Image.FORMAT_RGBA8)
|
||||
image.lock()
|
||||
|
||||
for layer in canvas.layers:
|
||||
var idx = 0
|
||||
if not layer.visible:
|
||||
continue
|
||||
for x in range(layer.layer_width):
|
||||
for y in range(layer.layer_height):
|
||||
var color = layer.get_pixel(x, y)
|
||||
var image_color = image.get_pixel(x, y)
|
||||
|
||||
if color.a != 0:
|
||||
image.set_pixel(x, y, image_color.blend(color))
|
||||
else:
|
||||
image.set_pixel(x, y, color)
|
||||
image.unlock()
|
||||
|
||||
var dir = Directory.new()
|
||||
if dir.file_exists(file_path):
|
||||
dir.remove(file_path)
|
||||
|
||||
image.save_png(file_path)
|
||||
|
||||
|
||||
func _on_SaveFileDialog_about_to_show():
|
||||
invalidate()
|
||||
|
||||
|
||||
func _on_SaveFileDialog_visibility_changed():
|
||||
invalidate()
|
@ -1,24 +0,0 @@
|
||||
tool
|
||||
extends Control
|
||||
|
||||
export var outline_size = 3
|
||||
|
||||
func _ready():
|
||||
pass
|
||||
|
||||
func _process(delta):
|
||||
update()
|
||||
|
||||
func _draw():
|
||||
if not rect_size == Vector2():
|
||||
draw_outline_box(rect_size, Color.gray, outline_size)
|
||||
|
||||
func draw_outline_box(size, color, width):
|
||||
#Top line
|
||||
draw_line(Vector2(0 + 1, 0), Vector2(size.x, 0), color, width)
|
||||
#Left line
|
||||
draw_line(Vector2(0 + 1, 0), Vector2(0, size.y), color, width)
|
||||
#Bottom line
|
||||
draw_line(Vector2(0 + 1, size.y), Vector2(size.x, size.y), color, width)
|
||||
#Right line
|
||||
draw_line(Vector2(size.x, 0), Vector2(size.x, size.y), color, width)
|
@ -1,24 +0,0 @@
|
||||
tool
|
||||
extends Control
|
||||
|
||||
var editor
|
||||
var canvas_outline
|
||||
var start_time
|
||||
var end_time
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
canvas_outline = get_parent().find_node("CanvasOutline")
|
||||
editor = get_parent()
|
||||
|
||||
|
||||
func _on_ColorPickerButton_color_changed(color):
|
||||
canvas_outline.color = color
|
||||
|
||||
|
||||
func _on_CheckButton_toggled(button_pressed):
|
||||
canvas_outline.visible = button_pressed
|
||||
|
||||
|
||||
func _on_Ok_pressed():
|
||||
hide()
|
@ -1,64 +0,0 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://addons/Godoxel/Settings.gd" type="Script" id=1]
|
||||
|
||||
|
||||
[node name="Settings" type="WindowDialog"]
|
||||
visible = true
|
||||
margin_top = 20.0
|
||||
margin_right = 300.0
|
||||
margin_bottom = 120.0
|
||||
window_title = "Settings"
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Ok" type="Button" parent="."]
|
||||
margin_left = 210.0
|
||||
margin_top = 70.0
|
||||
margin_right = 290.0
|
||||
margin_bottom = 90.0
|
||||
text = "Ok"
|
||||
|
||||
[node name="CanvasOutlineToggle" type="Control" parent="."]
|
||||
margin_left = 10.0
|
||||
margin_top = 10.0
|
||||
margin_right = 290.0
|
||||
margin_bottom = 30.0
|
||||
__meta__ = {
|
||||
"_edit_group_": true
|
||||
}
|
||||
|
||||
[node name="Label" type="Label" parent="CanvasOutlineToggle"]
|
||||
margin_right = 130.0
|
||||
margin_bottom = 20.0
|
||||
text = "Canvas Outline:"
|
||||
valign = 1
|
||||
|
||||
[node name="CheckButton" type="CheckButton" parent="CanvasOutlineToggle"]
|
||||
margin_left = 210.0
|
||||
margin_top = -10.0
|
||||
margin_right = 286.0
|
||||
margin_bottom = 30.0
|
||||
pressed = true
|
||||
|
||||
[node name="CanvasOutlineColor" type="Control" parent="."]
|
||||
margin_left = 10.0
|
||||
margin_top = 40.0
|
||||
margin_right = 290.0
|
||||
margin_bottom = 60.0
|
||||
__meta__ = {
|
||||
"_edit_group_": true
|
||||
}
|
||||
|
||||
[node name="Label" type="Label" parent="CanvasOutlineColor"]
|
||||
margin_right = 130.0
|
||||
margin_bottom = 20.0
|
||||
text = "Canvas Outline Color:"
|
||||
valign = 1
|
||||
|
||||
[node name="ColorPickerButton" type="ColorPickerButton" parent="CanvasOutlineColor"]
|
||||
margin_left = 170.0
|
||||
margin_right = 280.0
|
||||
margin_bottom = 20.0
|
||||
[connection signal="pressed" from="Ok" to="." method="_on_Ok_pressed"]
|
||||
[connection signal="toggled" from="CanvasOutlineToggle/CheckButton" to="." method="_on_CheckButton_toggled"]
|
||||
[connection signal="color_changed" from="CanvasOutlineColor/ColorPickerButton" to="." method="_on_ColorPickerButton_color_changed"]
|
@ -1,39 +0,0 @@
|
||||
tool
|
||||
extends Control
|
||||
|
||||
var size = 240
|
||||
|
||||
#TODO: To make reading the text easier, the text info with the longest text should have it's length applied to all the
|
||||
#the other text infos
|
||||
|
||||
func add_text_info(text_name, custom_node = null):
|
||||
var last_text_info_child = null
|
||||
var child_count = get_child_count()
|
||||
if not child_count <= 0:
|
||||
last_text_info_child = get_children()[get_children().size() - 1]
|
||||
var label = Label.new()
|
||||
label.name = text_name
|
||||
label.rect_size = Vector2(size, 14)
|
||||
if not last_text_info_child == null:
|
||||
var x = last_text_info_child.rect_position.x
|
||||
var y = last_text_info_child.rect_position.y
|
||||
var temp_size = size
|
||||
if child_count == 4:
|
||||
x = 0
|
||||
y = 20
|
||||
temp_size = 0
|
||||
label.rect_position = Vector2(x + temp_size, y)
|
||||
if not custom_node == null:
|
||||
label.add_child(custom_node)
|
||||
add_child(label)
|
||||
|
||||
func update_text_info(text_name, text_value = null, node = null, node_target_value = null, node_value = null):
|
||||
var text_label = self.get_node(text_name)
|
||||
if text_label == null:
|
||||
return
|
||||
if not node == null:
|
||||
get_node(text_name).get_node(node).set(node_target_value, node_value)
|
||||
if text_value == null:
|
||||
text_label.text = "%s: %s" % [text_name, null]
|
||||
else:
|
||||
text_label.text = "%s: %s" % [text_name, String(text_value)]
|
@ -1,94 +0,0 @@
|
||||
tool
|
||||
extends Node
|
||||
class_name GEUtils
|
||||
|
||||
|
||||
static func get_pixels_in_line(from: Vector2, to: Vector2):
|
||||
var dx = to[0] - from[0]
|
||||
var dy = to[1] - from[1]
|
||||
var nx = abs(dx)
|
||||
var ny = abs(dy)
|
||||
var signX = sign(dx)
|
||||
var signY = sign(dy)
|
||||
var p = from
|
||||
var points : Array = [p]
|
||||
|
||||
var ix = 0
|
||||
var iy = 0
|
||||
|
||||
while ix < nx || iy < ny:
|
||||
if (1 + (ix << 1)) * ny < (1 + (iy << 1)) * nx:
|
||||
p[0] += signX
|
||||
ix +=1
|
||||
else:
|
||||
p[1] += signY
|
||||
iy += 1
|
||||
points.append(p)
|
||||
return points
|
||||
|
||||
|
||||
static func to_1D_v(p, w) -> int:
|
||||
return p.x + p.y * w
|
||||
|
||||
|
||||
static func to_1D(x, y, w) -> int:
|
||||
return x + y * w
|
||||
|
||||
|
||||
static func to_2D(idx, w) -> Vector2:
|
||||
var p = Vector2()
|
||||
p.x = int(idx) % int(w)
|
||||
p.y = int(idx / w)
|
||||
return p
|
||||
|
||||
|
||||
|
||||
static func color_from_array(color_array):
|
||||
var r = color_array[0]
|
||||
var g = color_array[1]
|
||||
var b = color_array[2]
|
||||
var a = color_array[3]
|
||||
return Color(r, g, b, a)
|
||||
|
||||
static func random_color():
|
||||
return Color(randf(), randf(), randf())
|
||||
|
||||
static func random_color_alt():
|
||||
var rand = randi() % 6
|
||||
|
||||
match rand:
|
||||
#red
|
||||
0:
|
||||
return Color.red
|
||||
#blue
|
||||
1:
|
||||
return Color.blue
|
||||
#green
|
||||
2:
|
||||
return Color.green
|
||||
#orange
|
||||
3:
|
||||
return Color.orange
|
||||
#yellow
|
||||
4:
|
||||
return Color.yellow
|
||||
#purple
|
||||
5:
|
||||
return Color.purple
|
||||
|
||||
static func get_line_string(file, number):
|
||||
return file.get_as_text().split("\n")[number - 1].strip_edges()
|
||||
|
||||
static func printv(variable):
|
||||
var stack = get_stack()[get_stack().size() - 1]
|
||||
var line = stack.line
|
||||
var source = stack.source
|
||||
var file = File.new()
|
||||
file.open(source, File.READ)
|
||||
var line_string = get_line_string(file, line)
|
||||
file.close()
|
||||
var left_p = line_string.find("(")
|
||||
var left_p_string = line_string.right(left_p + 1)
|
||||
var right_p = left_p_string.find(")")
|
||||
var variable_name = left_p_string.left(right_p)
|
||||
print("%s: %s" % [variable_name, variable])
|
@ -1,6 +0,0 @@
|
||||
extends ViewportContainer
|
||||
tool
|
||||
|
||||
func _ready():
|
||||
get_child(0).size = rect_size
|
||||
|
@ -1,53 +0,0 @@
|
||||
extends GEAction
|
||||
class_name GEBrighten
|
||||
|
||||
|
||||
const brighten_color = 0.1
|
||||
|
||||
|
||||
func do_action(canvas, data: Array):
|
||||
.do_action(canvas, data)
|
||||
|
||||
var pixels = GEUtils.get_pixels_in_line(data[0], data[1])
|
||||
for pixel in pixels:
|
||||
if canvas.get_pixel_v(pixel) == null:
|
||||
continue
|
||||
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
continue
|
||||
|
||||
if pixel in action_data.undo.cells:
|
||||
var brightened_color = canvas.get_pixel_v(pixel).lightened(0.1)
|
||||
canvas.set_pixel_v(pixel, brightened_color)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(brightened_color)
|
||||
continue
|
||||
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
var brightened_color = canvas.get_pixel_v(pixel).lightened(0.1)
|
||||
canvas.set_pixel_v(pixel, brightened_color)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(brightened_color)
|
||||
|
||||
|
||||
func commit_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
return []
|
||||
|
||||
|
||||
func undo_action(canvas):
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
func redo_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
@ -1,47 +0,0 @@
|
||||
extends GEAction
|
||||
class_name GEBrush
|
||||
|
||||
|
||||
func do_action(canvas: GECanvas, data: Array):
|
||||
.do_action(canvas, data)
|
||||
|
||||
for pixel in GEUtils.get_pixels_in_line(data[0], data[1]):
|
||||
for off in BrushPrefabs.get_brush(data[3], data[4]):
|
||||
var p = pixel + off
|
||||
|
||||
if p in action_data.undo.cells or canvas.get_pixel_v(p) == null:
|
||||
continue
|
||||
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(p) == Color.transparent:
|
||||
continue
|
||||
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(p))
|
||||
action_data.undo.cells.append(p)
|
||||
|
||||
canvas.set_pixel_v(p, data[2])
|
||||
|
||||
action_data.redo.cells.append(p)
|
||||
action_data.redo.colors.append(data[2])
|
||||
|
||||
|
||||
func commit_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
return []
|
||||
|
||||
|
||||
func undo_action(canvas):
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
func redo_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
extends GEAction
|
||||
class_name GEBucket
|
||||
|
||||
|
||||
|
||||
func do_action(canvas, data: Array):
|
||||
.do_action(canvas, data)
|
||||
|
||||
if canvas.get_pixel_v(data[0]) == data[2]:
|
||||
return
|
||||
var pixels = canvas.select_same_color(data[0].x, data[0].y)
|
||||
|
||||
for pixel in pixels:
|
||||
if pixel in action_data.undo.cells:
|
||||
continue
|
||||
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
continue
|
||||
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
|
||||
canvas.set_pixel_v(pixel, data[2])
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(data[2])
|
||||
|
||||
|
||||
func commit_action(canvas):
|
||||
var cells = action_data.preview.cells
|
||||
var colors = action_data.preview.colors
|
||||
return []
|
||||
|
||||
|
||||
func undo_action(canvas):
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
func redo_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
|
@ -1,55 +0,0 @@
|
||||
extends GEAction
|
||||
class_name GEDarken
|
||||
|
||||
const dark_factor = 0.1
|
||||
|
||||
|
||||
func do_action(canvas, data: Array):
|
||||
.do_action(canvas, data)
|
||||
|
||||
var pixels = GEUtils.get_pixels_in_line(data[0], data[1])
|
||||
for pixel in pixels:
|
||||
if canvas.get_pixel_v(pixel) == null:
|
||||
continue
|
||||
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
continue
|
||||
|
||||
if pixel in action_data.undo.cells:
|
||||
var darkened_color = canvas.get_pixel_v(pixel).darkened(dark_factor)
|
||||
canvas.set_pixel_v(pixel, darkened_color)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(darkened_color)
|
||||
continue
|
||||
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
var darkened_color = canvas.get_pixel_v(pixel).darkened(dark_factor)
|
||||
canvas.set_pixel_v(pixel, darkened_color)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(darkened_color)
|
||||
|
||||
|
||||
func commit_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
return []
|
||||
|
||||
|
||||
func undo_action(canvas):
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
func redo_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
|
@ -1,59 +0,0 @@
|
||||
extends GEAction
|
||||
class_name GELine
|
||||
|
||||
|
||||
var mouse_start_pos = null
|
||||
|
||||
func do_action(canvas, data: Array):
|
||||
.do_action(canvas, data)
|
||||
|
||||
if mouse_start_pos == null:
|
||||
mouse_start_pos = data[0]
|
||||
|
||||
action_data.preview.cells.clear()
|
||||
action_data.preview.colors.clear()
|
||||
canvas.clear_preview_layer()
|
||||
|
||||
var pixels = GEUtils.get_pixels_in_line(data[0], mouse_start_pos)
|
||||
for pixel in pixels:
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
continue
|
||||
|
||||
canvas.set_preview_pixel_v(pixel, data[2])
|
||||
action_data.preview.cells.append(pixel)
|
||||
action_data.preview.colors.append(data[2])
|
||||
|
||||
|
||||
func commit_action(canvas):
|
||||
canvas.clear_preview_layer()
|
||||
var cells = action_data.preview.cells
|
||||
var colors = action_data.preview.colors
|
||||
for idx in range(cells.size()):
|
||||
if canvas.get_pixel_v(cells[idx]) == null:
|
||||
continue
|
||||
action_data.undo.cells.append(cells[idx])
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(cells[idx]))
|
||||
|
||||
canvas.set_pixel_v(cells[idx], colors[idx])
|
||||
|
||||
action_data.redo.cells.append(cells[idx])
|
||||
action_data.redo.colors.append(colors[idx])
|
||||
mouse_start_pos = null
|
||||
return []
|
||||
|
||||
|
||||
func undo_action(canvas):
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
func redo_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
|
@ -1,44 +0,0 @@
|
||||
extends GEAction
|
||||
class_name GEMultiLine
|
||||
|
||||
|
||||
func can_commit() -> bool:
|
||||
return false
|
||||
|
||||
|
||||
func update_action(canvas, data: Array):
|
||||
.update_action(canvas, data)
|
||||
|
||||
var pixels = GEUtils.get_pixels_in_line(data[0], data[1])
|
||||
for pixel in pixels:
|
||||
if pixel in action_data.undo.cells or canvas.get_pixel_v(pixel) == null or canvas.is_alpha_locked():
|
||||
continue
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
canvas.set_pixel_v(pixel, data[2])
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(data[2])
|
||||
|
||||
|
||||
func commit_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
return []
|
||||
|
||||
|
||||
func undo_action(canvas):
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
func redo_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
|
@ -1,59 +0,0 @@
|
||||
extends GEAction
|
||||
class_name GEPasteCut
|
||||
|
||||
|
||||
#data[2] = selection_pos
|
||||
#data[3] = selection_color
|
||||
#data[4] = cut pos
|
||||
#data[5] = cut size
|
||||
func do_action(canvas, data: Array):
|
||||
.do_action(canvas, data)
|
||||
|
||||
for pixel_pos in GEUtils.get_pixels_in_line(data[0], data[1]):
|
||||
for idx in range(data[2].size()):
|
||||
var pixel = data[2][idx]
|
||||
var color = data[3][idx]
|
||||
pixel -= data[4] + data[5] / 2
|
||||
pixel += pixel_pos
|
||||
|
||||
if canvas.get_pixel_v(pixel) == null:
|
||||
continue
|
||||
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
continue
|
||||
|
||||
var found = action_data.redo.cells.find(pixel)
|
||||
if found == -1:
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(color)
|
||||
else:
|
||||
action_data.redo.colors[found] = color
|
||||
|
||||
found = action_data.undo.cells.find(pixel)
|
||||
if found == -1:
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
|
||||
canvas.set_pixel_v(pixel, color)
|
||||
|
||||
|
||||
func commit_action(canvas):
|
||||
canvas.clear_preview_layer()
|
||||
return []
|
||||
|
||||
|
||||
func undo_action(canvas):
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
func redo_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
extends GEAction
|
||||
class_name GEPencil
|
||||
|
||||
|
||||
func do_action(canvas, data: Array):
|
||||
.do_action(canvas, data)
|
||||
|
||||
var pixels = GEUtils.get_pixels_in_line(data[0], data[1])
|
||||
for pixel in pixels:
|
||||
for p in get_points(canvas, pixel):
|
||||
_set_pixel(canvas, p, data[2])
|
||||
|
||||
|
||||
func _set_pixel(canvas, pixel, color):
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
canvas.set_pixel_v(pixel, color)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(color)
|
||||
|
||||
|
||||
func commit_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
return []
|
||||
|
||||
|
||||
func undo_action(canvas):
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
func redo_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
|
@ -1,58 +0,0 @@
|
||||
extends GEAction
|
||||
class_name GERainbow
|
||||
|
||||
|
||||
func do_action(canvas, data: Array):
|
||||
.do_action(canvas, data)
|
||||
|
||||
var pixels = GEUtils.get_pixels_in_line(data[0], data[1])
|
||||
for pixel in pixels:
|
||||
if canvas.get_pixel_v(pixel) == null:
|
||||
continue
|
||||
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
continue
|
||||
|
||||
if pixel in action_data.undo.cells:
|
||||
var color = GEUtils.random_color()
|
||||
canvas.set_pixel_v(pixel, color)
|
||||
|
||||
var idx = action_data.redo.cells.find(pixel)
|
||||
action_data.redo.cells.remove(idx)
|
||||
action_data.redo.colors.remove(idx)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(color)
|
||||
continue
|
||||
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
|
||||
var color = GEUtils.random_color()
|
||||
canvas.set_pixel_v(pixel, color)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(color)
|
||||
|
||||
|
||||
func commit_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
return []
|
||||
|
||||
|
||||
func undo_action(canvas):
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
func redo_action(canvas):
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
|
87
modules/paint/actions/brighten_action.cpp
Normal file
87
modules/paint/actions/brighten_action.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "brighten_action.h"
|
||||
|
||||
void BrightenAction::do_action(PaintCanvas *canvas, Array data) {
|
||||
/*
|
||||
.do_action(canvas, data)
|
||||
|
||||
var pixels = GEUtils.get_pixels_in_line(data[0], data[1])
|
||||
for pixel in pixels:
|
||||
if canvas.get_pixel_v(pixel) == null:
|
||||
continue
|
||||
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
continue
|
||||
|
||||
if pixel in action_data.undo.cells:
|
||||
var brightened_color = canvas.get_pixel_v(pixel).lightened(0.1)
|
||||
canvas.set_pixel_v(pixel, brightened_color)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(brightened_color)
|
||||
continue
|
||||
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
var brightened_color = canvas.get_pixel_v(pixel).lightened(0.1)
|
||||
canvas.set_pixel_v(pixel, brightened_color)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(brightened_color)
|
||||
*/
|
||||
}
|
||||
void BrightenAction::commit_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
*/
|
||||
}
|
||||
|
||||
void BrightenAction::undo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
void BrightenAction::redo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
|
||||
BrightenAction::BrightenAction() {
|
||||
}
|
||||
|
||||
BrightenAction::~BrightenAction() {
|
||||
}
|
||||
|
||||
void BrightenAction::_bind_methods() {
|
||||
}
|
51
modules/paint/actions/brighten_action.h
Normal file
51
modules/paint/actions/brighten_action.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef BRIGHTEN_ACTION_H
|
||||
#define BRIGHTEN_ACTION_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_action.h"
|
||||
|
||||
class PaintCanvas;
|
||||
|
||||
class BrightenAction : public PaintAction {
|
||||
GDCLASS(BrightenAction, PaintAction);
|
||||
|
||||
public:
|
||||
void do_action(PaintCanvas *canvas, Array data);
|
||||
void commit_action(PaintCanvas *canvas);
|
||||
|
||||
void undo_action(PaintCanvas *canvas);
|
||||
void redo_action(PaintCanvas *canvas);
|
||||
|
||||
BrightenAction();
|
||||
~BrightenAction();
|
||||
|
||||
//const brighten_color = 0.1
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif
|
81
modules/paint/actions/brush_action.cpp
Normal file
81
modules/paint/actions/brush_action.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "brush_action.h"
|
||||
|
||||
void BrushAction::do_action(PaintCanvas *canvas, Array data) {
|
||||
/*
|
||||
.do_action(canvas, data)
|
||||
|
||||
for pixel in GEUtils.get_pixels_in_line(data[0], data[1]):
|
||||
for off in BrushPrefabs.get_brush(data[3], data[4]):
|
||||
var p = pixel + off
|
||||
|
||||
if p in action_data.undo.cells or canvas.get_pixel_v(p) == null:
|
||||
continue
|
||||
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(p) == Color.transparent:
|
||||
continue
|
||||
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(p))
|
||||
action_data.undo.cells.append(p)
|
||||
|
||||
canvas.set_pixel_v(p, data[2])
|
||||
|
||||
action_data.redo.cells.append(p)
|
||||
action_data.redo.colors.append(data[2])
|
||||
*/
|
||||
}
|
||||
void BrushAction::commit_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
*/
|
||||
}
|
||||
|
||||
void BrushAction::undo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
void BrushAction::redo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
|
||||
BrushAction::BrushAction() {
|
||||
}
|
||||
|
||||
BrushAction::~BrushAction() {
|
||||
}
|
||||
|
||||
void BrushAction::_bind_methods() {
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
#ifndef BRUSH_ACTION_H
|
||||
#define BRUSH_ACTION_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
@ -22,13 +25,25 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_image_layer.h"
|
||||
#include "paint_action.h"
|
||||
|
||||
PaintImageLayer::PaintImageLayer() {
|
||||
}
|
||||
class PaintCanvas;
|
||||
|
||||
PaintImageLayer::~PaintImageLayer() {
|
||||
}
|
||||
class BrushAction : public PaintAction {
|
||||
GDCLASS(BrushAction, PaintAction);
|
||||
|
||||
void PaintImageLayer::_bind_methods() {
|
||||
}
|
||||
public:
|
||||
void do_action(PaintCanvas *canvas, Array data);
|
||||
void commit_action(PaintCanvas *canvas);
|
||||
|
||||
void undo_action(PaintCanvas *canvas);
|
||||
void redo_action(PaintCanvas *canvas);
|
||||
|
||||
BrushAction();
|
||||
~BrushAction();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif
|
82
modules/paint/actions/bucket_action.cpp
Normal file
82
modules/paint/actions/bucket_action.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "bucket_action.h"
|
||||
|
||||
void BucketAction::do_action(PaintCanvas *canvas, Array data) {
|
||||
/*
|
||||
.do_action(canvas, data)
|
||||
|
||||
if canvas.get_pixel_v(data[0]) == data[2]:
|
||||
return
|
||||
var pixels = canvas.select_same_color(data[0].x, data[0].y)
|
||||
|
||||
for pixel in pixels:
|
||||
if pixel in action_data.undo.cells:
|
||||
continue
|
||||
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
continue
|
||||
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
|
||||
canvas.set_pixel_v(pixel, data[2])
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(data[2])
|
||||
*/
|
||||
}
|
||||
void BucketAction::commit_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.preview.cells
|
||||
var colors = action_data.preview.colors
|
||||
*/
|
||||
}
|
||||
|
||||
void BucketAction::undo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
void BucketAction::redo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
|
||||
BucketAction::BucketAction() {
|
||||
}
|
||||
|
||||
BucketAction::~BucketAction() {
|
||||
}
|
||||
|
||||
void BucketAction::_bind_methods() {
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
#ifndef BUCKET_ACTION_H
|
||||
#define BUCKET_ACTION_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
@ -22,13 +25,25 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_save_file_dialog.h"
|
||||
#include "paint_action.h"
|
||||
|
||||
PaintSaveFileDialog::PaintSaveFileDialog() {
|
||||
}
|
||||
class PaintCanvas;
|
||||
|
||||
PaintSaveFileDialog::~PaintSaveFileDialog() {
|
||||
}
|
||||
class BucketAction : public PaintAction {
|
||||
GDCLASS(BucketAction, PaintAction);
|
||||
|
||||
void PaintSaveFileDialog::_bind_methods() {
|
||||
}
|
||||
public:
|
||||
void do_action(PaintCanvas *canvas, Array data);
|
||||
void commit_action(PaintCanvas *canvas);
|
||||
|
||||
void undo_action(PaintCanvas *canvas);
|
||||
void redo_action(PaintCanvas *canvas);
|
||||
|
||||
BucketAction();
|
||||
~BucketAction();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif
|
@ -1,45 +1,65 @@
|
||||
extends GEAction
|
||||
class_name GECut
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
const selection_color = Color(0.8, 0.8, 0.8, 0.5)
|
||||
var mouse_start_pos = null
|
||||
var mouse_end_pos = null
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
func can_commit() -> bool:
|
||||
return false #ugly way of handling a cut
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "cut_action.h"
|
||||
|
||||
func do_action(canvas, data: Array):
|
||||
bool CutAction::can_commit() {
|
||||
return false; //ugly way of handling a cut
|
||||
}
|
||||
|
||||
void CutAction::do_action(PaintCanvas *canvas, Array data) {
|
||||
/*
|
||||
.do_action(canvas, data)
|
||||
|
||||
|
||||
if mouse_start_pos == null:
|
||||
mouse_start_pos = data[0]
|
||||
mouse_end_pos = data[0]
|
||||
|
||||
|
||||
action_data.preview.cells.clear()
|
||||
action_data.preview.colors.clear()
|
||||
canvas.clear_preview_layer()
|
||||
|
||||
|
||||
var p = mouse_start_pos
|
||||
var s = mouse_end_pos - mouse_start_pos
|
||||
|
||||
|
||||
var pixels = GEUtils.get_pixels_in_line(p, p + Vector2(s.x, 0))
|
||||
pixels += GEUtils.get_pixels_in_line(p, p + Vector2(0, s.y))
|
||||
pixels += GEUtils.get_pixels_in_line(p + s, p + s + Vector2(0, -s.y))
|
||||
pixels += GEUtils.get_pixels_in_line(p + s, p + s + Vector2(-s.x, 0))
|
||||
|
||||
|
||||
for pixel in pixels:
|
||||
canvas.set_preview_pixel_v(pixel, selection_color)
|
||||
action_data.preview.cells.append(pixel)
|
||||
action_data.preview.colors.append(selection_color)
|
||||
|
||||
|
||||
func commit_action(canvas):
|
||||
*/
|
||||
}
|
||||
void CutAction::commit_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
canvas.clear_preview_layer()
|
||||
var p = mouse_start_pos
|
||||
var s = mouse_end_pos - mouse_start_pos
|
||||
|
||||
|
||||
for x in range(abs(s.x)+1):
|
||||
for y in range(abs(s.y)+1):
|
||||
var px = x
|
||||
@ -48,35 +68,45 @@ func commit_action(canvas):
|
||||
px *= -1
|
||||
if s.y < 0:
|
||||
py *= -1
|
||||
|
||||
|
||||
var pos = p + Vector2(px, py)
|
||||
var color = canvas.get_pixel(pos.x, pos.y)
|
||||
|
||||
|
||||
if color == null or color.a == 0.0:
|
||||
continue
|
||||
|
||||
|
||||
action_data.redo.cells.append(pos)
|
||||
action_data.redo.colors.append(canvas.get_pixel_v(pos))
|
||||
|
||||
|
||||
canvas.set_pixel_v(pos, Color.transparent)
|
||||
|
||||
|
||||
action_data.undo.cells.append(pos)
|
||||
action_data.undo.colors.append(Color.transparent)
|
||||
return []
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
func undo_action(canvas):
|
||||
void CutAction::undo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
func redo_action(canvas):
|
||||
*/
|
||||
}
|
||||
void CutAction::redo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
|
||||
CutAction::CutAction() {
|
||||
}
|
||||
|
||||
CutAction::~CutAction() {
|
||||
}
|
||||
|
||||
void CutAction::_bind_methods() {
|
||||
}
|
55
modules/paint/actions/cut_action.h
Normal file
55
modules/paint/actions/cut_action.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef CUT_ACTION_H
|
||||
#define CUT_ACTION_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_action.h"
|
||||
|
||||
class PaintCanvas;
|
||||
|
||||
class CutAction : public PaintAction {
|
||||
GDCLASS(CutAction, PaintAction);
|
||||
|
||||
public:
|
||||
bool can_commit();
|
||||
|
||||
void do_action(PaintCanvas *canvas, Array data);
|
||||
void commit_action(PaintCanvas *canvas);
|
||||
|
||||
void undo_action(PaintCanvas *canvas);
|
||||
void redo_action(PaintCanvas *canvas);
|
||||
|
||||
CutAction();
|
||||
~CutAction();
|
||||
|
||||
//const selection_color = Color(0.8, 0.8, 0.8, 0.5)
|
||||
//var mouse_start_pos = null
|
||||
//var mouse_end_pos = null
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif
|
87
modules/paint/actions/darken_action.cpp
Normal file
87
modules/paint/actions/darken_action.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "darken_action.h"
|
||||
|
||||
void DarkenAction::do_action(PaintCanvas *canvas, Array data) {
|
||||
/*
|
||||
.do_action(canvas, data)
|
||||
|
||||
var pixels = GEUtils.get_pixels_in_line(data[0], data[1])
|
||||
for pixel in pixels:
|
||||
if canvas.get_pixel_v(pixel) == null:
|
||||
continue
|
||||
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
continue
|
||||
|
||||
if pixel in action_data.undo.cells:
|
||||
var darkened_color = canvas.get_pixel_v(pixel).darkened(dark_factor)
|
||||
canvas.set_pixel_v(pixel, darkened_color)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(darkened_color)
|
||||
continue
|
||||
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
var darkened_color = canvas.get_pixel_v(pixel).darkened(dark_factor)
|
||||
canvas.set_pixel_v(pixel, darkened_color)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(darkened_color)
|
||||
*/
|
||||
}
|
||||
void DarkenAction::commit_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
*/
|
||||
}
|
||||
|
||||
void DarkenAction::undo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
void DarkenAction::redo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
|
||||
DarkenAction::DarkenAction() {
|
||||
}
|
||||
|
||||
DarkenAction::~DarkenAction() {
|
||||
}
|
||||
|
||||
void DarkenAction::_bind_methods() {
|
||||
}
|
51
modules/paint/actions/darken_action.h
Normal file
51
modules/paint/actions/darken_action.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef DARKEN_ACTION_H
|
||||
#define DARKEN_ACTION_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_action.h"
|
||||
|
||||
class PaintCanvas;
|
||||
|
||||
class DarkenAction : public PaintAction {
|
||||
GDCLASS(DarkenAction, PaintAction);
|
||||
|
||||
public:
|
||||
void do_action(PaintCanvas *canvas, Array data);
|
||||
void commit_action(PaintCanvas *canvas);
|
||||
|
||||
void undo_action(PaintCanvas *canvas);
|
||||
void redo_action(PaintCanvas *canvas);
|
||||
|
||||
DarkenAction();
|
||||
~DarkenAction();
|
||||
|
||||
//const dark_factor = 0.1
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif
|
91
modules/paint/actions/line_action.cpp
Normal file
91
modules/paint/actions/line_action.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "line_action.h"
|
||||
|
||||
void LineAction::do_action(PaintCanvas *canvas, Array data) {
|
||||
/*
|
||||
.do_action(canvas, data)
|
||||
|
||||
if mouse_start_pos == null:
|
||||
mouse_start_pos = data[0]
|
||||
|
||||
action_data.preview.cells.clear()
|
||||
action_data.preview.colors.clear()
|
||||
canvas.clear_preview_layer()
|
||||
|
||||
var pixels = GEUtils.get_pixels_in_line(data[0], mouse_start_pos)
|
||||
for pixel in pixels:
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
continue
|
||||
|
||||
canvas.set_preview_pixel_v(pixel, data[2])
|
||||
action_data.preview.cells.append(pixel)
|
||||
action_data.preview.colors.append(data[2])
|
||||
*/
|
||||
}
|
||||
void LineAction::commit_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
canvas.clear_preview_layer()
|
||||
var cells = action_data.preview.cells
|
||||
var colors = action_data.preview.colors
|
||||
for idx in range(cells.size()):
|
||||
if canvas.get_pixel_v(cells[idx]) == null:
|
||||
continue
|
||||
action_data.undo.cells.append(cells[idx])
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(cells[idx]))
|
||||
|
||||
canvas.set_pixel_v(cells[idx], colors[idx])
|
||||
|
||||
action_data.redo.cells.append(cells[idx])
|
||||
action_data.redo.colors.append(colors[idx])
|
||||
mouse_start_pos = null
|
||||
*/
|
||||
}
|
||||
|
||||
void LineAction::undo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
void LineAction::redo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
|
||||
LineAction::LineAction() {
|
||||
}
|
||||
|
||||
LineAction::~LineAction() {
|
||||
}
|
||||
|
||||
void LineAction::_bind_methods() {
|
||||
}
|
51
modules/paint/actions/line_action.h
Normal file
51
modules/paint/actions/line_action.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef LINE_ACTION_H
|
||||
#define LINE_ACTION_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_action.h"
|
||||
|
||||
class PaintCanvas;
|
||||
|
||||
class LineAction : public PaintAction {
|
||||
GDCLASS(LineAction, PaintAction);
|
||||
|
||||
public:
|
||||
void do_action(PaintCanvas *canvas, Array data);
|
||||
void commit_action(PaintCanvas *canvas);
|
||||
|
||||
void undo_action(PaintCanvas *canvas);
|
||||
void redo_action(PaintCanvas *canvas);
|
||||
|
||||
LineAction();
|
||||
~LineAction();
|
||||
|
||||
//var mouse_start_pos = null
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif
|
78
modules/paint/actions/multiline_action.cpp
Normal file
78
modules/paint/actions/multiline_action.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "multiline_action.h"
|
||||
|
||||
bool MultiLineAction::can_commit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void MultiLineAction::do_action(PaintCanvas *canvas, Array data) {
|
||||
/*
|
||||
.do_action(canvas, data)
|
||||
|
||||
var pixels = GEUtils.get_pixels_in_line(data[0], data[1])
|
||||
for pixel in pixels:
|
||||
if pixel in action_data.undo.cells or canvas.get_pixel_v(pixel) == null or canvas.is_alpha_locked():
|
||||
continue
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
canvas.set_pixel_v(pixel, data[2])
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(data[2])
|
||||
*/
|
||||
}
|
||||
void MultiLineAction::commit_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
*/
|
||||
}
|
||||
|
||||
void MultiLineAction::undo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
void MultiLineAction::redo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
|
||||
MultiLineAction::MultiLineAction() {
|
||||
}
|
||||
|
||||
MultiLineAction::~MultiLineAction() {
|
||||
}
|
||||
|
||||
void MultiLineAction::_bind_methods() {
|
||||
}
|
51
modules/paint/actions/multiline_action.h
Normal file
51
modules/paint/actions/multiline_action.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef MULTI_LINE_ACTION_H
|
||||
#define MULTI_LINE_ACTION_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_action.h"
|
||||
|
||||
class PaintCanvas;
|
||||
|
||||
class MultiLineAction : public PaintAction {
|
||||
GDCLASS(MultiLineAction, PaintAction);
|
||||
|
||||
public:
|
||||
bool can_commit();
|
||||
|
||||
void do_action(PaintCanvas *canvas, Array data);
|
||||
void commit_action(PaintCanvas *canvas);
|
||||
|
||||
void undo_action(PaintCanvas *canvas);
|
||||
void redo_action(PaintCanvas *canvas);
|
||||
|
||||
MultiLineAction();
|
||||
~MultiLineAction();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif
|
@ -1,91 +1,115 @@
|
||||
extends Node
|
||||
class_name GEAction
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
var action_data = {}
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
func _init():
|
||||
action_data["redo"] = {}
|
||||
action_data["undo"] = {}
|
||||
action_data["preview"] = {}
|
||||
#include "paint_action.h"
|
||||
|
||||
|
||||
func do_action(canvas, data: Array):
|
||||
void PaintAction::do_action(PaintCanvas *canvas, Array data) {
|
||||
/*
|
||||
if not "cells" in action_data.redo:
|
||||
action_data.redo["cells"] = []
|
||||
action_data.redo["colors"] = []
|
||||
|
||||
|
||||
if not "cells" in action_data.undo:
|
||||
action_data.undo["cells"] = []
|
||||
action_data.undo["colors"] = []
|
||||
|
||||
|
||||
if not "cells" in action_data.preview:
|
||||
action_data.preview["cells"] = []
|
||||
action_data.preview["colors"] = []
|
||||
|
||||
|
||||
if not "layer" in action_data:
|
||||
action_data["layer"] = canvas.active_layer
|
||||
|
||||
|
||||
func commit_action(canvas):
|
||||
*/
|
||||
}
|
||||
void PaintAction::commit_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
print("NO IMPL commit_action ")
|
||||
return []
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
func undo_action(canvas):
|
||||
void PaintAction::undo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
print("NO IMPL undo_action ")
|
||||
|
||||
|
||||
func redo_action(canvas):
|
||||
*/
|
||||
}
|
||||
void PaintAction::redo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
print("NO IMPL redo_action ")
|
||||
|
||||
|
||||
func can_commit() -> bool:
|
||||
*/
|
||||
}
|
||||
bool PaintAction::can_commit() {
|
||||
/*
|
||||
return not action_data.redo.empty()
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
func get_x_sym_points(canvas_width, pixel):
|
||||
Array PaintAction::get_x_sym_points(int canvas_width, Vector2i pixel) {
|
||||
/*
|
||||
var p = int(canvas_width - pixel.x)
|
||||
var all_points = [pixel, Vector2(p-1, pixel.y)]
|
||||
|
||||
|
||||
var points :Array = []
|
||||
for point in all_points:
|
||||
if point in points:
|
||||
continue
|
||||
points.append(point)
|
||||
return points
|
||||
|
||||
|
||||
func get_y_sym_points(canvas_height, pixel):
|
||||
*/
|
||||
}
|
||||
Array PaintAction::get_y_sym_points(int canvas_height, Vector2i pixel) {
|
||||
/*
|
||||
var p = int(canvas_height - pixel.y)
|
||||
var all_points = [pixel, Vector2(pixel.x, p-1)]
|
||||
|
||||
|
||||
var points :Array = []
|
||||
for point in all_points:
|
||||
if point in points:
|
||||
continue
|
||||
points.append(point)
|
||||
return points
|
||||
|
||||
|
||||
func get_xy_sym_points(canvas_width, canvas_height, pixel):
|
||||
*/
|
||||
}
|
||||
Array PaintAction::get_xy_sym_points(int canvas_width, int canvas_height, Vector2i pixel) {
|
||||
/*
|
||||
var all_points = []
|
||||
var xpoints = get_x_sym_points(canvas_width, pixel)
|
||||
|
||||
|
||||
all_points += get_y_sym_points(canvas_height, xpoints[0])
|
||||
all_points += get_y_sym_points(canvas_height, xpoints[1])
|
||||
|
||||
|
||||
var points :Array = []
|
||||
for point in all_points:
|
||||
if point in points:
|
||||
continue
|
||||
points.append(point)
|
||||
|
||||
|
||||
return points
|
||||
|
||||
|
||||
func get_points(canvas, pixel):
|
||||
*/
|
||||
}
|
||||
Array PaintAction::get_points(PaintCanvas *canvas, Vector2i pixel) {
|
||||
/*
|
||||
var points = []
|
||||
if canvas.symmetry_x and canvas.symmetry_y:
|
||||
var sym_points = get_xy_sym_points(canvas.canvas_width, canvas.canvas_height, pixel)
|
||||
@ -117,7 +141,23 @@ func get_points(canvas, pixel):
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
return []
|
||||
points.append(pixel)
|
||||
|
||||
|
||||
return points
|
||||
*/
|
||||
}
|
||||
|
||||
PaintAction::PaintAction() {
|
||||
/*
|
||||
|
||||
action_data["redo"] = {}
|
||||
action_data["undo"] = {}
|
||||
action_data["preview"] = {}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
PaintAction::~PaintAction() {
|
||||
}
|
||||
|
||||
void PaintAction::_bind_methods() {
|
||||
}
|
64
modules/paint/actions/paint_action.h
Normal file
64
modules/paint/actions/paint_action.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef PAINT_ACTIONS_H
|
||||
#define PAINT_ACTIONS_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "core/reference.h"
|
||||
|
||||
#include "core/pool_vector.h"
|
||||
#include "core/variant.h"
|
||||
#include "core/array.h"
|
||||
#include "core/math/vector2i.h"
|
||||
|
||||
class PaintCanvas;
|
||||
|
||||
//extends Node (this should probably not be a node)
|
||||
//class_name GEAction
|
||||
class PaintAction : public Reference {
|
||||
GDCLASS(PaintAction, Reference);
|
||||
|
||||
public:
|
||||
virtual void do_action(PaintCanvas *canvas, Array data);
|
||||
virtual void commit_action(PaintCanvas *canvas);
|
||||
|
||||
virtual void undo_action(PaintCanvas *canvas);
|
||||
virtual void redo_action(PaintCanvas *canvas);
|
||||
virtual bool can_commit();
|
||||
|
||||
virtual Array get_x_sym_points(int canvas_width, Vector2i pixel);
|
||||
virtual Array get_y_sym_points(int canvas_height, Vector2i pixel);
|
||||
virtual Array get_xy_sym_points(int canvas_width, int canvas_height, Vector2i pixel);
|
||||
virtual Array get_points(PaintCanvas *canvas, Vector2i pixel);
|
||||
|
||||
PaintAction();
|
||||
~PaintAction();
|
||||
|
||||
//var action_data = {}
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif
|
93
modules/paint/actions/paste_cut_action.cpp
Normal file
93
modules/paint/actions/paste_cut_action.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paste_cut_action.h"
|
||||
|
||||
//data[2] = selection_pos
|
||||
//data[3] = selection_color
|
||||
//data[4] = cut pos
|
||||
//data[5] = cut size
|
||||
void PasteCutAction::do_action(PaintCanvas *canvas, Array data) {
|
||||
/*
|
||||
.do_action(canvas, data)
|
||||
|
||||
for pixel_pos in GEUtils.get_pixels_in_line(data[0], data[1]):
|
||||
for idx in range(data[2].size()):
|
||||
var pixel = data[2][idx]
|
||||
var color = data[3][idx]
|
||||
pixel -= data[4] + data[5] / 2
|
||||
pixel += pixel_pos
|
||||
|
||||
if canvas.get_pixel_v(pixel) == null:
|
||||
continue
|
||||
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
continue
|
||||
|
||||
var found = action_data.redo.cells.find(pixel)
|
||||
if found == -1:
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(color)
|
||||
else:
|
||||
action_data.redo.colors[found] = color
|
||||
|
||||
found = action_data.undo.cells.find(pixel)
|
||||
if found == -1:
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
|
||||
canvas.set_pixel_v(pixel, color)
|
||||
*/
|
||||
}
|
||||
void PasteCutAction::commit_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
canvas.clear_preview_layer()
|
||||
*/
|
||||
}
|
||||
|
||||
void PasteCutAction::undo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
void PasteCutAction::redo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
|
||||
PasteCutAction::PasteCutAction() {
|
||||
}
|
||||
|
||||
PasteCutAction::~PasteCutAction() {
|
||||
}
|
||||
|
||||
void PasteCutAction::_bind_methods() {
|
||||
}
|
49
modules/paint/actions/paste_cut_action.h
Normal file
49
modules/paint/actions/paste_cut_action.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef PASTE_CUT_ACTION_H
|
||||
#define PASTE_CUT_ACTION_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_action.h"
|
||||
|
||||
class PaintCanvas;
|
||||
|
||||
class PasteCutAction : public PaintAction {
|
||||
GDCLASS(PasteCutAction, PaintAction);
|
||||
|
||||
public:
|
||||
void do_action(PaintCanvas *canvas, Array data);
|
||||
void commit_action(PaintCanvas *canvas);
|
||||
|
||||
void undo_action(PaintCanvas *canvas);
|
||||
void redo_action(PaintCanvas *canvas);
|
||||
|
||||
PasteCutAction();
|
||||
~PasteCutAction();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif
|
80
modules/paint/actions/pencil_action.cpp
Normal file
80
modules/paint/actions/pencil_action.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "pencil_action.h"
|
||||
|
||||
void PencilAction::do_action(PaintCanvas *canvas, Array data) {
|
||||
/*
|
||||
.do_action(canvas, data)
|
||||
|
||||
var pixels = GEUtils.get_pixels_in_line(data[0], data[1])
|
||||
for pixel in pixels:
|
||||
for p in get_points(canvas, pixel):
|
||||
_set_pixel(canvas, p, data[2])
|
||||
*/
|
||||
}
|
||||
void PencilAction::commit_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
return []
|
||||
*/
|
||||
}
|
||||
|
||||
void PencilAction::undo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
void PencilAction::redo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
|
||||
void PencilAction::_set_pixel(PaintCanvas *canvas, Vector2i pixel, Color color) {
|
||||
/*
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
canvas.set_pixel_v(pixel, color)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(color)
|
||||
*/
|
||||
}
|
||||
|
||||
PencilAction::PencilAction() {
|
||||
}
|
||||
|
||||
PencilAction::~PencilAction() {
|
||||
}
|
||||
|
||||
void PencilAction::_bind_methods() {
|
||||
}
|
51
modules/paint/actions/pencil_action.h
Normal file
51
modules/paint/actions/pencil_action.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef PENCIL_ACTION_H
|
||||
#define PENCIL_ACTION_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_action.h"
|
||||
|
||||
class PaintCanvas;
|
||||
|
||||
class PencilAction : public PaintAction {
|
||||
GDCLASS(PencilAction, PaintAction);
|
||||
|
||||
public:
|
||||
void do_action(PaintCanvas *canvas, Array data);
|
||||
void commit_action(PaintCanvas *canvas);
|
||||
|
||||
void undo_action(PaintCanvas *canvas);
|
||||
void redo_action(PaintCanvas *canvas);
|
||||
|
||||
void _set_pixel(PaintCanvas *canvas, Vector2i pixel, Color color);
|
||||
|
||||
PencilAction();
|
||||
~PencilAction();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif
|
94
modules/paint/actions/rainbow_action.cpp
Normal file
94
modules/paint/actions/rainbow_action.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "rainbow_action.h"
|
||||
|
||||
void RainbowAction::do_action(PaintCanvas *canvas, Array data) {
|
||||
/*
|
||||
.do_action(canvas, data)
|
||||
|
||||
var pixels = GEUtils.get_pixels_in_line(data[0], data[1])
|
||||
for pixel in pixels:
|
||||
if canvas.get_pixel_v(pixel) == null:
|
||||
continue
|
||||
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
continue
|
||||
|
||||
if pixel in action_data.undo.cells:
|
||||
var color = GEUtils.random_color()
|
||||
canvas.set_pixel_v(pixel, color)
|
||||
|
||||
var idx = action_data.redo.cells.find(pixel)
|
||||
action_data.redo.cells.remove(idx)
|
||||
action_data.redo.colors.remove(idx)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(color)
|
||||
continue
|
||||
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.undo.cells.append(pixel)
|
||||
|
||||
var color = GEUtils.random_color()
|
||||
canvas.set_pixel_v(pixel, color)
|
||||
|
||||
action_data.redo.cells.append(pixel)
|
||||
action_data.redo.colors.append(color)
|
||||
*/
|
||||
}
|
||||
void RainbowAction::commit_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
|
||||
void RainbowAction::undo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
void RainbowAction::redo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
|
||||
RainbowAction::RainbowAction() {
|
||||
}
|
||||
|
||||
RainbowAction::~RainbowAction() {
|
||||
}
|
||||
|
||||
void RainbowAction::_bind_methods() {
|
||||
}
|
49
modules/paint/actions/rainbow_action.h
Normal file
49
modules/paint/actions/rainbow_action.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef RAINBOW_ACTION_H
|
||||
#define RAINBOW_ACTION_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_action.h"
|
||||
|
||||
class PaintCanvas;
|
||||
|
||||
class RainbowAction : public PaintAction {
|
||||
GDCLASS(RainbowAction, PaintAction);
|
||||
|
||||
public:
|
||||
void do_action(PaintCanvas *canvas, Array data);
|
||||
void commit_action(PaintCanvas *canvas);
|
||||
|
||||
void undo_action(PaintCanvas *canvas);
|
||||
void redo_action(PaintCanvas *canvas);
|
||||
|
||||
RainbowAction();
|
||||
~RainbowAction();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif
|
@ -1,69 +1,101 @@
|
||||
extends GEAction
|
||||
class_name GERect
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
var mouse_start_pos = null
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
func do_action(canvas, data: Array):
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "rect_action.h"
|
||||
|
||||
void RectAction::do_action(PaintCanvas *canvas, Array data) {
|
||||
/*
|
||||
.do_action(canvas, data)
|
||||
|
||||
|
||||
if mouse_start_pos == null:
|
||||
mouse_start_pos = data[0]
|
||||
#print("init:", mouse_start_pos)
|
||||
|
||||
|
||||
|
||||
|
||||
action_data.undo.cells.clear()
|
||||
action_data.undo.colors.clear()
|
||||
action_data.preview.cells.clear()
|
||||
action_data.preview.colors.clear()
|
||||
canvas.clear_preview_layer()
|
||||
|
||||
|
||||
var p = mouse_start_pos
|
||||
var s = data[0] - mouse_start_pos
|
||||
var pixels = GEUtils.get_pixels_in_line(p, p + Vector2(s.x, 0))
|
||||
pixels += GEUtils.get_pixels_in_line(p, p + Vector2(0, s.y))
|
||||
pixels += GEUtils.get_pixels_in_line(p + s, p + s + Vector2(0, -s.y))
|
||||
pixels += GEUtils.get_pixels_in_line(p + s, p + s + Vector2(-s.x, 0))
|
||||
|
||||
|
||||
for pixel in pixels:
|
||||
if canvas.get_pixel_v(pixel) == null:
|
||||
continue
|
||||
|
||||
|
||||
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
|
||||
continue
|
||||
|
||||
|
||||
canvas.set_preview_pixel_v(pixel, data[2])
|
||||
action_data.undo.cells.append(pixel)
|
||||
action_data.undo.colors.append(canvas.get_pixel_v(pixel))
|
||||
action_data.preview.cells.append(pixel)
|
||||
action_data.preview.colors.append(data[2])
|
||||
|
||||
|
||||
func commit_action(canvas):
|
||||
*/
|
||||
}
|
||||
void RectAction::commit_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
canvas.clear_preview_layer()
|
||||
var cells = action_data.preview.cells
|
||||
var colors = action_data.preview.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas.set_pixel_v(cells[idx], colors[idx])
|
||||
|
||||
|
||||
action_data.redo.cells.append(cells[idx])
|
||||
action_data.redo.colors.append(colors[idx])
|
||||
mouse_start_pos = null
|
||||
return []
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
func undo_action(canvas):
|
||||
void RectAction::undo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.undo.cells
|
||||
var colors = action_data.undo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
|
||||
|
||||
func redo_action(canvas):
|
||||
*/
|
||||
}
|
||||
void RectAction::redo_action(PaintCanvas *canvas) {
|
||||
/*
|
||||
var cells = action_data.redo.cells
|
||||
var colors = action_data.redo.colors
|
||||
for idx in range(cells.size()):
|
||||
canvas._set_pixel_v(action_data.layer, cells[idx], colors[idx])
|
||||
*/
|
||||
}
|
||||
|
||||
RectAction::RectAction() {
|
||||
}
|
||||
|
||||
RectAction::~RectAction() {
|
||||
}
|
||||
|
||||
void RectAction::_bind_methods() {
|
||||
}
|
51
modules/paint/actions/rect_action.h
Normal file
51
modules/paint/actions/rect_action.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef RECT_ACTION_H
|
||||
#define RECT_ACTION_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_action.h"
|
||||
|
||||
class PaintCanvas;
|
||||
|
||||
class RectAction : public PaintAction {
|
||||
GDCLASS(RectAction, PaintAction);
|
||||
|
||||
public:
|
||||
void do_action(PaintCanvas *canvas, Array data);
|
||||
void commit_action(PaintCanvas *canvas);
|
||||
|
||||
void undo_action(PaintCanvas *canvas);
|
||||
void redo_action(PaintCanvas *canvas);
|
||||
|
||||
RectAction();
|
||||
~RectAction();
|
||||
|
||||
//var mouse_start_pos = null
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/BrushCircle.png-dd250909fee7964ffc38f7e4fcfe9c07.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/BrushCircle.png"
|
||||
dest_files=[ "res://.import/BrushCircle.png-dd250909fee7964ffc38f7e4fcfe9c07.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/BrushCircle_Hovered.png-ae1a4d835af51e8a293b71d6a241b71c.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/BrushCircle_Hovered.png"
|
||||
dest_files=[ "res://.import/BrushCircle_Hovered.png-ae1a4d835af51e8a293b71d6a241b71c.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/BrushHLine.png-9182ec8ac804af16d356bf911782e299.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/BrushHLine.png"
|
||||
dest_files=[ "res://.import/BrushHLine.png-9182ec8ac804af16d356bf911782e299.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/BrushHLine_Hovered.png-e51d5f3c1628c510a225057f3ed60d5a.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/BrushHLine_Hovered.png"
|
||||
dest_files=[ "res://.import/BrushHLine_Hovered.png-e51d5f3c1628c510a225057f3ed60d5a.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/BrushRect.png-2b2d0ae4889c1fbc5c7bee7ae5515663.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/BrushRect.png"
|
||||
dest_files=[ "res://.import/BrushRect.png-2b2d0ae4889c1fbc5c7bee7ae5515663.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/BrushRect_Hovered.png-b09066b673d6082ce887a03a19f17977.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/BrushRect_Hovered.png"
|
||||
dest_files=[ "res://.import/BrushRect_Hovered.png-b09066b673d6082ce887a03a19f17977.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/BrushVLine.png-022220d888fe2fe2f8a081bcca62b4b2.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/BrushVLine.png"
|
||||
dest_files=[ "res://.import/BrushVLine.png-022220d888fe2fe2f8a081bcca62b4b2.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/BrushVLine_Hovered.png-104e29757699756f1b44bd32a622df2c.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/BrushVLine_Hovered.png"
|
||||
dest_files=[ "res://.import/BrushVLine_Hovered.png-104e29757699756f1b44bd32a622df2c.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/Godoxel_Preview.png-e30103581d3fc0ed2a2c92cdf72b5c70.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/Godoxel_Preview.png"
|
||||
dest_files=[ "res://.import/Godoxel_Preview.png-e30103581d3fc0ed2a2c92cdf72b5c70.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/arrow_down.png-d2bd93428c0bc172a28a43c55aac576e.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/arrow_down.png"
|
||||
dest_files=[ "res://.import/arrow_down.png-d2bd93428c0bc172a28a43c55aac576e.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/arrow_up.png-2598e148d1b795a628ce80a4fd5cf401.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/arrow_up.png"
|
||||
dest_files=[ "res://.import/arrow_up.png-2598e148d1b795a628ce80a4fd5cf401.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,124 +0,0 @@
|
||||
Bitstream Vera Fonts Copyright
|
||||
|
||||
The fonts have a generous copyright, allowing derivative works (as
|
||||
long as "Bitstream" or "Vera" are not in the names), and full
|
||||
redistribution (so long as they are not *sold* by themselves). They
|
||||
can be be bundled, redistributed and sold with any software.
|
||||
|
||||
The fonts are distributed under the following copyright:
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream
|
||||
Vera is a trademark of Bitstream, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the fonts accompanying this license ("Fonts") and associated
|
||||
documentation files (the "Font Software"), to reproduce and distribute
|
||||
the Font Software, including without limitation the rights to use,
|
||||
copy, merge, publish, distribute, and/or sell copies of the Font
|
||||
Software, and to permit persons to whom the Font Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice
|
||||
shall be included in all copies of one or more of the Font Software
|
||||
typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in
|
||||
particular the designs of glyphs or characters in the Fonts may be
|
||||
modified and additional glyphs or characters may be added to the
|
||||
Fonts, only if the fonts are renamed to names not containing either
|
||||
the words "Bitstream" or the word "Vera".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts
|
||||
or Font Software that has been modified and is distributed under the
|
||||
"Bitstream Vera" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but
|
||||
no copy of one or more of the Font Software typefaces may be sold by
|
||||
itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
|
||||
BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL,
|
||||
OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT
|
||||
SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the names of Gnome, the Gnome
|
||||
Foundation, and Bitstream Inc., shall not be used in advertising or
|
||||
otherwise to promote the sale, use or other dealings in this Font
|
||||
Software without prior written authorization from the Gnome Foundation
|
||||
or Bitstream Inc., respectively. For further information, contact:
|
||||
fonts at gnome dot org.
|
||||
|
||||
Copyright FAQ
|
||||
=============
|
||||
|
||||
1. I don't understand the resale restriction... What gives?
|
||||
|
||||
Bitstream is giving away these fonts, but wishes to ensure its
|
||||
competitors can't just drop the fonts as is into a font sale system
|
||||
and sell them as is. It seems fair that if Bitstream can't make money
|
||||
from the Bitstream Vera fonts, their competitors should not be able to
|
||||
do so either. You can sell the fonts as part of any software package,
|
||||
however.
|
||||
|
||||
2. I want to package these fonts separately for distribution and
|
||||
sale as part of a larger software package or system. Can I do so?
|
||||
|
||||
Yes. A RPM or Debian package is a "larger software package" to begin
|
||||
with, and you aren't selling them independently by themselves.
|
||||
See 1. above.
|
||||
|
||||
3. Are derivative works allowed?
|
||||
Yes!
|
||||
|
||||
4. Can I change or add to the font(s)?
|
||||
Yes, but you must change the name(s) of the font(s).
|
||||
|
||||
5. Under what terms are derivative works allowed?
|
||||
|
||||
You must change the name(s) of the fonts. This is to ensure the
|
||||
quality of the fonts, both to protect Bitstream and Gnome. We want to
|
||||
ensure that if an application has opened a font specifically of these
|
||||
names, it gets what it expects (though of course, using fontconfig,
|
||||
substitutions could still could have occurred during font
|
||||
opening). You must include the Bitstream copyright. Additional
|
||||
copyrights can be added, as per copyright law. Happy Font Hacking!
|
||||
|
||||
6. If I have improvements for Bitstream Vera, is it possible they might get
|
||||
adopted in future versions?
|
||||
|
||||
Yes. The contract between the Gnome Foundation and Bitstream has
|
||||
provisions for working with Bitstream to ensure quality additions to
|
||||
the Bitstream Vera font family. Please contact us if you have such
|
||||
additions. Note, that in general, we will want such additions for the
|
||||
entire family, not just a single font, and that you'll have to keep
|
||||
both Gnome and Jim Lyles, Vera's designer, happy! To make sense to add
|
||||
glyphs to the font, they must be stylistically in keeping with Vera's
|
||||
design. Vera cannot become a "ransom note" font. Jim Lyles will be
|
||||
providing a document describing the design elements used in Vera, as a
|
||||
guide and aid for people interested in contributing to Vera.
|
||||
|
||||
7. I want to sell a software package that uses these fonts: Can I do so?
|
||||
|
||||
Sure. Bundle the fonts with your software and sell your software
|
||||
with the fonts. That is the intent of the copyright.
|
||||
|
||||
8. If applications have built the names "Bitstream Vera" into them,
|
||||
can I override this somehow to use fonts of my choosing?
|
||||
|
||||
This depends on exact details of the software. Most open source
|
||||
systems and software (e.g., Gnome, KDE, etc.) are now converting to
|
||||
use fontconfig (see www.fontconfig.org) to handle font configuration,
|
||||
selection and substitution; it has provisions for overriding font
|
||||
names and subsituting alternatives. An example is provided by the
|
||||
supplied local.conf file, which chooses the family Bitstream Vera for
|
||||
"sans", "serif" and "monospace". Other software (e.g., the XFree86
|
||||
core server) has other mechanisms for font substitution.
|
||||
|
@ -1,11 +0,0 @@
|
||||
Contained herin is the Bitstream Vera font family.
|
||||
|
||||
The Copyright information is found in the COPYRIGHT.TXT file (along
|
||||
with being incoporated into the fonts themselves).
|
||||
|
||||
The releases notes are found in the file "RELEASENOTES.TXT".
|
||||
|
||||
We hope you enjoy Vera!
|
||||
|
||||
Bitstream, Inc.
|
||||
The Gnome Project
|
@ -1,162 +0,0 @@
|
||||
Bitstream Vera Fonts - April 16, 2003
|
||||
=====================================
|
||||
|
||||
The version number of these fonts is 1.10 to distinguish them from the
|
||||
beta test fonts.
|
||||
|
||||
Note that the Vera copyright is incorporated in the fonts themselves.
|
||||
The License field in the fonts contains the copyright license as it
|
||||
appears below. The TrueType copyright field is not large enough to
|
||||
contain the full license, so the license is incorporated (as you might
|
||||
think if you thought about it) into the license field, which
|
||||
unfortunately can be obscure to find. (In pfaedit, see: Element->Font
|
||||
Info->TTFNames->License).
|
||||
|
||||
Our apologies for it taking longer to complete the fonts than planned.
|
||||
Beta testers requested a tighter line spacing (less leading) and Jim
|
||||
Lyles redesigned Vera's accents to bring its line spacing to more
|
||||
typical of other fonts. This took additional time and effort. Our
|
||||
thanks to Jim for this effort above and beyond the call of duty.
|
||||
|
||||
There are four monospace and sans faces (normal, oblique, bold, bold
|
||||
oblique) and two serif faces (normal and bold). Fontconfig/Xft2 (see
|
||||
www.fontconfig.org) can artificially oblique the serif faces for you:
|
||||
this loses hinting and distorts the faces slightly, but is visibly
|
||||
different than normal and bold, and reasonably pleasing.
|
||||
|
||||
On systems with fontconfig 2.0 or 2.1 installed, making your sans,
|
||||
serif and monospace fonts default to these fonts is very easy. Just
|
||||
drop the file local.conf into your /etc/fonts directory. This will
|
||||
make the Bitstream fonts your default fonts for all applications using
|
||||
fontconfig (if sans, serif, or monospace names are used, as they often
|
||||
are as default values in many desktops). The XML in local.conf may
|
||||
need modification to enable subpixel decimation, if appropriate,
|
||||
however, the commented out phrase does so for XFree86 4.3, in the case
|
||||
that the server does not have sufficient information to identify the
|
||||
use of a flat panel. Fontconfig 2.2 adds Vera to the list of font
|
||||
families and will, by default use it as the default sans, serif and
|
||||
monospace fonts.
|
||||
|
||||
During the testing of the final Vera fonts, we learned that screen
|
||||
fonts in general are only typically hinted to work correctly at
|
||||
integer pixel sizes. Vera is coded internally for integer sizes only.
|
||||
We need to investigate further to see if there are commonly used fonts
|
||||
that are hinted to be rounded but are not rounded to integer sizes due
|
||||
to oversights in their coding.
|
||||
|
||||
Most fonts work best at 8 pixels and below if anti-aliased only, as
|
||||
the amount of work required to hint well at smaller and smaller sizes
|
||||
becomes astronomical. GASP tables are typically used to control
|
||||
whether hinting is used or not, but Freetype/Xft does not currently
|
||||
support GASP tables (which are present in Vera).
|
||||
|
||||
To mitigate this problem, both for Vera and other fonts, there will be
|
||||
(very shortly) a new fontconfig 2.2 release that will, by default not
|
||||
apply hints if the size is below 8 pixels. if you should have a font
|
||||
that in fact has been hinted more agressively, you can use fontconfig
|
||||
to note this exception. We believe this should improve many hinted
|
||||
fonts in addition to Vera, though implemeting GASP support is likely
|
||||
the right long term solution.
|
||||
|
||||
Font rendering in Gnome or KDE is the combination of algorithms in
|
||||
Xft2 and Freetype, along with hinting in the fonts themselves. It is
|
||||
vital to have sufficient information to disentangle problems that you
|
||||
may observe.
|
||||
|
||||
Note that having your font rendering system set up correctly is vital
|
||||
to proper judgement of problems of the fonts:
|
||||
|
||||
* Freetype may or may not be configured to in ways that may
|
||||
implement execution of possibly patented (in some parts of the world)
|
||||
TrueType hinting algorithms, particularly at small sizes. Best
|
||||
results are obtained while using these algorithms.
|
||||
|
||||
* The freetype autohinter (used when the possibly patented
|
||||
algorithms are not used) continues to improve with each release. If
|
||||
you are using the autohinter, please ensure you are using an up to
|
||||
date version of freetype before reporting problems.
|
||||
|
||||
* Please identify what version of freetype you are using in any
|
||||
bug reports, and how your freetype is configured.
|
||||
|
||||
* Make sure you are not using the freetype version included in
|
||||
XFree86 4.3, as it has bugs that significantly degrade most fonts,
|
||||
including Vera. if you build XFree86 4.3 from source yourself, you may
|
||||
have installed this broken version without intending it (as I
|
||||
did). Vera was verified with the recently released Freetype 2.1.4. On
|
||||
many systems, 'ldd" can be used to see which freetype shared library
|
||||
is actually being used.
|
||||
|
||||
* Xft/X Render does not (yet) implement gamma correction. This
|
||||
causes significant problems rendering white text on a black background
|
||||
(causing partial pixels to be insufficiently shaded) if the gamma of
|
||||
your monitor has not been compensated for, and minor problems with
|
||||
black text on a while background. The program "xgamma" can be used to
|
||||
set a gamma correction value in the X server's color pallette. Most
|
||||
monitors have a gamma near 2.
|
||||
|
||||
* Note that the Vera family uses minimal delta hinting. Your
|
||||
results on other systems when not used anti-aliased may not be
|
||||
entirely satisfying. We are primarily interested in reports of
|
||||
problems on open source systems implementing Xft2/fontconfig/freetype
|
||||
(which implements antialiasing and hinting adjustements, and
|
||||
sophisticated subpixel decimation on flatpanels). Also, the
|
||||
algorithms used by Xft2 adjust the hints to integer widths and the
|
||||
results are crisper on open source systems than on Windows or
|
||||
MacIntosh.
|
||||
|
||||
* Your fontconfig may (probably does) predate the release of
|
||||
fontconfig 2.2, and you may see artifacts not present when the font is
|
||||
used at very small sizes with hinting enabled. "vc-list -V" can be
|
||||
used to see what version you have installed.
|
||||
|
||||
We believe and hope that these fonts will resolve the problems
|
||||
reported during beta test. The largest change is the reduction of
|
||||
leading (interline spacing), which had annoyed a number of people, and
|
||||
reduced Vera's utility for some applcations. The Vera monospace font
|
||||
should also now make '0' and 'O' and '1' and 'l' more clearly
|
||||
distinguishable.
|
||||
|
||||
The version of these fonts is version 1.10. Fontconfig should be
|
||||
choosing the new version of the fonts if both the released fonts and
|
||||
beta test fonts are installed (though please discard them: they have
|
||||
names of form tt20[1-12]gn.ttf). Note that older versions of
|
||||
fontconfig sometimes did not rebuild their cache correctly when new
|
||||
fonts are installed: please upgrade to fontconfig 2.2. "fc-cache -f"
|
||||
can be used to force rebuilding fontconfig's cache files.
|
||||
|
||||
If you note problems, please send them to fonts at gnome dot org, with
|
||||
exactly which face and size and unicode point you observe the problem
|
||||
at. The xfd utility from XFree86 CVS may be useful for this (e.g. "xfd
|
||||
-fa sans"). A possibly more useful program to examine fonts at a
|
||||
variety of sizes is the "waterfall" program found in Keith Packard's
|
||||
CVS.
|
||||
|
||||
$ cvs -d :pserver:anoncvs@keithp.com:/local/src/CVS login
|
||||
Logging in to :pserver:anoncvs@keithp.com:2401/local/src/CVS
|
||||
CVS password: <hit return>
|
||||
$ cvs -d :pserver:anoncvs@keithp.com:/local/src/CVS co waterfall
|
||||
$ cd waterfall
|
||||
$ xmkmf -a
|
||||
$ make
|
||||
# make install
|
||||
# make install.man
|
||||
|
||||
Again, please make sure you are running an up-to-date freetype, and
|
||||
that you are only examining integer sizes.
|
||||
|
||||
Reporting Problems
|
||||
==================
|
||||
|
||||
Please send problem reports to fonts at gnome org, with the following
|
||||
information:
|
||||
|
||||
1. Version of Freetype, Xft2 and fontconfig
|
||||
2. Whether TT hinting is being used, or the autohinter
|
||||
3. Application being used
|
||||
4. Character/Unicode code point that has problems (if applicable)
|
||||
5. Version of which operating system
|
||||
6. Please include a screenshot, when possible.
|
||||
|
||||
Please check the fonts list archives before reporting problems to cut
|
||||
down on duplication.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,8 +0,0 @@
|
||||
[InternetShortcut]
|
||||
URL=http://www.all-free-download.com/
|
||||
IDList=
|
||||
HotKey=0
|
||||
IconFile=C:\WINDOWS\system32\SHELL32.dll
|
||||
IconIndex=23
|
||||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,2
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/grid.png-e3d637acacdb891e09f422df261dbd1e.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/grid.png"
|
||||
dest_files=[ "res://.import/grid.png-e3d637acacdb891e09f422df261dbd1e.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/lock_layer.png-076954b389746de9e13c853ed5d9ba59.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/lock_layer.png"
|
||||
dest_files=[ "res://.import/lock_layer.png-076954b389746de9e13c853ed5d9ba59.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/lock_layer_1.png-4848d5f2cd0f48c68b880712b6b38776.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/lock_layer_1.png"
|
||||
dest_files=[ "res://.import/lock_layer_1.png-4848d5f2cd0f48c68b880712b6b38776.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/minidotta.png-adac81df344972ef82e2499656aa288e.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/minidotta.png"
|
||||
dest_files=[ "res://.import/minidotta.png-adac81df344972ef82e2499656aa288e.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/minidotta_invis.png-5232a113bb226997ae55212b2aa90bd4.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/minidotta_invis.png"
|
||||
dest_files=[ "res://.import/minidotta_invis.png-5232a113bb226997ae55212b2aa90bd4.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=false
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
@ -1,35 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/unlock_layer.png-ae7c97a04fb889522c7c466fdc9dd8f6.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Godoxel/assets/unlock_layer.png"
|
||||
dest_files=[ "res://.import/unlock_layer.png-ae7c97a04fb889522c7c466fdc9dd8f6.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
91
modules/paint/dialogs/paint_save_file_dialog.cpp
Normal file
91
modules/paint/dialogs/paint_save_file_dialog.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_save_file_dialog.h"
|
||||
|
||||
void PaintSaveFileDialog::_ready() {
|
||||
/*
|
||||
# warning-ignore:return_value_discarded
|
||||
get_line_edit().connect("text_entered", self, "_on_LineEdit_text_entered")
|
||||
invalidate()
|
||||
clear_filters()
|
||||
add_filter("*.png ; PNG Images")
|
||||
*/
|
||||
}
|
||||
void PaintSaveFileDialog::_on_SaveFileDialog_file_selected(String path) {
|
||||
/*
|
||||
#print("selected file: ", path)
|
||||
file_path = path
|
||||
save_file()
|
||||
*/
|
||||
}
|
||||
void PaintSaveFileDialog::save_file() {
|
||||
/*
|
||||
var image = Image.new()
|
||||
var canvas = get_parent().paint_canvas
|
||||
image.create(canvas.canvas_width, canvas.canvas_height, true, Image.FORMAT_RGBA8)
|
||||
image.lock()
|
||||
|
||||
for layer in canvas.layers:
|
||||
var idx = 0
|
||||
if not layer.visible:
|
||||
continue
|
||||
for x in range(layer.layer_width):
|
||||
for y in range(layer.layer_height):
|
||||
var color = layer.get_pixel(x, y)
|
||||
var image_color = image.get_pixel(x, y)
|
||||
|
||||
if color.a != 0:
|
||||
image.set_pixel(x, y, image_color.blend(color))
|
||||
else:
|
||||
image.set_pixel(x, y, color)
|
||||
image.unlock()
|
||||
|
||||
var dir = Directory.new()
|
||||
if dir.file_exists(file_path):
|
||||
dir.remove(file_path)
|
||||
|
||||
image.save_png(file_path)
|
||||
*/
|
||||
}
|
||||
void PaintSaveFileDialog::_on_SaveFileDialog_about_to_show() {
|
||||
/*
|
||||
invalidate()
|
||||
*/
|
||||
}
|
||||
void PaintSaveFileDialog::_on_SaveFileDialog_visibility_changed() {
|
||||
/*
|
||||
invalidate()
|
||||
*/
|
||||
}
|
||||
|
||||
PaintSaveFileDialog::PaintSaveFileDialog() {
|
||||
//var file_path = ""
|
||||
}
|
||||
|
||||
PaintSaveFileDialog::~PaintSaveFileDialog() {
|
||||
}
|
||||
|
||||
void PaintSaveFileDialog::_bind_methods() {
|
||||
}
|
@ -25,17 +25,25 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/gui/file_dialog.h"
|
||||
|
||||
class PaintSaveFileDialog : public Control {
|
||||
GDCLASS(PaintSaveFileDialog, Control);
|
||||
class PaintSaveFileDialog : public FileDialog {
|
||||
GDCLASS(PaintSaveFileDialog, FileDialog);
|
||||
|
||||
public:
|
||||
void _ready();
|
||||
void _on_SaveFileDialog_file_selected(String path);
|
||||
void save_file();
|
||||
void _on_SaveFileDialog_about_to_show();
|
||||
void _on_SaveFileDialog_visibility_changed();
|
||||
|
||||
PaintSaveFileDialog();
|
||||
~PaintSaveFileDialog();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
//var file_path = ""
|
||||
};
|
||||
|
||||
#endif
|
@ -24,7 +24,494 @@ SOFTWARE.
|
||||
|
||||
#include "paint_canvas.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")
|
||||
|
||||
#-------------------------------
|
||||
# setup layers and canvas
|
||||
#-------------------------------
|
||||
connect("mouse_entered", self, "_on_mouse_entered")
|
||||
connect("mouse_exited", self, "_on_mouse_exited")
|
||||
|
||||
#-------------------------------
|
||||
# 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")
|
||||
|
||||
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)
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::_draw() {
|
||||
/*
|
||||
for layer in layers:
|
||||
layer.update_texture()
|
||||
|
||||
preview_layer.update_texture()
|
||||
tool_layer.update_texture()
|
||||
*/
|
||||
}
|
||||
|
||||
void PaintCanvas::resize(int width, int height) {
|
||||
/*
|
||||
if width < 0:
|
||||
width = 1
|
||||
if height < 0:
|
||||
height = 1
|
||||
|
||||
set_canvas_width(width)
|
||||
set_canvas_height(height)
|
||||
|
||||
preview_layer.resize(width, height)
|
||||
tool_layer.resize(width, height)
|
||||
for layer in layers:
|
||||
layer.resize(width, height)
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::set_pixel_size(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)
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::set_grid_size(int size) {
|
||||
/*
|
||||
grid_size = size
|
||||
if not find_node("Grid"):
|
||||
return
|
||||
find_node("Grid").size = size * pixel_size
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::set_big_grid_size(int size) {
|
||||
/*
|
||||
big_grid_size = size
|
||||
if not find_node("BigGrid"):
|
||||
return
|
||||
find_node("BigGrid").size = size * pixel_size
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::set_canvas_width(int val) {
|
||||
/*
|
||||
canvas_width = val
|
||||
rect_size.x = canvas_width * pixel_size
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::set_canvas_height(int val) {
|
||||
/*
|
||||
canvas_height = val
|
||||
rect_size.y = canvas_height * pixel_size
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::toggle_alpha_locked(String layer_name) {
|
||||
/*
|
||||
var layer = find_layer_by_name(layer_name)
|
||||
layer.toggle_alpha_locked()
|
||||
*/
|
||||
}
|
||||
bool PaintCanvas::is_alpha_locked() {
|
||||
/*
|
||||
return active_layer.alpha_locked
|
||||
*/
|
||||
}
|
||||
Rect2 PaintCanvas::get_content_margin() {
|
||||
/*
|
||||
var rect = Rect2(999999, 999999, -999999, -999999)
|
||||
|
||||
preview_layer.image.get_used_rect()
|
||||
for layer in layers:
|
||||
|
||||
var r = layer.image.get_used_rect()
|
||||
|
||||
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
|
||||
|
||||
return rect
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::crop_to_content() {
|
||||
/*
|
||||
var rect = get_content_margin()
|
||||
|
||||
#print(rect)
|
||||
|
||||
for layer in layers:
|
||||
layer.image
|
||||
|
||||
# set_canvas_width(rect.size.x)
|
||||
# set_canvas_height(rect.size.x)
|
||||
|
||||
# preview_layer.resize(width, height)
|
||||
# tool_layer.resize(width, height)
|
||||
# for layer in layers:
|
||||
# layer.resize(width, height)
|
||||
*/
|
||||
}
|
||||
Node *PaintCanvas::get_active_layer() {
|
||||
/*
|
||||
return active_layer
|
||||
*/
|
||||
}
|
||||
Node *PaintCanvas::get_preview_layer() {
|
||||
/*
|
||||
return preview_layer
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::clear_active_layer() {
|
||||
/*
|
||||
active_layer.clear()
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::clear_preview_layer() {
|
||||
/*
|
||||
preview_layer.clear()
|
||||
*/
|
||||
}
|
||||
|
||||
void PaintCanvas::clear_layer(String layer_name) {
|
||||
/*
|
||||
for layer in layers:
|
||||
if layer.name == layer_name:
|
||||
layer.clear()
|
||||
break
|
||||
*/
|
||||
}
|
||||
Node *PaintCanvas::remove_layer(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
|
||||
*/
|
||||
}
|
||||
Node *PaintCanvas::add_new_layer(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":
|
||||
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
|
||||
*/
|
||||
}
|
||||
Node *PaintCanvas::duplicate_layer(String layer_name, String new_layer_name) {
|
||||
/*
|
||||
for layer in layers:
|
||||
if layer.name == new_layer_name:
|
||||
return
|
||||
|
||||
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
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::toggle_layer_visibility(String layer_name) {
|
||||
/*
|
||||
for layer in layers:
|
||||
if layer.name == layer_name:
|
||||
layer.visible = not layer.visible
|
||||
*/
|
||||
}
|
||||
Node *PaintCanvas::find_layer_by_name(String layer_name) {
|
||||
/*
|
||||
for layer in layers:
|
||||
if layer.name == layer_name:
|
||||
return layer
|
||||
return null
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::toggle_lock_layer(String layer_name) {
|
||||
/*
|
||||
find_layer_by_name(layer_name).toggle_lock()
|
||||
*/
|
||||
}
|
||||
bool PaintCanvas::is_active_layer_locked() {
|
||||
/*
|
||||
return active_layer.locked
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::move_layer_forward(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)
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::move_layer_back(String layer_name) {
|
||||
/*
|
||||
var layer = find_layer_by_name(layer_name).texture_rect_ref
|
||||
canvas_layers.move_child(layer, layer.get_index() + 1)
|
||||
*/
|
||||
}
|
||||
|
||||
void PaintCanvas::select_layer(String layer_name) {
|
||||
/*
|
||||
active_layer = find_layer_by_name(layer_name)
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::_on_mouse_entered() {
|
||||
/*
|
||||
mouse_on_top = true
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::_on_mouse_exited() {
|
||||
/*
|
||||
mouse_on_top = false
|
||||
*/
|
||||
}
|
||||
bool PaintCanvas::is_inside_canvas(int x, int y) {
|
||||
/*
|
||||
if x < 0 or y < 0:
|
||||
return false
|
||||
if x >= canvas_width or 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(Array pixels, Color color) {
|
||||
/*
|
||||
for pixel in pixels:
|
||||
_set_pixel(active_layer, pixel.x, pixel.y, color)
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::set_pixel_v(Vector2 pos, Color color) {
|
||||
/*
|
||||
set_pixel(pos.x, pos.y, color)
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::set_pixel(int x, int y, Color color) {
|
||||
/*
|
||||
_set_pixel(active_layer, x, y, color)
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::_set_pixel_v(PaintCanvasLayer *layer, Vector2 v, Color color) {
|
||||
/*
|
||||
_set_pixel(layer, v.x, v.y, color)
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::_set_pixel(PaintCanvasLayer *layer, int x, int y, Color color) {
|
||||
/*
|
||||
if not is_inside_canvas(x, y):
|
||||
return
|
||||
layer.set_pixel(x, y, color)
|
||||
*/
|
||||
}
|
||||
Color PaintCanvas::get_pixel_v(Vector2 pos) {
|
||||
/*
|
||||
return get_pixel(pos.x, pos.y)
|
||||
*/
|
||||
}
|
||||
Color PaintCanvas::get_pixel(int x, int y) {
|
||||
/*
|
||||
if active_layer:
|
||||
return active_layer.get_pixel(x, y)
|
||||
return null
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::set_preview_pixel_v(Vector2 pos, Color color) {
|
||||
/*
|
||||
set_preview_pixel(pos.x, pos.y, color)
|
||||
*/
|
||||
}
|
||||
|
||||
void PaintCanvas::set_preview_pixel(int x, int y, Color color) {
|
||||
/*
|
||||
if not is_inside_canvas(x, y):
|
||||
return
|
||||
preview_layer.set_pixel(x, y, color)
|
||||
*/
|
||||
}
|
||||
Color PaintCanvas::get_preview_pixel_v(Vector2 pos) {
|
||||
/*
|
||||
return get_preview_pixel(pos.x, pos.y)
|
||||
*/
|
||||
}
|
||||
|
||||
Color PaintCanvas::get_preview_pixel(int x, int y) {
|
||||
/*
|
||||
if not preview_layer:
|
||||
return null
|
||||
return preview_layer.get_pixel(x, y)
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::toggle_grid() {
|
||||
/*
|
||||
$Grid.visible = not $Grid.visible
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::show_grid() {
|
||||
/*
|
||||
$Grid.show()
|
||||
*/
|
||||
}
|
||||
void PaintCanvas::hide_grid() {
|
||||
/*
|
||||
$Grid.hide()
|
||||
*/
|
||||
}
|
||||
|
||||
Array PaintCanvas::select_color(int x, 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
|
||||
*/
|
||||
}
|
||||
Array PaintCanvas::select_same_color(int x, 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(int pos_x, int pos_y) {
|
||||
/*
|
||||
var pixels = []
|
||||
|
||||
var to_check_queue = []
|
||||
var checked_queue = []
|
||||
|
||||
to_check_queue.append(GEUtils.to_1D(pos_x, pos_y, canvas_width))
|
||||
|
||||
var 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)
|
||||
|
||||
if idx in checked_queue:
|
||||
continue
|
||||
|
||||
checked_queue.append(idx)
|
||||
|
||||
if get_pixel(p.x, p.y) != color:
|
||||
continue
|
||||
|
||||
# add to result
|
||||
pixels.append(p)
|
||||
|
||||
# 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)
|
||||
|
||||
x = p.x + 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 = GEUtils.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)
|
||||
|
||||
return pixels
|
||||
*/
|
||||
}
|
||||
|
||||
PaintCanvas::PaintCanvas() {
|
||||
/*
|
||||
|
||||
export var pixel_size: int = 16 setget set_pixel_size
|
||||
export(int, 1, 2500) var canvas_width = 48 setget set_canvas_width # == pixels
|
||||
export(int, 1, 2500) var canvas_height = 28 setget set_canvas_height # == pixels
|
||||
export var grid_size = 16 setget set_grid_size
|
||||
export var big_grid_size = 10 setget set_big_grid_size
|
||||
export var can_draw = true
|
||||
|
||||
var mouse_in_region
|
||||
var mouse_on_top
|
||||
|
||||
var layers : Array = [] # Key: layer_name, val: GELayer
|
||||
var active_layer: GELayer
|
||||
var preview_layer: GELayer
|
||||
var tool_layer: GELayer
|
||||
var canvas_layers: Control
|
||||
|
||||
var canvas
|
||||
var grid
|
||||
var big_grid
|
||||
var selected_pixels = []
|
||||
|
||||
var symmetry_x = false
|
||||
var symmetry_y = false
|
||||
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
PaintCanvas::~PaintCanvas() {
|
||||
|
@ -27,15 +27,102 @@ SOFTWARE.
|
||||
|
||||
#include "scene/gui/control.h"
|
||||
|
||||
class PaintCanvasLayer;
|
||||
|
||||
//class_name GECanvas
|
||||
class PaintCanvas : public Control {
|
||||
GDCLASS(PaintCanvas, Control);
|
||||
|
||||
public:
|
||||
void _enter_tree();
|
||||
void _process(float delta);
|
||||
void _draw();
|
||||
|
||||
void resize(int width, int height);
|
||||
|
||||
void set_pixel_size(int size);
|
||||
void set_grid_size(int size);
|
||||
void set_big_grid_size(int size);
|
||||
void set_canvas_width(int val);
|
||||
void set_canvas_height(int val);
|
||||
|
||||
void toggle_alpha_locked(String layer_name);
|
||||
bool is_alpha_locked();
|
||||
|
||||
Rect2 get_content_margin();
|
||||
void crop_to_content();
|
||||
|
||||
Node *get_active_layer();
|
||||
Node *get_preview_layer();
|
||||
void clear_active_layer();
|
||||
void clear_preview_layer();
|
||||
void clear_layer(String layer_name);
|
||||
Node *remove_layer(String layer_name);
|
||||
Node *add_new_layer(String layer_name);
|
||||
Node *duplicate_layer(String layer_name, String new_layer_name);
|
||||
void toggle_layer_visibility(String layer_name);
|
||||
Node *find_layer_by_name(String layer_name);
|
||||
void toggle_lock_layer(String layer_name);
|
||||
bool is_active_layer_locked();
|
||||
void move_layer_forward(String layer_name);
|
||||
void move_layer_back(String layer_name);
|
||||
void select_layer(String layer_name);
|
||||
|
||||
void _on_mouse_entered();
|
||||
void _on_mouse_exited();
|
||||
|
||||
bool is_inside_canvas(int x, int y);
|
||||
void set_pixel_arr(Array pixels, Color color);
|
||||
void set_pixel_v(Vector2 pos, Color color);
|
||||
void set_pixel(int x, int y, Color color);
|
||||
void _set_pixel_v(PaintCanvasLayer *layer, Vector2 v, Color color);
|
||||
void _set_pixel(PaintCanvasLayer *layer, int x, int y, Color color);
|
||||
Color get_pixel_v(Vector2 pos);
|
||||
Color get_pixel(int x, int y);
|
||||
void set_preview_pixel_v(Vector2 pos, Color color);
|
||||
void set_preview_pixel(int x, int y, Color color);
|
||||
Color get_preview_pixel_v(Vector2 pos);
|
||||
Color get_preview_pixel(int x, int y);
|
||||
|
||||
void toggle_grid();
|
||||
void show_grid();
|
||||
void hide_grid();
|
||||
|
||||
Array select_color(int x, int y);
|
||||
Array select_same_color(int x, int y);
|
||||
Array get_neighbouring_pixels(int pos_x, int pos_y);
|
||||
|
||||
PaintCanvas();
|
||||
~PaintCanvas();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
/*
|
||||
export var pixel_size: int = 16 setget set_pixel_size
|
||||
export(int, 1, 2500) var canvas_width = 48 setget set_canvas_width # == pixels
|
||||
export(int, 1, 2500) var canvas_height = 28 setget set_canvas_height # == pixels
|
||||
export var grid_size = 16 setget set_grid_size
|
||||
export var big_grid_size = 10 setget set_big_grid_size
|
||||
export var can_draw = true
|
||||
|
||||
var mouse_in_region
|
||||
var mouse_on_top
|
||||
|
||||
var layers : Array = [] # Key: layer_name, val: GELayer
|
||||
var active_layer: GELayer
|
||||
var preview_layer: GELayer
|
||||
var tool_layer: GELayer
|
||||
var canvas_layers: Control
|
||||
|
||||
var canvas
|
||||
var grid
|
||||
var big_grid
|
||||
var selected_pixels = []
|
||||
|
||||
var symmetry_x = false
|
||||
var symmetry_y = false
|
||||
*/
|
||||
};
|
||||
|
||||
#endif
|
||||
|
141
modules/paint/paint_canvas_layer.cpp
Normal file
141
modules/paint/paint_canvas_layer.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_canvas_layer.h"
|
||||
|
||||
void PaintCanvasLayer::_init() {
|
||||
/*
|
||||
texture = ImageTexture.new()
|
||||
*/
|
||||
}
|
||||
void PaintCanvasLayer::create(Node *texture_rect_ref, int width, int height) {
|
||||
/*
|
||||
self.texture_rect_ref = texture_rect_ref
|
||||
|
||||
layer_width = width
|
||||
layer_height = height
|
||||
|
||||
image = Image.new()
|
||||
image.create(width, height, false, Image.FORMAT_RGBA8)
|
||||
image.fill(Color.transparent)
|
||||
update_texture()
|
||||
*/
|
||||
}
|
||||
|
||||
void PaintCanvasLayer::resize(int width, int height) {
|
||||
/*
|
||||
var pixel_colors = []
|
||||
var prev_width = layer_width
|
||||
var prev_height = layer_height
|
||||
|
||||
image.lock()
|
||||
for y in range(prev_height):
|
||||
for x in range(prev_width):
|
||||
pixel_colors.append(image.get_pixel(x, y))
|
||||
image.unlock()
|
||||
|
||||
layer_width = width
|
||||
layer_height = height
|
||||
|
||||
image.create(width, height, false, Image.FORMAT_RGBA8)
|
||||
|
||||
image.lock()
|
||||
for x in range(prev_width):
|
||||
for y in range(prev_height):
|
||||
if x >= width or y >= height:
|
||||
continue
|
||||
image.set_pixel(x, y, pixel_colors[GEUtils.to_1D(x, y, prev_width)])
|
||||
image.unlock()
|
||||
|
||||
update_texture()
|
||||
*/
|
||||
}
|
||||
void PaintCanvasLayer::set_pixel(int x, int y, Color color) {
|
||||
/*
|
||||
image.lock()
|
||||
image.set_pixel(x, y, color)
|
||||
image.unlock()
|
||||
*/
|
||||
}
|
||||
Color PaintCanvasLayer::get_pixel(int x, int y) {
|
||||
/*
|
||||
if x < 0 or y < 0 or x >= image.get_width() or y >= image.get_height():
|
||||
return null
|
||||
image.lock()
|
||||
var pixel = image.get_pixel(x, y)
|
||||
image.unlock()
|
||||
return pixel
|
||||
*/
|
||||
}
|
||||
void PaintCanvasLayer::clear() {
|
||||
/*
|
||||
image.fill(Color.transparent)
|
||||
update_texture()
|
||||
*/
|
||||
}
|
||||
void PaintCanvasLayer::update_texture() {
|
||||
/*
|
||||
texture.create_from_image(image, 0)
|
||||
texture_rect_ref.texture = texture
|
||||
texture_rect_ref.margin_right = 0
|
||||
texture_rect_ref.margin_bottom = 0
|
||||
*/
|
||||
}
|
||||
void PaintCanvasLayer::set_visible(bool vis) {
|
||||
/*
|
||||
visible = vis
|
||||
texture_rect_ref.visible = visible
|
||||
*/
|
||||
}
|
||||
void PaintCanvasLayer::toggle_lock() {
|
||||
/*
|
||||
locked = not locked
|
||||
*/
|
||||
}
|
||||
void PaintCanvasLayer::toggle_alpha_locked() {
|
||||
/*
|
||||
alpha_locked = not alpha_locked
|
||||
*/
|
||||
}
|
||||
|
||||
PaintCanvasLayer::PaintCanvasLayer() {
|
||||
/*
|
||||
var name
|
||||
var layer_width
|
||||
var layer_height
|
||||
var visible = true setget set_visible
|
||||
var locked = false
|
||||
var alpha_locked = false
|
||||
|
||||
var texture: ImageTexture
|
||||
var image: Image
|
||||
var texture_rect_ref
|
||||
*/
|
||||
}
|
||||
|
||||
PaintCanvasLayer::~PaintCanvasLayer() {
|
||||
}
|
||||
|
||||
void PaintCanvasLayer::_bind_methods() {
|
||||
}
|
69
modules/paint/paint_canvas_layer.h
Normal file
69
modules/paint/paint_canvas_layer.h
Normal file
@ -0,0 +1,69 @@
|
||||
#ifndef PAINT_CANVAS_LAYER_H
|
||||
#define PAINT_CANVAS_LAYER_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "core/reference.h"
|
||||
|
||||
class Node;
|
||||
|
||||
//class_name GELayer
|
||||
class PaintCanvasLayer : public Reference {
|
||||
GDCLASS(PaintCanvasLayer, Reference);
|
||||
|
||||
public:
|
||||
void _init();
|
||||
void create(Node *texture_rect_ref, int width, int height);
|
||||
|
||||
void resize(int width, int height);
|
||||
void set_pixel(int x, int y, Color color);
|
||||
Color get_pixel(int x, int y);
|
||||
void clear();
|
||||
void update_texture();
|
||||
void set_visible(bool vis);
|
||||
void toggle_lock();
|
||||
void toggle_alpha_locked();
|
||||
|
||||
PaintCanvasLayer();
|
||||
~PaintCanvasLayer();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
/*
|
||||
var name
|
||||
var layer_width
|
||||
var layer_height
|
||||
var visible = true setget set_visible
|
||||
var locked = false
|
||||
var alpha_locked = false
|
||||
|
||||
var texture: ImageTexture
|
||||
var image: Image
|
||||
var texture_rect_ref
|
||||
*/
|
||||
};
|
||||
|
||||
#endif
|
@ -24,6 +24,36 @@ SOFTWARE.
|
||||
|
||||
#include "paint_color_grid.h"
|
||||
|
||||
void PaintColorGrid::_enter_tree() {
|
||||
/*
|
||||
for child in get_children():
|
||||
child.set("custom_styles/normal", StyleBoxFlat.new())
|
||||
child.get("custom_styles/normal").set("bg_color", Color(randf(), randf(), randf()))
|
||||
for child in get_children():
|
||||
if child.is_connected("pressed", self, "change_color_to"):
|
||||
return
|
||||
child.connect("pressed", self, "change_color_to", [child.get("custom_styles/normal").bg_color])
|
||||
*/
|
||||
}
|
||||
void PaintColorGrid::change_color_to(Color color) {
|
||||
/*
|
||||
emit_signal("color_change_request", color)
|
||||
*/
|
||||
}
|
||||
void PaintColorGrid::add_color_prefab(Color color) {
|
||||
/*
|
||||
var dup = get_child(0).duplicate()
|
||||
add_child(dup)
|
||||
move_child(dup, 0)
|
||||
dup.set("custom_styles/normal", StyleBoxFlat.new())
|
||||
dup.get("custom_styles/normal").set("bg_color", color)
|
||||
for child in get_children():
|
||||
if child.is_connected("pressed", self, "change_color_to"):
|
||||
return
|
||||
child.connect("pressed", self, "change_color_to", [child.get("custom_styles/normal").bg_color])
|
||||
*/
|
||||
}
|
||||
|
||||
PaintColorGrid::PaintColorGrid() {
|
||||
}
|
||||
|
||||
@ -31,4 +61,5 @@ PaintColorGrid::~PaintColorGrid() {
|
||||
}
|
||||
|
||||
void PaintColorGrid::_bind_methods() {
|
||||
//signal color_change_request
|
||||
}
|
||||
|
@ -25,12 +25,16 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/gui/grid_container.h"
|
||||
|
||||
class PaintColorGrid : public Control {
|
||||
GDCLASS(PaintColorGrid, Control);
|
||||
class PaintColorGrid : public GridContainer {
|
||||
GDCLASS(PaintColorGrid, GridContainer);
|
||||
|
||||
public:
|
||||
void _enter_tree();
|
||||
void change_color_to(Color color);
|
||||
void add_color_prefab(Color color);
|
||||
|
||||
PaintColorGrid();
|
||||
~PaintColorGrid();
|
||||
|
||||
|
@ -1,3 +1,31 @@
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_layer_button.h"
|
||||
|
||||
PaintLayerButton::PaintLayerButton() {
|
||||
/*
|
||||
[gd_scene load_steps=11 format=2]
|
||||
|
||||
[ext_resource path="res://addons/Godoxel/assets/minidotta_invis.png" type="Texture" id=1]
|
||||
@ -108,3 +136,13 @@ texture_normal = ExtResource( 3 )
|
||||
texture_pressed = ExtResource( 2 )
|
||||
expand = true
|
||||
stretch_mode = 3
|
||||
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
PaintLayerButton::~PaintLayerButton() {
|
||||
}
|
||||
|
||||
void PaintLayerButton::_bind_methods() {
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
#ifndef PAINT_IMAGE_LAYER_H
|
||||
#define PAINT_IMAGE_LAYER_H
|
||||
#ifndef PAINT_LAYER_BUTTON_H
|
||||
#define PAINT_LAYER_BUTTON_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
@ -25,14 +25,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/gui/panel_container.h"
|
||||
|
||||
class PaintImageLayer : public Control {
|
||||
GDCLASS(PaintImageLayer, Control);
|
||||
class PaintLayerButton : public PanelContainer {
|
||||
GDCLASS(PaintLayerButton, PanelContainer);
|
||||
|
||||
public:
|
||||
PaintImageLayer();
|
||||
~PaintImageLayer();
|
||||
PaintLayerButton();
|
||||
~PaintLayerButton();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
@ -24,6 +24,135 @@ SOFTWARE.
|
||||
|
||||
#include "paint_navbar.h"
|
||||
|
||||
/*
|
||||
tool
|
||||
extends MenuButton
|
||||
|
||||
var popup = get_popup()
|
||||
signal item_pressed
|
||||
|
||||
func _ready():
|
||||
popup.connect("id_pressed", self, "id_pressed")
|
||||
|
||||
func id_pressed(id):
|
||||
emit_signal("item_pressed", name, popup.get_item_text(id), id)
|
||||
|
||||
*/
|
||||
|
||||
void PaintNavbar::_ready() {
|
||||
/*
|
||||
editor = owner
|
||||
paint_canvas = editor.find_node("PaintCanvas")
|
||||
|
||||
for i in get_node("Buttons").get_children():
|
||||
i.connect("item_pressed", self, "button_pressed")
|
||||
*/
|
||||
}
|
||||
void PaintNavbar::button_pressed(String button_name, Node *button_item, int id) {
|
||||
/*
|
||||
# print("pressed: ", button_name)
|
||||
# print("pressed item is: '%s'" % button_item)
|
||||
|
||||
match button_name:
|
||||
"File":
|
||||
handle_file_menu(button_item, id)
|
||||
"Edit":
|
||||
handle_edit_menu(button_item, id)
|
||||
"Canvas":
|
||||
handle_canvas_menu(button_item, id)
|
||||
"Layer":
|
||||
handle_layer_menu(button_item, id)
|
||||
"Grid":
|
||||
handle_grid_menu(button_item, id)
|
||||
"Magic":
|
||||
handle_magic_menu(button_item, id)
|
||||
"Editor":
|
||||
handle_editor_menu(button_item, id)
|
||||
*/
|
||||
}
|
||||
|
||||
void PaintNavbar::handle_file_menu(String pressed_item, int id) {
|
||||
/*
|
||||
match pressed_item:
|
||||
"Save":
|
||||
owner.get_node("SaveFileDialog").show()
|
||||
"Load":
|
||||
owner.get_node("LoadFileDialog").show()
|
||||
"New":
|
||||
owner.get_node("ConfirmationDialog").show()
|
||||
*/
|
||||
}
|
||||
void PaintNavbar::handle_edit_menu(String pressed_item, int id) {
|
||||
/*
|
||||
match pressed_item:
|
||||
"Add Layer":
|
||||
editor.add_new_layer()
|
||||
*/
|
||||
}
|
||||
void PaintNavbar::handle_canvas_menu(String pressed_item, int id) {
|
||||
/*
|
||||
match pressed_item:
|
||||
"Change Size":
|
||||
owner.get_node("ChangeCanvasSize").show()
|
||||
"Crop To Content":
|
||||
owner.paint_canvas.crop_to_content()
|
||||
*/
|
||||
}
|
||||
void PaintNavbar::handle_layer_menu(String pressed_item, int id) {
|
||||
/*
|
||||
match pressed_item:
|
||||
"Add Layer":
|
||||
editor.add_new_layer()
|
||||
"Delete Layer":
|
||||
editor.remove_active_layer()
|
||||
"Duplicate Layer":
|
||||
editor.duplicate_active_layer()
|
||||
"Clear Layer":
|
||||
owner.paint_canvas.clear_active_layer()
|
||||
"Toggle Alpha Locked":
|
||||
owner.paint_canvas.active_layer.toggle_alpha_locked()
|
||||
$Buttons/Layer.get_popup().set_item_checked(id, not $Buttons/Layer.get_popup().is_item_checked(id))
|
||||
owner.find_node("LockAlpha").pressed = $Buttons/Layer.get_popup().is_item_checked(id)
|
||||
*/
|
||||
}
|
||||
void PaintNavbar::handle_grid_menu(String pressed_item, int id) {
|
||||
/*
|
||||
match pressed_item:
|
||||
"Change Grid Size":
|
||||
owner.get_node("ChangeGridSizeDialog").show()
|
||||
"Toggle Grid":
|
||||
owner.paint_canvas.toggle_grid()
|
||||
*/
|
||||
}
|
||||
|
||||
void PaintNavbar::handle_magic_menu(String pressed_item, int id) {
|
||||
/*
|
||||
match pressed_item:
|
||||
"Add Layer":
|
||||
editor.add_new_layer()
|
||||
*/
|
||||
}
|
||||
void PaintNavbar::handle_editor_menu(String pressed_item, int id) {
|
||||
/*
|
||||
match pressed_item:
|
||||
"Settings":
|
||||
owner.get_node("Settings").show()
|
||||
"Toggle Grid":
|
||||
var grids_node = owner.find_node("Grids")
|
||||
grids_node.visible = !grids_node.visible
|
||||
"Reset Canvas Position":
|
||||
owner.paint_canvas_node.rect_position = Vector2(0, 0)
|
||||
*/
|
||||
}
|
||||
bool PaintNavbar::is_any_menu_open() {
|
||||
/*
|
||||
for child in $Buttons.get_children():
|
||||
if child.get_popup().visible:
|
||||
return true
|
||||
return false
|
||||
*/
|
||||
}
|
||||
|
||||
PaintNavbar::PaintNavbar() {
|
||||
}
|
||||
|
||||
|
@ -31,11 +31,29 @@ class PaintNavbar : public Control {
|
||||
GDCLASS(PaintNavbar, Control);
|
||||
|
||||
public:
|
||||
void _ready();
|
||||
void button_pressed(String button_name, Node *button_item, int id);
|
||||
|
||||
void handle_file_menu(String pressed_item, int id);
|
||||
void handle_edit_menu(String pressed_item, int id);
|
||||
void handle_canvas_menu(String pressed_item, int id);
|
||||
void handle_layer_menu(String pressed_item, int id);
|
||||
void handle_grid_menu(String pressed_item, int id);
|
||||
|
||||
void handle_magic_menu(String pressed_item, int id);
|
||||
void handle_editor_menu(String pressed_item, int id);
|
||||
bool is_any_menu_open();
|
||||
|
||||
PaintNavbar();
|
||||
~PaintNavbar();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
/*
|
||||
var editor
|
||||
var paint_canvas
|
||||
*/
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -24,7 +24,32 @@ SOFTWARE.
|
||||
|
||||
#include "paint_selection_box.h"
|
||||
|
||||
void PaintSelectionBox::_process(float delta) {
|
||||
/*
|
||||
update()
|
||||
*/
|
||||
}
|
||||
void PaintSelectionBox::_draw() {
|
||||
/*
|
||||
if not rect_size == Vector2():
|
||||
draw_outline_box(rect_size, Color.gray, outline_size)
|
||||
*/
|
||||
}
|
||||
void PaintSelectionBox::draw_outline_box(Vector2 size, Color color, int width) {
|
||||
/*
|
||||
#Top line
|
||||
draw_line(Vector2(0 + 1, 0), Vector2(size.x, 0), color, width)
|
||||
#Left line
|
||||
draw_line(Vector2(0 + 1, 0), Vector2(0, size.y), color, width)
|
||||
#Bottom line
|
||||
draw_line(Vector2(0 + 1, size.y), Vector2(size.x, size.y), color, width)
|
||||
#Right line
|
||||
draw_line(Vector2(size.x, 0), Vector2(size.x, size.y), color, width)
|
||||
*/
|
||||
}
|
||||
|
||||
PaintSelectionBox::PaintSelectionBox() {
|
||||
////export var outline_size = 3
|
||||
}
|
||||
|
||||
PaintSelectionBox::~PaintSelectionBox() {
|
||||
|
@ -31,11 +31,17 @@ class PaintSelectionBox : public Control {
|
||||
GDCLASS(PaintSelectionBox, Control);
|
||||
|
||||
public:
|
||||
void _process(float delta);
|
||||
void _draw();
|
||||
void draw_outline_box(Vector2 size, Color color, int width);
|
||||
|
||||
PaintSelectionBox();
|
||||
~PaintSelectionBox();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
//export var outline_size = 3
|
||||
};
|
||||
|
||||
#endif
|
||||
|
125
modules/paint/paint_settings.cpp
Normal file
125
modules/paint/paint_settings.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "paint_settings.h"
|
||||
|
||||
void PaintTextInfo::_enter_tree() {
|
||||
/*
|
||||
canvas_outline = get_parent().find_node("CanvasOutline")
|
||||
editor = get_parent()
|
||||
*/
|
||||
}
|
||||
void PaintTextInfo::_on_ColorPickerButton_color_changed(Color color) {
|
||||
/*
|
||||
canvas_outline.color = color
|
||||
*/
|
||||
}
|
||||
void PaintTextInfo::_on_CheckButton_toggled(bool button_pressed) {
|
||||
/*
|
||||
canvas_outline.visible = button_pressed
|
||||
*/
|
||||
}
|
||||
void PaintTextInfo::_on_Ok_pressed() {
|
||||
/*
|
||||
hide()
|
||||
*/
|
||||
}
|
||||
|
||||
PaintTextInfo::PaintTextInfo() {
|
||||
/*
|
||||
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://addons/Godoxel/Settings.gd" type="Script" id=1]
|
||||
|
||||
|
||||
[node name="Settings" type="WindowDialog"]
|
||||
visible = true
|
||||
margin_top = 20.0
|
||||
margin_right = 300.0
|
||||
margin_bottom = 120.0
|
||||
window_title = "Settings"
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Ok" type="Button" parent="."]
|
||||
margin_left = 210.0
|
||||
margin_top = 70.0
|
||||
margin_right = 290.0
|
||||
margin_bottom = 90.0
|
||||
text = "Ok"
|
||||
|
||||
[node name="CanvasOutlineToggle" type="Control" parent="."]
|
||||
margin_left = 10.0
|
||||
margin_top = 10.0
|
||||
margin_right = 290.0
|
||||
margin_bottom = 30.0
|
||||
__meta__ = {
|
||||
"_edit_group_": true
|
||||
}
|
||||
|
||||
[node name="Label" type="Label" parent="CanvasOutlineToggle"]
|
||||
margin_right = 130.0
|
||||
margin_bottom = 20.0
|
||||
text = "Canvas Outline:"
|
||||
valign = 1
|
||||
|
||||
[node name="CheckButton" type="CheckButton" parent="CanvasOutlineToggle"]
|
||||
margin_left = 210.0
|
||||
margin_top = -10.0
|
||||
margin_right = 286.0
|
||||
margin_bottom = 30.0
|
||||
pressed = true
|
||||
|
||||
[node name="CanvasOutlineColor" type="Control" parent="."]
|
||||
margin_left = 10.0
|
||||
margin_top = 40.0
|
||||
margin_right = 290.0
|
||||
margin_bottom = 60.0
|
||||
__meta__ = {
|
||||
"_edit_group_": true
|
||||
}
|
||||
|
||||
[node name="Label" type="Label" parent="CanvasOutlineColor"]
|
||||
margin_right = 130.0
|
||||
margin_bottom = 20.0
|
||||
text = "Canvas Outline Color:"
|
||||
valign = 1
|
||||
|
||||
[node name="ColorPickerButton" type="ColorPickerButton" parent="CanvasOutlineColor"]
|
||||
margin_left = 170.0
|
||||
margin_right = 280.0
|
||||
margin_bottom = 20.0
|
||||
[connection signal="pressed" from="Ok" to="." method="_on_Ok_pressed"]
|
||||
[connection signal="toggled" from="CanvasOutlineToggle/CheckButton" to="." method="_on_CheckButton_toggled"]
|
||||
[connection signal="color_changed" from="CanvasOutlineColor/ColorPickerButton" to="." method="_on_ColorPickerButton_color_changed"]
|
||||
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
PaintTextInfo::~PaintTextInfo() {
|
||||
}
|
||||
|
||||
void PaintTextInfo::_bind_methods() {
|
||||
}
|
55
modules/paint/paint_settings.h
Normal file
55
modules/paint/paint_settings.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef PAINT_SETTINGS_H
|
||||
#define PAINT_SETTINGS_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 Flairieve
|
||||
Copyright (c) 2020-2022 cobrapitz
|
||||
Copyright (c) 2022 Péter Magyar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "scene/gui/control.h"
|
||||
|
||||
class PaintTextInfo : public Control {
|
||||
GDCLASS(PaintTextInfo, Control);
|
||||
|
||||
public:
|
||||
void _enter_tree();
|
||||
void _on_ColorPickerButton_color_changed(Color color);
|
||||
void _on_CheckButton_toggled(bool button_pressed);
|
||||
void _on_Ok_pressed();
|
||||
|
||||
PaintTextInfo();
|
||||
~PaintTextInfo();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
/*
|
||||
|
||||
var editor
|
||||
var canvas_outline
|
||||
var start_time
|
||||
var end_time
|
||||
|
||||
*/
|
||||
};
|
||||
|
||||
#endif
|
@ -24,7 +24,48 @@ SOFTWARE.
|
||||
|
||||
#include "paint_text_info.h"
|
||||
|
||||
//TODO: To make reading the text easier, the text info with the longest text should have it's length applied to all the
|
||||
//the other text infos
|
||||
|
||||
void PaintTextInfo::add_text_info(String text_name, Node *custom_node) {
|
||||
/*
|
||||
var last_text_info_child = null
|
||||
var child_count = get_child_count()
|
||||
if not child_count <= 0:
|
||||
last_text_info_child = get_children()[get_children().size() - 1]
|
||||
var label = Label.new()
|
||||
label.name = text_name
|
||||
label.rect_size = Vector2(size, 14)
|
||||
if not last_text_info_child == null:
|
||||
var x = last_text_info_child.rect_position.x
|
||||
var y = last_text_info_child.rect_position.y
|
||||
var temp_size = size
|
||||
if child_count == 4:
|
||||
x = 0
|
||||
y = 20
|
||||
temp_size = 0
|
||||
label.rect_position = Vector2(x + temp_size, y)
|
||||
if not custom_node == null:
|
||||
label.add_child(custom_node)
|
||||
add_child(label)
|
||||
*/
|
||||
}
|
||||
void PaintTextInfo::update_text_info(String text_name, Node *text_value, Node *node, Node *node_target_value, Node *node_value) {
|
||||
/*
|
||||
var text_label = self.get_node(text_name)
|
||||
if text_label == null:
|
||||
return
|
||||
if not node == null:
|
||||
get_node(text_name).get_node(node).set(node_target_value, node_value)
|
||||
if text_value == null:
|
||||
text_label.text = "%s: %s" % [text_name, null]
|
||||
else:
|
||||
text_label.text = "%s: %s" % [text_name, String(text_value)]
|
||||
*/
|
||||
}
|
||||
|
||||
PaintTextInfo::PaintTextInfo() {
|
||||
//var size = 240
|
||||
}
|
||||
|
||||
PaintTextInfo::~PaintTextInfo() {
|
||||
|
@ -31,11 +31,16 @@ class PaintTextInfo : public Control {
|
||||
GDCLASS(PaintTextInfo, Control);
|
||||
|
||||
public:
|
||||
void add_text_info(String text_name, Node *custom_node = nullptr);
|
||||
void update_text_info(String text_name, Node *text_value = nullptr, Node *node = nullptr, Node *node_target_value = nullptr, Node *node_value = nullptr);
|
||||
|
||||
PaintTextInfo();
|
||||
~PaintTextInfo();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
//var size = 240
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -24,6 +24,114 @@ SOFTWARE.
|
||||
|
||||
#include "paint_utilities.h"
|
||||
|
||||
Array PaintUtilities::PaintUtilities::get_pixels_in_line(Vector2 from, Vector2 to) {
|
||||
/*
|
||||
var dx = to[0] - from[0]
|
||||
var dy = to[1] - from[1]
|
||||
var nx = abs(dx)
|
||||
var ny = abs(dy)
|
||||
var signX = sign(dx)
|
||||
var signY = sign(dy)
|
||||
var p = from
|
||||
var points : Array = [p]
|
||||
|
||||
var ix = 0
|
||||
var iy = 0
|
||||
|
||||
while ix < nx || iy < ny:
|
||||
if (1 + (ix << 1)) * ny < (1 + (iy << 1)) * nx:
|
||||
p[0] += signX
|
||||
ix +=1
|
||||
else:
|
||||
p[1] += signY
|
||||
iy += 1
|
||||
points.append(p)
|
||||
return points
|
||||
*/
|
||||
}
|
||||
|
||||
int to_1D_v(Vector2 p, float w) {
|
||||
/*
|
||||
return p.x + p.y * w
|
||||
*/
|
||||
}
|
||||
int PaintUtilities::to_1D(float x, float y, float w) {
|
||||
/*
|
||||
return x + y * w
|
||||
*/
|
||||
}
|
||||
Vector2 PaintUtilities::to_2D(int idx, float w) {
|
||||
/*
|
||||
var p = Vector2()
|
||||
p.x = int(idx) % int(w)
|
||||
p.y = int(idx / w)
|
||||
return p
|
||||
*/
|
||||
}
|
||||
|
||||
Color PaintUtilities::color_from_array(PoolRealArray color_array) {
|
||||
/*
|
||||
var r = color_array[0]
|
||||
var g = color_array[1]
|
||||
var b = color_array[2]
|
||||
var a = color_array[3]
|
||||
return Color(r, g, b, a)
|
||||
*/
|
||||
}
|
||||
Color PaintUtilities::random_color() {
|
||||
/*
|
||||
return Color(randf(), randf(), randf())
|
||||
*/
|
||||
}
|
||||
Color PaintUtilities::random_color_alt() {
|
||||
/*
|
||||
var rand = randi() % 6
|
||||
|
||||
match rand:
|
||||
#red
|
||||
0:
|
||||
return Color.red
|
||||
#blue
|
||||
1:
|
||||
return Color.blue
|
||||
#green
|
||||
2:
|
||||
return Color.green
|
||||
#orange
|
||||
3:
|
||||
return Color.orange
|
||||
#yellow
|
||||
4:
|
||||
return Color.yellow
|
||||
#purple
|
||||
5:
|
||||
return Color.purple
|
||||
*/
|
||||
}
|
||||
|
||||
String PaintUtilities::get_line_string(String file, int number) {
|
||||
/*
|
||||
return file.get_as_text().split("\n")[number - 1].strip_edges()
|
||||
*/
|
||||
}
|
||||
|
||||
void PaintUtilities::printv(Variant variable) {
|
||||
/*
|
||||
var stack = get_stack()[get_stack().size() - 1]
|
||||
var line = stack.line
|
||||
var source = stack.source
|
||||
var file = File.new()
|
||||
file.open(source, File.READ)
|
||||
var line_string = get_line_string(file, line)
|
||||
file.close()
|
||||
var left_p = line_string.find("(")
|
||||
var left_p_string = line_string.right(left_p + 1)
|
||||
var right_p = left_p_string.find(")")
|
||||
var variable_name = left_p_string.left(right_p)
|
||||
print("%s: %s" % [variable_name, variable])
|
||||
*/
|
||||
}
|
||||
|
||||
PaintUtilities::PaintUtilities() {
|
||||
}
|
||||
|
||||
|
@ -25,12 +25,30 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "scene/gui/control.h"
|
||||
#include "core/object.h"
|
||||
|
||||
class PaintUtilities : public Control {
|
||||
GDCLASS(PaintUtilities, Control);
|
||||
#include "core/pool_vector.h"
|
||||
#include "core/variant.h"
|
||||
|
||||
//class_name GEUtils
|
||||
class PaintUtilities : public Object {
|
||||
GDCLASS(PaintUtilities, Object);
|
||||
|
||||
public:
|
||||
static Array get_pixels_in_line(Vector2 from, Vector2 to);
|
||||
|
||||
static int to_1D_v(Vector2 p, float w);
|
||||
static int to_1D(float x, float y, float w);
|
||||
static Vector2 to_2D(int idx, float w);
|
||||
|
||||
static Color color_from_array(PoolRealArray color_array);
|
||||
static Color random_color();
|
||||
static Color random_color_alt();
|
||||
|
||||
static String get_line_string(String file, int number);
|
||||
|
||||
static void printv(Variant variable);
|
||||
|
||||
PaintUtilities();
|
||||
~PaintUtilities();
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -27,15 +27,192 @@ SOFTWARE.
|
||||
|
||||
#include "scene/gui/control.h"
|
||||
|
||||
#include "core/os/keyboard.h"
|
||||
#include "core/reference.h"
|
||||
|
||||
class PaintAction;
|
||||
class PaintCanvasLayer;
|
||||
class InputEvent;
|
||||
|
||||
class PaintWindow : public Control {
|
||||
GDCLASS(PaintWindow, Control);
|
||||
|
||||
public:
|
||||
enum Tools {
|
||||
PAINT = 0,
|
||||
BRUSH,
|
||||
BUCKET,
|
||||
RAINBOW,
|
||||
LINE,
|
||||
RECT,
|
||||
DARKEN,
|
||||
BRIGHTEN,
|
||||
COLORPICKER,
|
||||
CUT,
|
||||
PASTECUT,
|
||||
};
|
||||
|
||||
enum KeyboardShortcuts {
|
||||
K_UNDO = KEY_Z,
|
||||
K_REDO = KEY_Y,
|
||||
K_PENCIL = KEY_Q,
|
||||
K_BRUSH = KEY_W,
|
||||
K_BUCKET = KEY_F,
|
||||
K_RAINBOW = KEY_R,
|
||||
K_LINE = KEY_L,
|
||||
K_DARK = KEY_D,
|
||||
K_BRIGHT = KEY_B,
|
||||
K_CUT = KEY_C,
|
||||
K_PICK = KEY_P,
|
||||
};
|
||||
|
||||
enum {
|
||||
max_zoom_out = 1,
|
||||
max_zoom_in = 50,
|
||||
};
|
||||
|
||||
void _input(Ref<InputEvent> event);
|
||||
void _process(float delta);
|
||||
|
||||
void _handle_shortcuts(int scancode);
|
||||
void _draw_tool_brush();
|
||||
|
||||
void _handle_scroll();
|
||||
|
||||
void _handle_zoom(Ref<InputEvent> event);
|
||||
|
||||
void _handle_cut();
|
||||
void brush_process();
|
||||
void update_text_info();
|
||||
|
||||
void _on_Save_pressed();
|
||||
|
||||
void do_action(Array data);
|
||||
void commit_action();
|
||||
void redo_action();
|
||||
void undo_action();
|
||||
|
||||
Ref<PaintAction> get_action();
|
||||
|
||||
void set_selected_color(Color color);
|
||||
void set_brush(Tools new_mode);
|
||||
|
||||
void change_color(Color new_color);
|
||||
|
||||
void _on_ColorPicker_color_changed(Color color);
|
||||
void _on_PaintTool_pressed();
|
||||
void _on_BucketTool_pressed();
|
||||
void _on_RainbowTool_pressed();
|
||||
void _on_BrushTool_pressed();
|
||||
void _on_LineTool_pressed();
|
||||
void _on_RectTool_pressed();
|
||||
void _on_DarkenTool_pressed();
|
||||
void _on_BrightenTool_pressed();
|
||||
void _on_ColorPickerTool_pressed();
|
||||
void _on_CutTool_pressed();
|
||||
void _on_Editor_visibility_changed();
|
||||
|
||||
void highlight_layer(String layer_name);
|
||||
void toggle_layer_visibility(Node *button, String layer_name);
|
||||
void select_layer(String layer_name);
|
||||
void lock_layer(Node *button, String layer_name);
|
||||
|
||||
Ref<PaintCanvasLayer> add_new_layer();
|
||||
void remove_active_layer();
|
||||
void duplicate_active_layer();
|
||||
|
||||
void move_up(Node *layer_btn);
|
||||
void move_down(Node *layer_btn);
|
||||
|
||||
void _connect_layer_buttons();
|
||||
|
||||
void _on_Button_pressed();
|
||||
void _on_PaintCanvasContainer_mouse_entered();
|
||||
void _on_PaintCanvasContainer_mouse_exited();
|
||||
void _on_ColorPicker_popup_closed();
|
||||
|
||||
bool is_position_in_canvas(Vector2 pos);
|
||||
|
||||
bool is_mouse_in_canvas();
|
||||
|
||||
bool is_any_menu_open();
|
||||
|
||||
void _on_LockAlpha_pressed();
|
||||
void _on_BrushRect_pressed();
|
||||
void _on_BrushCircle_pressed();
|
||||
void _on_BrushVLine_pressed();
|
||||
void _on_BrushHLine_pressed();
|
||||
void _on_BrushSize_value_changed(float value);
|
||||
void _on_XSymmetry_pressed();
|
||||
void _on_YSymmetry_pressed();
|
||||
|
||||
PaintWindow();
|
||||
~PaintWindow();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
/*
|
||||
|
||||
var layer_buttons: Control
|
||||
var paint_canvas_container_node
|
||||
var paint_canvas: GECanvas
|
||||
var canvas_background: TextureRect
|
||||
var grids_node
|
||||
var colors_grid
|
||||
var selected_color = Color(1, 1, 1, 1) setget set_selected_color
|
||||
var util = preload("res://addons/Godoxel/Util.gd")
|
||||
var textinfo
|
||||
var allow_drawing = true
|
||||
|
||||
var mouse_in_region = false
|
||||
var mouse_on_top = false
|
||||
|
||||
var _middle_mouse_pressed_pos = null
|
||||
var _middle_mouse_pressed_start_pos = null
|
||||
var _left_mouse_pressed_start_pos = Vector2()
|
||||
var _previous_tool
|
||||
var brush_mode
|
||||
|
||||
var _layer_button_ref = {}
|
||||
|
||||
var _total_added_layers = 1
|
||||
|
||||
var selected_brush_prefab = 0
|
||||
var _last_drawn_pixel = Vector2.ZERO
|
||||
var _last_preview_draw_cell_pos = Vector2.ZERO
|
||||
|
||||
var _selection_cells = []
|
||||
var _selection_colors = []
|
||||
|
||||
var _cut_pos = Vector2.ZERO
|
||||
var _cut_size = Vector2.ZERO
|
||||
|
||||
var _actions_history = [] # for undo
|
||||
var _redo_history = []
|
||||
var _current_action
|
||||
|
||||
var _last_mouse_pos_canvas_area = Vector2.ZERO
|
||||
|
||||
var _picked_color = false
|
||||
|
||||
var mouse_position = Vector2()
|
||||
var canvas_position = Vector2()
|
||||
var canvas_mouse_position = Vector2()
|
||||
var cell_mouse_position = Vector2()
|
||||
var cell_color = Color()
|
||||
|
||||
var last_mouse_position = Vector2()
|
||||
var last_canvas_position = Vector2()
|
||||
var last_canvas_mouse_position = Vector2()
|
||||
var last_cell_mouse_position = Vector2()
|
||||
var last_cell_color = Color()
|
||||
|
||||
const current_layer_highlight = Color(0.354706, 0.497302, 0.769531)
|
||||
const other_layer_highlight = Color(0.180392, 0.176471, 0.176471)
|
||||
const locked_layer_highlight = Color(0.098039, 0.094118, 0.094118)
|
||||
|
||||
var big_grid_pixels = 4 // 1 grid-box is big_grid_pixels big
|
||||
*/
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +0,0 @@
|
||||
[plugin]
|
||||
|
||||
name="Godoxel - Pixel Image Editor"
|
||||
description=""
|
||||
author=""
|
||||
version=""
|
||||
script="plugin.gd"
|
@ -1,37 +0,0 @@
|
||||
tool
|
||||
extends EditorPlugin
|
||||
|
||||
var editor_scene = load("res://addons/Godoxel/Editor.tscn").instance()
|
||||
|
||||
func _enter_tree():
|
||||
editor_scene.name = "Editor"
|
||||
if get_editor_interface().get_editor_viewport().has_node("Editor"):
|
||||
var n = get_editor_interface().get_editor_viewport().get_node("Editor")
|
||||
n.name = "EditorDel"
|
||||
n.queue_free()
|
||||
get_editor_interface().get_editor_viewport().add_child(editor_scene, true)
|
||||
editor_scene.owner = get_editor_interface().get_editor_viewport()
|
||||
make_visible(false)
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
if editor_scene:
|
||||
editor_scene.queue_free()
|
||||
|
||||
|
||||
func has_main_screen():
|
||||
return true
|
||||
|
||||
|
||||
func make_visible(visible):
|
||||
if editor_scene:
|
||||
editor_scene.visible = visible
|
||||
|
||||
|
||||
func get_plugin_name():
|
||||
return "Paint"
|
||||
|
||||
|
||||
func get_plugin_icon():
|
||||
# Must return some kind of Texture for the icon.
|
||||
return get_editor_interface().get_base_control().get_icon("CanvasModulate", "EditorIcons")
|
Loading…
Reference in New Issue
Block a user