simple composable grid context and grid controller, fiend sprite, godotxel addon

This commit is contained in:
veclav talica
2023-11-24 04:02:18 +05:00
commit 9441aa63cb
180 changed files with 9040 additions and 0 deletions

View File

@ -0,0 +1,123 @@
extends Node
class_name GEAction
var action_data = {}
func _init():
action_data["redo"] = {}
action_data["undo"] = {}
action_data["preview"] = {}
func do_action(canvas, data: Array):
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):
print("NO IMPL commit_action ")
return []
func undo_action(canvas):
print("NO IMPL undo_action ")
func redo_action(canvas):
print("NO IMPL redo_action ")
func can_commit() -> bool:
return not action_data.redo.empty()
func get_x_sym_points(canvas_width, 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):
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):
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):
var points = []
if canvas.symmetry_x and canvas.symmetry_y:
var sym_points = get_xy_sym_points(canvas.canvas_width, canvas.canvas_height, pixel)
for point in sym_points:
if point in action_data.undo.cells or canvas.get_pixel_v(point) == null:
continue
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
continue
points.append(point)
elif canvas.symmetry_y:
var sym_points = get_y_sym_points(canvas.canvas_height, pixel)
for point in sym_points:
if point in action_data.undo.cells or canvas.get_pixel_v(point) == null:
continue
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
continue
points.append(point)
elif canvas.symmetry_x:
var sym_points = get_x_sym_points(canvas.canvas_width, pixel)
for point in sym_points:
if point in action_data.undo.cells or canvas.get_pixel_v(point) == null:
continue
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
continue
points.append(point)
else:
if pixel in action_data.undo.cells or canvas.get_pixel_v(pixel) == null:
return []
if canvas.is_alpha_locked() and canvas.get_pixel_v(pixel) == Color.transparent:
return []
points.append(pixel)
return points

View File

@ -0,0 +1,53 @@
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

@ -0,0 +1,47 @@
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

@ -0,0 +1,49 @@
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

@ -0,0 +1,82 @@
extends GEAction
class_name GECut
const selection_color = Color(0.8, 0.8, 0.8, 0.5)
var mouse_start_pos = null
var mouse_end_pos = null
func can_commit() -> bool:
return false #ugly way of handling a cut
func do_action(canvas, data: Array):
.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):
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
var py = y
if s.x < 0:
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):
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,55 @@
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

@ -0,0 +1,59 @@
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

@ -0,0 +1,44 @@
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

@ -0,0 +1,59 @@
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

@ -0,0 +1,43 @@
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

@ -0,0 +1,58 @@
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,69 @@
extends GEAction
class_name GERect
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]
#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):
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):
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])