1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-19 09:39:48 +00:00

Undo/redo now removes tiles and re-indexes tilemap tiles

This commit is contained in:
Emmanouil Papadeas 2024-11-24 22:23:05 +02:00
parent 3e2587e4ca
commit c1028131a1
9 changed files with 41 additions and 39 deletions

View file

@ -954,7 +954,7 @@ func general_redo(project := current_project) -> void:
## Performs actions done after an undo or redo is done. this takes [member general_undo] and
## [member general_redo] a step further. Does further work if the current action requires it
## like refreshing textures, redraw UI elements etc...[br]
## [param frame_index] and [param layer_index] are there for optimizzation. if the undo or redo
## [param frame_index] and [param layer_index] are there for optimization. if the undo or redo
## happens only in one cel then the cel's frame and layer should be passed to [param frame_index]
## and [param layer_index] respectively, otherwise the entire timeline will be refreshed.
func undo_or_redo(
@ -981,10 +981,14 @@ func undo_or_redo(
):
if layer_index > -1 and frame_index > -1:
canvas.update_texture(layer_index, frame_index, project)
var cel := project.frames[frame_index].cels[layer_index]
cel.on_undo_redo(undo)
else:
for i in project.frames.size():
for j in project.layers.size():
canvas.update_texture(j, i, project)
var cel := project.frames[i].cels[j]
cel.on_undo_redo(undo)
canvas.selection.queue_redraw()
if action_name == "Scale":

View file

@ -77,7 +77,7 @@ func update_texture() -> void:
cel.texture_changed.emit()
func tool_finished_drawing() -> void:
func on_undo_redo(undo: bool) -> void:
pass

View file

@ -36,11 +36,11 @@ func update_texture() -> void:
super.update_texture()
func tool_finished_drawing() -> void:
update_tileset()
func on_undo_redo(undo: bool) -> void:
update_tileset(undo)
func update_tileset() -> void:
func update_tileset(undo: bool) -> void:
for i in indices.size():
var coords := get_tile_coords(i)
var rect := Rect2i(coords, tileset.tile_size)
@ -74,6 +74,10 @@ func update_tileset() -> void:
if not found_tile:
tileset.add_tile(image_portion, TileSetPanel.tile_editing_mode)
indices[i] = tileset.tiles.size() - 1
if undo:
var tile_removed := tileset.remove_unused_tiles()
if tile_removed:
re_index_tiles()
## Cases:[br]
@ -209,7 +213,6 @@ func get_tile_position(coords: Vector2i) -> int:
return x + y
## Unused, should delete.
func re_index_tiles() -> void:
for i in indices.size():
var x_coord := float(tileset.tile_size.x) * (i % indices_x)

View file

@ -3,6 +3,7 @@ extends RefCounted
signal updated
var project: Project
var name := ""
var tile_size: Vector2i
var tiles: Array[Tile] = []
@ -12,40 +13,44 @@ class Tile:
var image: Image
var mode_added: TileSetPanel.TileEditingMode
var times_used := 1
var undo_step_added := 0
func _init(_image: Image, _mode_added: TileSetPanel.TileEditingMode) -> void:
func _init(
_image: Image, _mode_added: TileSetPanel.TileEditingMode, _undo_step_added := 0
) -> void:
image = _image
mode_added = _mode_added
undo_step_added = _undo_step_added
func can_be_removed() -> bool:
func can_be_removed(project: Project) -> bool:
if project.undos < undo_step_added:
return true
return mode_added != TileSetPanel.TileEditingMode.STACK and times_used <= 0
func _init(_tile_size: Vector2i, _name := "") -> void:
func _init(_tile_size: Vector2i, _project: Project, _name := "") -> void:
tile_size = _tile_size
project = _project
name = _name
#var indices_x := ceili(float(_project_size.x) / tile_size.x)
#var indices_y := ceili(float(_project_size.y) / tile_size.y)
#tiles.resize(indices_x * indices_y + 1)
var empty_image := Image.create_empty(tile_size.x, tile_size.y, false, Image.FORMAT_RGBA8)
tiles.append(Tile.new(empty_image, TileSetPanel.tile_editing_mode))
func add_tile(image: Image, edit_mode: TileSetPanel.TileEditingMode) -> void:
var tile := Tile.new(image, edit_mode)
var tile := Tile.new(image, edit_mode, project.undos)
tiles.append(tile)
updated.emit()
func insert_tile(image: Image, position: int, edit_mode: TileSetPanel.TileEditingMode) -> void:
var tile := Tile.new(image, edit_mode)
var tile := Tile.new(image, edit_mode, project.undos)
tiles.insert(position, tile)
updated.emit()
func unuse_tile_at_index(index: int) -> bool:
tiles[index].times_used -= 1
if tiles[index].can_be_removed():
if tiles[index].can_be_removed(project):
remove_tile_at_index(index)
return true
return false
@ -69,12 +74,11 @@ func find_tile(image: Image) -> int:
return -1
## Unused, should delete.
func remove_unused_tiles() -> bool:
var tile_removed := false
for i in range(tiles.size() - 1, 0, -1):
var tile := tiles[i]
if tile.can_be_removed():
tile_removed = true
if tile.can_be_removed(project):
remove_tile_at_index(i)
tile_removed = true
return tile_removed

View file

@ -76,16 +76,9 @@ func draw_end(_pos: Vector2i) -> void:
is_moving = false
_draw_cache = []
var project := Global.current_project
update_cels(project)
project.can_undo = true
func update_cels(project := Global.current_project) -> void:
for cel_index in project.selected_cels:
var cel := project.frames[cel_index[0]].cels[cel_index[1]] as BaseCel
cel.tool_finished_drawing()
func is_placing_tiles() -> bool:
return Global.current_project.get_current_cel() is CelTileMap and TileSetPanel.placing_tiles

View file

@ -96,9 +96,6 @@ func draw_start(pos: Vector2i) -> void:
_old_spacing_mode = _spacing_mode
pos = snap_position(pos)
super.draw_start(pos)
if is_placing_tiles():
draw_tile(pos, TileSetPanel.selected_tile_index)
return
if Input.is_action_pressed(&"draw_color_picker", true):
_picking_color = true
_pick_color(pos)
@ -106,6 +103,10 @@ func draw_start(pos: Vector2i) -> void:
_picking_color = false
Global.canvas.selection.transform_content_confirm()
prepare_undo("Draw")
if is_placing_tiles():
draw_tile(pos, TileSetPanel.selected_tile_index)
return
var can_skip_mask := true
if tool_slot.color.a < 1 and !_overwrite:
can_skip_mask = false
@ -115,7 +116,6 @@ func draw_start(pos: Vector2i) -> void:
_drawer.color_op.overwrite = _overwrite
_draw_points = []
prepare_undo("Draw")
_drawer.reset()
_draw_line = Input.is_action_pressed("draw_create_line")
@ -141,13 +141,13 @@ func draw_move(pos_i: Vector2i) -> void:
var pos := _get_stabilized_position(pos_i)
pos = snap_position(pos)
super.draw_move(pos)
if is_placing_tiles():
draw_tile(pos, TileSetPanel.selected_tile_index)
return
if _picking_color: # Still return even if we released Alt
if Input.is_action_pressed(&"draw_color_picker", true):
_pick_color(pos)
return
if is_placing_tiles():
draw_tile(pos, TileSetPanel.selected_tile_index)
return
if _draw_line:
_spacing_mode = false # spacing mode is disabled during line mode
@ -170,12 +170,13 @@ func draw_move(pos_i: Vector2i) -> void:
func draw_end(pos: Vector2i) -> void:
pos = snap_position(pos)
if _picking_color:
super.draw_end(pos)
return
if is_placing_tiles():
super.draw_end(pos)
draw_tile(pos, TileSetPanel.selected_tile_index)
return
if _picking_color:
super.draw_end(pos)
commit_undo()
return
if _draw_line:

View file

@ -158,7 +158,6 @@ func text_to_pixels() -> void:
if image is ImageExtended:
image.convert_rgb_to_indexed()
commit_undo("Draw", undo_data)
update_cels(project)
func commit_undo(action: String, undo_data: Dictionary) -> void:

View file

@ -517,7 +517,6 @@ func transform_content_confirm() -> void:
big_bounding_rectangle.position
)
cel_image.convert_rgb_to_indexed()
cel.tool_finished_drawing()
project.selection_map.move_bitmap_values(project)
commit_undo("Move Selection", undo_data)
@ -553,7 +552,6 @@ func transform_content_cancel() -> void:
big_bounding_rectangle.position
)
cel.transformed_content = null
cel.tool_finished_drawing()
for cel_index in project.selected_cels:
canvas.update_texture(cel_index[1])
original_preview_image = Image.new()

View file

@ -847,7 +847,7 @@ func add_layer(type := 0) -> void:
l = Layer3D.new(project)
SteamManager.set_achievement("ACH_3D_LAYER")
Global.LayerTypes.TILEMAP:
l = LayerTileMap.new(project, TileSetCustom.new(Vector2i(16, 16)))
l = LayerTileMap.new(project, TileSetCustom.new(Vector2i(16, 16), project))
var cels := []
for f in project.frames: