Created the rest of the skeleton classes for the paint module, and moved the code into them.

This commit is contained in:
Relintai 2022-04-15 19:40:12 +02:00
parent a662e12c3c
commit e70fb4a67e
98 changed files with 5338 additions and 4675 deletions

View File

@ -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

View File

@ -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])

View File

@ -1,9 +0,0 @@
extends RichTextLabel
tool
func _ready():
pass
func display_text(text):
self.text = text

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -1,2 +0,0 @@
tool
extends Control

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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"]

View File

@ -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)]

View File

@ -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])

View File

@ -1,6 +0,0 @@
extends ViewportContainer
tool
func _ready():
get_child(0).size = rect_size

View File

@ -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])

View File

@ -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])

View File

@ -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])

View File

@ -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])

View File

@ -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])

View File

@ -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])

View File

@ -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])

View File

@ -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])

View File

@ -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])

View 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() {
}

View 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

View 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() {
}

View File

@ -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

View 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() {
}

View File

@ -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

View File

@ -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() {
}

View 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

View 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() {
}

View 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

View 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() {
}

View 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

View 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() {
}

View 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

View File

@ -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() {
}

View 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

View 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() {
}

View 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

View 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() {
}

View 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

View 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() {
}

View 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

View File

@ -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() {
}

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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() {
}

View File

@ -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

View File

@ -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() {

View File

@ -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

View 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() {
}

View 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

View File

@ -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
}

View File

@ -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();

View File

@ -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() {
}

View File

@ -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();

View File

@ -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() {
}

View File

@ -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

View File

@ -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() {

View File

@ -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

View 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() {
}

View 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

View File

@ -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() {

View File

@ -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

View File

@ -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() {
}

View File

@ -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

View File

@ -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

View File

@ -1,7 +0,0 @@
[plugin]
name="Godoxel - Pixel Image Editor"
description=""
author=""
version=""
script="plugin.gd"

View File

@ -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")