From 423c77235dc55da45176fb5ba6fe4ee310bc304e Mon Sep 17 00:00:00 2001 From: Emmanouil Papadeas <35376950+OverloadedOrama@users.noreply.github.com> Date: Fri, 29 Nov 2024 19:08:55 +0200 Subject: [PATCH] Add documentation for CelTileMap and rename update_tileset to update_tilemap --- src/Autoload/OpenSave.gd | 2 +- src/Classes/Cels/CelTileMap.gd | 131 +++++++++++------- src/Classes/ImageEffect.gd | 2 +- src/Classes/Project.gd | 6 +- src/Tools/BaseDraw.gd | 2 +- src/Tools/DesignTools/Bucket.gd | 2 +- src/Tools/UtilityTools/Move.gd | 2 +- src/Tools/UtilityTools/Text.gd | 2 +- src/UI/Canvas/Selection.gd | 2 +- .../Dialogs/ImageEffects/FlipImageDialog.gd | 2 +- .../LayerEffects/LayerEffectsSettings.gd | 2 +- src/UI/TopMenuContainer/TopMenuContainer.gd | 2 +- 12 files changed, 93 insertions(+), 64 deletions(-) diff --git a/src/Autoload/OpenSave.gd b/src/Autoload/OpenSave.gd index a4c58ba26..0a8eb3237 100644 --- a/src/Autoload/OpenSave.gd +++ b/src/Autoload/OpenSave.gd @@ -727,7 +727,7 @@ func open_image_at_cel(image: Image, layer_index := 0, frame_index := 0) -> void cel_image.convert_rgb_to_indexed() var redo_data := {} if cel is CelTileMap: - (cel as CelTileMap).update_tileset() + (cel as CelTileMap).update_tilemap() redo_data[cel] = (cel as CelTileMap).serialize_undo_data() cel_image.add_data_to_dictionary(redo_data) project.deserialize_cel_undo_data(redo_data, undo_data) diff --git a/src/Classes/Cels/CelTileMap.gd b/src/Classes/Cels/CelTileMap.gd index 00d6bcf20..fd266828b 100644 --- a/src/Classes/Cels/CelTileMap.gd +++ b/src/Classes/Cels/CelTileMap.gd @@ -33,7 +33,7 @@ var vertical_cells: int ## The key is the index of the tile in the tileset, ## and the value is the index of the tilemap tile that changed first, along with ## its image that is being changed when manual mode is enabled. -## Gets reset on [method update_tileset]. +## Gets reset on [method update_tilemap]. var editing_images := {} @@ -130,6 +130,9 @@ func tiles_equal(cell_position: int, image_portion: Image, tile_image: Image) -> return image_portion.get_data() == final_image_portion.get_data() +## Applies transformations to [param tile_image] based on [param flip_h], +## [param flip_v] and [param transpose], and returns the transformed image. +## If [param reverse] is [code]true[/code], the transposition is applied the reverse way. func transform_tile( tile_image: Image, flip_h: bool, flip_v: bool, transpose: bool, reverse := false ) -> Image: @@ -156,7 +159,59 @@ func transform_tile( return transformed_tile -func update_tileset( +## Appends data to a [Dictionary] to be used for undo/redo. +func serialize_undo_data() -> Dictionary: + var dict := {} + var cell_indices := [] + cell_indices.resize(cells.size()) + for i in cell_indices.size(): + cell_indices[i] = cells[i].serialize() + dict["cell_indices"] = cell_indices + dict["tileset"] = tileset.serialize_undo_data() + dict["resize"] = false + return dict + + +## Same purpose as [method serialize_undo_data], but for when the image resource +## ([param source_image]) we want to store to the undo/redo stack +## is not the same as [member image]. This method also handles the resizing logic for undo/redo. +func serialize_undo_data_source_image( + source_image: ImageExtended, redo_data: Dictionary, undo_data: Dictionary +) -> void: + undo_data[self] = serialize_undo_data() + if source_image.get_size() != image.get_size(): + undo_data[self]["resize"] = true + _resize_cells(source_image.get_size()) + tileset.clear_tileset(self) + var tile_editing_mode := TileSetPanel.tile_editing_mode + if tile_editing_mode == TileSetPanel.TileEditingMode.MANUAL: + tile_editing_mode = TileSetPanel.TileEditingMode.AUTO + update_tilemap(tile_editing_mode, source_image) + redo_data[self] = serialize_undo_data() + redo_data[self]["resize"] = undo_data[self]["resize"] + + +## Reads data from a [param dict] [Dictionary], and uses them to add methods to [param undo_redo]. +func deserialize_undo_data(dict: Dictionary, undo_redo: UndoRedo, undo: bool) -> void: + var cell_indices = dict.cell_indices + if undo: + undo_redo.add_undo_method(_deserialize_cell_data.bind(cell_indices, dict.resize)) + if dict.has("tileset"): + undo_redo.add_undo_method(tileset.deserialize_undo_data.bind(dict.tileset, self)) + else: + undo_redo.add_do_method(_deserialize_cell_data.bind(cell_indices, dict.resize)) + if dict.has("tileset"): + undo_redo.add_do_method(tileset.deserialize_undo_data.bind(dict.tileset, self)) + + +## Gets called every time a change is being applied to the [param image], +## such as when finishing drawing with a draw tool, or when applying an image effect. +## This method responsible for updating the indices of the [member cells], as well as +## updating the [member tileset] with the incoming changes. +## The updating behavior depends on the current tile editing mode +## by [member TileSetPanel.tile_editing_mode]. +## If a [param source_image] is provided, that image is being used instead of [member image]. +func update_tilemap( tile_editing_mode := TileSetPanel.tile_editing_mode, source_image := image ) -> void: editing_images.clear() @@ -201,6 +256,8 @@ func update_tileset( cells[i].remove_transformations() +## Gets called by [method update_tilemap]. This method is responsible for handling +## the tilemap updating behavior for the auto tile editing mode.[br] ## Cases:[br] ## 0) Cell is transparent. Set its index to 0. ## [br] @@ -308,6 +365,8 @@ func _re_index_cells_after_index(index: int) -> void: cells[i].index -= 1 +## Updates the [member image] data of the cell of the tilemap in [param cell_position], +## to ensure that it is the same as its mapped tile in the [member tileset]. func _update_cell(cell_position: int) -> void: var coords := get_cell_coords_in_image(cell_position) var rect := Rect2i(coords, tileset.tile_size) @@ -329,11 +388,14 @@ func _update_cell(cell_position: int) -> void: image.convert_rgb_to_indexed() +## Calls [method _update_cell] for all [member cells]. func _update_cel_portions() -> void: for i in cells.size(): _update_cell(i) +## Loops through all [member cells] of the tilemap and updates their indices, +## so they can remain mapped to the [member tileset]'s tiles. func _re_index_all_cells() -> void: for i in cells.size(): var coords := get_cell_coords_in_image(i) @@ -349,6 +411,7 @@ func _re_index_all_cells() -> void: break +## Resizes the [member cells] array based on [param new_size]. func _resize_cells(new_size: Vector2i) -> void: horizontal_cells = ceili(float(new_size.x) / tileset.tile_size.x) vertical_cells = ceili(float(new_size.y) / tileset.tile_size.y) @@ -357,11 +420,17 @@ func _resize_cells(new_size: Vector2i) -> void: cells[i] = Cell.new() +## Returns [code]true[/code] if the user just did a Redo. func _is_redo() -> bool: return Global.control.redone -## If the tileset has been modified by another tile, make sure to also update it here. +## If the tileset has been modified by another [param cel], +## make sure to also update it here. +## If [param replace_index] is larger than -1, it means that manual mode +## has been used to replace a tile in the tileset in another cel, +## so call [method _update_cel_portions] to update it in this cel as well. +## Otherwise, call [method _re_index_all_cells] to ensure that the cells have correct indices. func _on_tileset_updated(cel: CelTileMap, replace_index: int) -> void: if cel == self or not is_instance_valid(cel): return @@ -375,6 +444,14 @@ func _on_tileset_updated(cel: CelTileMap, replace_index: int) -> void: Global.canvas.queue_redraw() +func _deserialize_cell_data(cell_indices: Array, resize: bool) -> void: + if resize: + _resize_cells(image.get_size()) + for i in cell_indices.size(): + var cell_data: Dictionary = cell_indices[i] + cells[i].deserialize(cell_data) + + # Overridden Methods: func set_content(content, texture: ImageTexture = null) -> void: super.set_content(content, texture) @@ -425,54 +502,6 @@ func update_texture(undo := false) -> void: super.update_texture(undo) -func serialize_undo_data() -> Dictionary: - var dict := {} - var cell_indices := [] - cell_indices.resize(cells.size()) - for i in cell_indices.size(): - cell_indices[i] = cells[i].serialize() - dict["cell_indices"] = cell_indices - dict["tileset"] = tileset.serialize_undo_data() - dict["resize"] = false - return dict - - -func serialize_undo_data_source_image( - source_image: ImageExtended, redo_data: Dictionary, undo_data: Dictionary -) -> void: - undo_data[self] = serialize_undo_data() - if source_image.get_size() != image.get_size(): - undo_data[self]["resize"] = true - _resize_cells(source_image.get_size()) - tileset.clear_tileset(self) - var tile_editing_mode := TileSetPanel.tile_editing_mode - if tile_editing_mode == TileSetPanel.TileEditingMode.MANUAL: - tile_editing_mode = TileSetPanel.TileEditingMode.AUTO - update_tileset(tile_editing_mode, source_image) - redo_data[self] = serialize_undo_data() - redo_data[self]["resize"] = undo_data[self]["resize"] - - -func deserialize_undo_data(dict: Dictionary, undo_redo: UndoRedo, undo: bool) -> void: - var cell_indices = dict.cell_indices - if undo: - undo_redo.add_undo_method(deserialize_cell_data.bind(cell_indices, dict.resize)) - if dict.has("tileset"): - undo_redo.add_undo_method(tileset.deserialize_undo_data.bind(dict.tileset, self)) - else: - undo_redo.add_do_method(deserialize_cell_data.bind(cell_indices, dict.resize)) - if dict.has("tileset"): - undo_redo.add_do_method(tileset.deserialize_undo_data.bind(dict.tileset, self)) - - -func deserialize_cell_data(cell_indices: Array, resize: bool) -> void: - if resize: - _resize_cells(image.get_size()) - for i in cell_indices.size(): - var cell_data: Dictionary = cell_indices[i] - cells[i].deserialize(cell_data) - - func serialize() -> Dictionary: var dict := super.serialize() var cell_indices := [] diff --git a/src/Classes/ImageEffect.gd b/src/Classes/ImageEffect.gd index d1cf3c12e..5efec7fe0 100644 --- a/src/Classes/ImageEffect.gd +++ b/src/Classes/ImageEffect.gd @@ -157,7 +157,7 @@ func display_animate_dialog() -> void: func _commit_undo(action: String, undo_data: Dictionary, project: Project) -> void: - project.update_tilesets(undo_data) + project.update_tilemaps(undo_data) var redo_data := _get_undo_data(project) project.undos += 1 project.undo_redo.create_action(action) diff --git a/src/Classes/Project.gd b/src/Classes/Project.gd index 4aba6f9a6..7b9fd9ef4 100644 --- a/src/Classes/Project.gd +++ b/src/Classes/Project.gd @@ -1017,8 +1017,8 @@ func add_tileset(tileset: TileSetCustom) -> void: ## Loops through all cels in [param cel_dictionary], and for [CelTileMap]s, -## it calls [method CelTileMap.update_tileset]. -func update_tilesets(cel_dictionary: Dictionary) -> void: +## it calls [method CelTileMap.update_tilemap]. +func update_tilemaps(cel_dictionary: Dictionary) -> void: for cel in cel_dictionary: if cel is CelTileMap: - (cel as CelTileMap).update_tileset() + (cel as CelTileMap).update_tilemap() diff --git a/src/Tools/BaseDraw.gd b/src/Tools/BaseDraw.gd index 21cd49057..f8cd6e201 100644 --- a/src/Tools/BaseDraw.gd +++ b/src/Tools/BaseDraw.gd @@ -273,7 +273,7 @@ func prepare_undo(action: String) -> void: func commit_undo() -> void: var project := Global.current_project - project.update_tilesets(_undo_data) + project.update_tilemaps(_undo_data) var redo_data := _get_undo_data() var frame := -1 var layer := -1 diff --git a/src/Tools/DesignTools/Bucket.gd b/src/Tools/DesignTools/Bucket.gd index 6712e6be3..02db74905 100644 --- a/src/Tools/DesignTools/Bucket.gd +++ b/src/Tools/DesignTools/Bucket.gd @@ -495,7 +495,7 @@ func _set_pixel_pattern(image: ImageExtended, x: int, y: int, pattern_size: Vect func commit_undo() -> void: var project := Global.current_project - project.update_tilesets(_undo_data) + project.update_tilemaps(_undo_data) var redo_data := _get_undo_data() var frame := -1 var layer := -1 diff --git a/src/Tools/UtilityTools/Move.gd b/src/Tools/UtilityTools/Move.gd index dc0635ddd..437c2484a 100644 --- a/src/Tools/UtilityTools/Move.gd +++ b/src/Tools/UtilityTools/Move.gd @@ -131,7 +131,7 @@ func _snap_position(pos: Vector2) -> Vector2: func _commit_undo(action: String) -> void: var project := Global.current_project - project.update_tilesets(_undo_data) + project.update_tilemaps(_undo_data) var redo_data := _get_undo_data() var frame := -1 var layer := -1 diff --git a/src/Tools/UtilityTools/Text.gd b/src/Tools/UtilityTools/Text.gd index 5487add12..20fa26783 100644 --- a/src/Tools/UtilityTools/Text.gd +++ b/src/Tools/UtilityTools/Text.gd @@ -163,7 +163,7 @@ func text_to_pixels() -> void: func commit_undo(action: String, undo_data: Dictionary) -> void: var project := Global.current_project - project.update_tilesets(undo_data) + project.update_tilemaps(undo_data) var redo_data := _get_undo_data() var frame := -1 var layer := -1 diff --git a/src/UI/Canvas/Selection.gd b/src/UI/Canvas/Selection.gd index ba3fa0986..df0ea3c7d 100644 --- a/src/UI/Canvas/Selection.gd +++ b/src/UI/Canvas/Selection.gd @@ -569,7 +569,7 @@ func commit_undo(action: String, undo_data_tmp: Dictionary) -> void: print("No undo data found!") return var project := Global.current_project - project.update_tilesets(undo_data_tmp) + project.update_tilemaps(undo_data_tmp) var redo_data := get_undo_data(undo_data_tmp["undo_image"]) project.undos += 1 project.undo_redo.create_action(action) diff --git a/src/UI/Dialogs/ImageEffects/FlipImageDialog.gd b/src/UI/Dialogs/ImageEffects/FlipImageDialog.gd index b5633d258..51aee6e2e 100644 --- a/src/UI/Dialogs/ImageEffects/FlipImageDialog.gd +++ b/src/UI/Dialogs/ImageEffects/FlipImageDialog.gd @@ -47,7 +47,7 @@ func _flip_image(cel: Image, affect_selection: bool, project: Project) -> void: func _commit_undo(action: String, undo_data: Dictionary, project: Project) -> void: _flip_selection(project) - project.update_tilesets(undo_data) + project.update_tilemaps(undo_data) var redo_data := _get_undo_data(project) project.undos += 1 project.undo_redo.create_action(action) diff --git a/src/UI/Timeline/LayerEffects/LayerEffectsSettings.gd b/src/UI/Timeline/LayerEffects/LayerEffectsSettings.gd index 757ad5b12..802509522 100644 --- a/src/UI/Timeline/LayerEffects/LayerEffectsSettings.gd +++ b/src/UI/Timeline/LayerEffects/LayerEffectsSettings.gd @@ -165,7 +165,7 @@ func _apply_effect(layer: BaseLayer, effect: LayerEffect) -> void: var shader_image_effect := ShaderImageEffect.new() shader_image_effect.generate_image(cel_image, effect.shader, effect.params, image_size) - project.update_tilesets(undo_data) + project.update_tilemaps(undo_data) for frame in project.frames: var cel := frame.cels[layer.index] var cel_image := cel.get_image() diff --git a/src/UI/TopMenuContainer/TopMenuContainer.gd b/src/UI/TopMenuContainer/TopMenuContainer.gd index 3e4ea7882..7f78eba23 100644 --- a/src/UI/TopMenuContainer/TopMenuContainer.gd +++ b/src/UI/TopMenuContainer/TopMenuContainer.gd @@ -734,7 +734,7 @@ func _color_mode_submenu_id_pressed(id: ColorModes) -> void: project.color_mode = Image.FORMAT_RGBA8 else: project.color_mode = Project.INDEXED_MODE - project.update_tilesets(undo_data) + project.update_tilemaps(undo_data) project.serialize_cel_undo_data(pixel_cels, redo_data) project.undo_redo.create_action("Change color mode") project.undos += 1