First commit 🎉
This commit is contained in:
commit
43ea213f9b
728 changed files with 37080 additions and 0 deletions
323
addons/popochiu/editor/helpers/popochiu_editor_helper.gd
Normal file
323
addons/popochiu/editor/helpers/popochiu_editor_helper.gd
Normal file
|
@ -0,0 +1,323 @@
|
|||
@tool
|
||||
class_name PopochiuEditorHelper
|
||||
extends Resource
|
||||
## Utils class for Editor related things.
|
||||
|
||||
# ---- Strings, paths, scenes, and other values ----------------------------------------------------
|
||||
const POPUPS_FOLDER = "res://addons/popochiu/editor/popups/"
|
||||
const CREATE_OBJECT_FOLDER = "res://addons/popochiu/editor/popups/create_object/"
|
||||
const CREATE_ROOM = preload(CREATE_OBJECT_FOLDER + "create_room/create_room.tscn")
|
||||
const CREATE_CHARACTER = preload(CREATE_OBJECT_FOLDER + "create_character/create_character.tscn")
|
||||
const CREATE_INVENTORY_ITEM = preload(
|
||||
CREATE_OBJECT_FOLDER + "create_inventory_item/create_inventory_item.tscn"
|
||||
)
|
||||
const CREATE_DIALOG = preload(CREATE_OBJECT_FOLDER + "create_dialog/create_dialog.tscn")
|
||||
const CREATE_PROP = preload(CREATE_OBJECT_FOLDER + "create_prop/create_prop.tscn")
|
||||
const CREATE_HOTSPOT = preload(CREATE_OBJECT_FOLDER + "create_hotspot/create_hotspot.tscn")
|
||||
const CREATE_WALKABLE_AREA = preload(
|
||||
CREATE_OBJECT_FOLDER + "create_walkable_area/create_walkable_area.tscn"
|
||||
)
|
||||
const CREATE_REGION = preload(CREATE_OBJECT_FOLDER + "create_region/create_region.tscn")
|
||||
const CREATE_MARKER = preload(CREATE_OBJECT_FOLDER + "create_marker/create_marker.tscn")
|
||||
const DELETE_CONFIRMATION_SCENE = preload(
|
||||
POPUPS_FOLDER + "delete_confirmation/delete_confirmation.tscn"
|
||||
)
|
||||
const PROGRESS_DIALOG_SCENE = preload(POPUPS_FOLDER + "progress/progress.tscn")
|
||||
const SETUP_SCENE = preload("res://addons/popochiu/editor/popups/setup/setup.tscn")
|
||||
# ---- Identifiers ---------------------------------------------------------------------------------
|
||||
const POPOCHIU_OBJECT_POLYGON_GROUP = "popochiu_object_polygon"
|
||||
const MIGRATIONS_PANEL_SCENE = preload(
|
||||
"res://addons/popochiu/editor/popups/migrations_panel/migrations_panel.tscn"
|
||||
)
|
||||
# ---- Classes -------------------------------------------------------------------------------------
|
||||
const PopochiuSignalBus = preload("res://addons/popochiu/editor/helpers/popochiu_signal_bus.gd")
|
||||
const DeleteConfirmation = preload(POPUPS_FOLDER + "delete_confirmation/delete_confirmation.gd")
|
||||
const Progress = preload(POPUPS_FOLDER + "progress/progress.gd")
|
||||
const CreateObject = preload(CREATE_OBJECT_FOLDER + "create_object.gd")
|
||||
const MigrationsPanel = preload(
|
||||
"res://addons/popochiu/editor/popups/migrations_panel/migrations_panel.gd"
|
||||
)
|
||||
|
||||
static var signal_bus := PopochiuSignalBus.new()
|
||||
static var ei := EditorInterface
|
||||
static var undo_redo: EditorUndoRedoManager = null
|
||||
static var dock: Panel = null
|
||||
|
||||
static var _room_scene_path_template := PopochiuResources.ROOMS_PATH.path_join("%s/room_%s.tscn")
|
||||
|
||||
|
||||
#region Public #####################################################################################
|
||||
static func select_node(node: Node) -> void:
|
||||
ei.get_selection().clear()
|
||||
ei.get_selection().add_node(node)
|
||||
|
||||
|
||||
static func show_popup(popup_name: String) -> void:
|
||||
PopochiuUtils.print_normal(popup_name)
|
||||
|
||||
|
||||
static func add_resource_to_popochiu(target: String, resource: Resource) -> int:
|
||||
return PopochiuResources.set_data_value(target, resource.script_name, resource.resource_path)
|
||||
|
||||
|
||||
static func show_delete_confirmation(
|
||||
content: DeleteConfirmation, min_size := Vector2i(640, 160)
|
||||
) -> void:
|
||||
var dialog := ConfirmationDialog.new()
|
||||
dialog.title = content.title
|
||||
|
||||
dialog.confirmed.connect(
|
||||
func () -> void:
|
||||
if content.on_confirmed:
|
||||
content.on_confirmed.call()
|
||||
|
||||
dialog.queue_free()
|
||||
)
|
||||
dialog.canceled.connect(
|
||||
func () -> void:
|
||||
if content.on_canceled:
|
||||
content.on_canceled.call()
|
||||
|
||||
dialog.queue_free()
|
||||
)
|
||||
dialog.about_to_popup.connect(content.on_about_to_popup)
|
||||
dialog.add_child(content)
|
||||
|
||||
await show_dialog(dialog, min_size)
|
||||
|
||||
|
||||
static func show_progress(min_size := Vector2i(640, 80)) -> Progress:
|
||||
var dialog := AcceptDialog.new()
|
||||
var content: Progress = PROGRESS_DIALOG_SCENE.instantiate()
|
||||
|
||||
dialog.borderless = true
|
||||
dialog.add_child(content)
|
||||
dialog.get_ok_button().hide()
|
||||
await show_dialog(dialog, min_size)
|
||||
|
||||
return content
|
||||
|
||||
|
||||
static func show_creation_popup(scene: PackedScene, min_size := Vector2i(640, 180)) -> void:
|
||||
var content: CreateObject = scene.instantiate()
|
||||
var dialog := ConfirmationDialog.new()
|
||||
|
||||
content.content_changed.connect(
|
||||
func () -> void:
|
||||
content.custom_minimum_size = content.get_child(0).size
|
||||
content.size = content.get_child(0).size
|
||||
|
||||
dialog.reset_size()
|
||||
dialog.move_to_center()
|
||||
)
|
||||
dialog.confirmed.connect(content.create)
|
||||
dialog.canceled.connect(dialog.queue_free)
|
||||
dialog.about_to_popup.connect(content.on_about_to_popup)
|
||||
dialog.add_child(content)
|
||||
await show_dialog(dialog, min_size)
|
||||
|
||||
dialog.register_text_enter(content.input)
|
||||
|
||||
|
||||
static func show_setup(is_welcome := false) -> void:
|
||||
var dialog := ConfirmationDialog.new()
|
||||
var content := SETUP_SCENE.instantiate()
|
||||
|
||||
dialog.title = "Setup"
|
||||
dialog.confirmed.connect(content.on_close)
|
||||
dialog.close_requested.connect(content.on_close)
|
||||
dialog.about_to_popup.connect(content.on_about_to_popup)
|
||||
|
||||
dialog.add_child(content)
|
||||
dock.add_child.call_deferred(dialog)
|
||||
await dialog.ready
|
||||
|
||||
content.define_content(is_welcome)
|
||||
content.size_calculated.connect(
|
||||
func () -> void:
|
||||
dialog.reset_size()
|
||||
dialog.move_to_center()
|
||||
)
|
||||
|
||||
await show_dialog(dialog, content.custom_minimum_size)
|
||||
|
||||
|
||||
static func show_migrations(
|
||||
content: MigrationsPanel, min_size := Vector2i(640, 640)
|
||||
) -> AcceptDialog:
|
||||
var dialog := AcceptDialog.new()
|
||||
dialog.title = "Migration Tool"
|
||||
content.anchors_preset = Control.PRESET_FULL_RECT
|
||||
dialog.add_child(content)
|
||||
await show_dialog(dialog, min_size)
|
||||
|
||||
return dialog
|
||||
|
||||
|
||||
static func show_dialog(dialog: Window, min_size := Vector2i.ZERO) -> void:
|
||||
if not dialog.is_inside_tree():
|
||||
dock.add_child.call_deferred(dialog)
|
||||
await dialog.ready
|
||||
|
||||
dialog.popup_centered(min_size * EditorInterface.get_editor_scale())
|
||||
|
||||
|
||||
|
||||
# Type-checking functions
|
||||
static func is_popochiu_clickable(node: Node) -> bool:
|
||||
return node is PopochiuCharacter \
|
||||
or node is PopochiuProp \
|
||||
or node is PopochiuHotspot
|
||||
|
||||
|
||||
static func is_popochiu_object(node: Node) -> bool:
|
||||
return node is PopochiuRoom \
|
||||
or is_popochiu_room_object(node)
|
||||
|
||||
|
||||
static func is_popochiu_room_object(node: Node) -> bool:
|
||||
return node is PopochiuCharacter \
|
||||
or node is PopochiuProp \
|
||||
or node is PopochiuHotspot \
|
||||
or node is PopochiuWalkableArea \
|
||||
or node is PopochiuRegion
|
||||
|
||||
|
||||
static func is_room(node: Node) -> bool:
|
||||
return node is PopochiuRoom
|
||||
|
||||
|
||||
static func is_character(node: Node) -> bool:
|
||||
return node is PopochiuCharacter
|
||||
|
||||
|
||||
static func is_prop(node: Node) -> bool:
|
||||
return node is PopochiuProp
|
||||
|
||||
|
||||
static func is_hotspot(node: Node) -> bool:
|
||||
return node is PopochiuHotspot
|
||||
|
||||
|
||||
static func is_walkable_area(node: Node) -> bool:
|
||||
return node is PopochiuWalkableArea
|
||||
|
||||
|
||||
static func is_region(node: Node) -> bool:
|
||||
return node is PopochiuRegion
|
||||
|
||||
|
||||
static func is_marker(node: Node) -> bool:
|
||||
return node is Marker2D
|
||||
|
||||
|
||||
static func is_popochiu_obj_polygon(node: Node):
|
||||
return node.is_in_group(POPOCHIU_OBJECT_POLYGON_GROUP)
|
||||
|
||||
|
||||
# Context-checking functions
|
||||
static func is_editing_room() -> bool:
|
||||
# If the open scene in the editor is a PopochiuRoom, return true
|
||||
return is_room(ei.get_edited_scene_root())
|
||||
|
||||
|
||||
# Quick-access functions
|
||||
static func get_first_child_by_group(node: Node, group: StringName) -> Node:
|
||||
if (node == null):
|
||||
return null
|
||||
for n in node.get_children():
|
||||
if n.is_in_group(group):
|
||||
return n
|
||||
return null
|
||||
|
||||
|
||||
static func get_all_children(node, children := []) -> Array:
|
||||
if node == null:
|
||||
return []
|
||||
children.push_back(node)
|
||||
for child in node.get_children():
|
||||
children = get_all_children(child, children)
|
||||
return children
|
||||
|
||||
|
||||
## Overrides the font [param font_name] in [param node] by the theme [Font] identified by
|
||||
## [param editor_font_name].
|
||||
static func override_font(node: Control, font_name: String, editor_font_name: String) -> void:
|
||||
node.add_theme_font_override(font_name, node.get_theme_font(editor_font_name, "EditorFonts"))
|
||||
|
||||
|
||||
static func frame_processed() -> void:
|
||||
await EditorInterface.get_base_control().get_tree().process_frame
|
||||
|
||||
|
||||
static func secs_passed(secs := 1.0) -> void:
|
||||
await EditorInterface.get_base_control().get_tree().create_timer(secs).timeout
|
||||
|
||||
|
||||
static func filesystem_scanned() -> void:
|
||||
EditorInterface.get_resource_filesystem().scan.call_deferred()
|
||||
await EditorInterface.get_resource_filesystem().filesystem_changed
|
||||
|
||||
|
||||
static func pack_scene(node: Node, path := "") -> int:
|
||||
var packed_scene := PackedScene.new()
|
||||
packed_scene.pack(node)
|
||||
|
||||
if path.is_empty():
|
||||
path = node.scene_file_path
|
||||
|
||||
return ResourceSaver.save(packed_scene, path)
|
||||
|
||||
|
||||
## Helper function to recursively remove all folders and files inside [param folder_path].
|
||||
static func remove_recursive(folder_path: String) -> bool:
|
||||
if DirAccess.dir_exists_absolute(folder_path):
|
||||
# Delete subfolders and their contents recursively in folder_path
|
||||
for subfolder_path: String in get_absolute_directory_paths_at(folder_path):
|
||||
remove_recursive(subfolder_path)
|
||||
|
||||
# Delete all files in folder_path
|
||||
for file_path: String in get_absolute_file_paths_at(folder_path):
|
||||
if DirAccess.remove_absolute(file_path) != OK:
|
||||
return false
|
||||
|
||||
# Once all files are deleted in folder_path, remove folder_path
|
||||
if DirAccess.remove_absolute(folder_path) != OK:
|
||||
return false
|
||||
return true
|
||||
|
||||
|
||||
## Helper function to get the absolute directory paths for all folders under [param folder_path].
|
||||
static func get_absolute_directory_paths_at(folder_path: String) -> Array:
|
||||
var dir_array : PackedStringArray = []
|
||||
|
||||
if DirAccess.dir_exists_absolute(folder_path):
|
||||
for folder in DirAccess.get_directories_at(folder_path):
|
||||
dir_array.append(folder_path.path_join(folder))
|
||||
|
||||
return Array(dir_array)
|
||||
|
||||
|
||||
## Helper function to get the absolute file paths for all files under [param folder_path].
|
||||
static func get_absolute_file_paths_at(folder_path: String) -> PackedStringArray:
|
||||
var file_array : PackedStringArray = []
|
||||
|
||||
if DirAccess.dir_exists_absolute(folder_path):
|
||||
for file in DirAccess.get_files_at(folder_path):
|
||||
file_array.append(folder_path.path_join(file))
|
||||
|
||||
return file_array
|
||||
|
||||
|
||||
## Returns an array of [PopochiuRoom] (instances) for all the rooms in the project.
|
||||
static func get_rooms() -> Array[PopochiuRoom]:
|
||||
var rooms: Array[PopochiuRoom] = []
|
||||
rooms.assign(PopochiuResources.get_section_keys("rooms").map(
|
||||
func (room_name: String) -> PopochiuRoom:
|
||||
var scene_path := _room_scene_path_template.replace("%s", room_name.to_snake_case())
|
||||
return (load(scene_path) as PackedScene).instantiate(PackedScene.GEN_EDIT_STATE_INSTANCE)
|
||||
))
|
||||
return rooms
|
||||
|
||||
|
||||
#endregion
|
|
@ -0,0 +1 @@
|
|||
uid://bgogdq51wvqyn
|
359
addons/popochiu/editor/helpers/popochiu_gui_templates_helper.gd
Normal file
359
addons/popochiu/editor/helpers/popochiu_gui_templates_helper.gd
Normal file
|
@ -0,0 +1,359 @@
|
|||
@tool
|
||||
extends Resource
|
||||
## Helper class for operations related to the GUI templates
|
||||
|
||||
static var _template_id := ""
|
||||
static var _template_theme_path := ""
|
||||
|
||||
#region Public #####################################################################################
|
||||
## Creates a copy of the selected template, including its components. Also generate the necessary
|
||||
## scripts to define custom logic for the graphical interface and its commands.
|
||||
static func copy_gui_template(
|
||||
template_name: String, on_progress: Callable, on_complete: Callable
|
||||
) -> void:
|
||||
if (
|
||||
DirAccess.dir_exists_absolute(PopochiuResources.GUI_GAME_FOLDER)
|
||||
and template_name == PopochiuResources.get_data_value("ui", "template", "")
|
||||
):
|
||||
PopochiuUtils.print_normal("No changes in GUI template.")
|
||||
|
||||
on_complete.call()
|
||||
return
|
||||
|
||||
on_progress.call(0, "Starting GUI template application")
|
||||
|
||||
_template_theme_path = ""
|
||||
|
||||
var scene_path := PopochiuResources.GUI_CUSTOM_SCENE
|
||||
var commands_template_path := PopochiuResources.GUI_CUSTOM_TEMPLATE
|
||||
|
||||
_template_id = template_name.to_snake_case()
|
||||
|
||||
if _template_id != PopochiuResources.GUI_CUSTOM:
|
||||
scene_path = PopochiuResources.GUI_TEMPLATES_FOLDER.path_join(
|
||||
"%s/%s_gui.tscn" % [_template_id, _template_id]
|
||||
)
|
||||
commands_template_path = PopochiuResources.GUI_SCRIPT_TEMPLATES_FOLDER.path_join(
|
||||
"%s_commands_template.gd" % _template_id
|
||||
)
|
||||
|
||||
var script_path := PopochiuResources.GUI_GAME_SCENE.replace(".tscn", ".gd")
|
||||
|
||||
await _wait()
|
||||
on_progress.call(5, "Creating Graphic Interface scene")
|
||||
|
||||
# ---- Make a copy of the selected GUI template ------------------------------------------------
|
||||
if _create_scene(scene_path) != OK:
|
||||
PopochiuUtils.print_error("Couldn't create %s file" % PopochiuResources.GUI_GAME_SCENE)
|
||||
return
|
||||
|
||||
await _wait(2.0)
|
||||
on_progress.call(10, "Copying a bunch of components")
|
||||
|
||||
# Copy the components used by the GUI template to the res://game/gui/components
|
||||
# folder so devs can play with them freely -----------------------------------------------------
|
||||
await copy_components(scene_path, true)
|
||||
|
||||
on_progress.call(60, "Creating scripts")
|
||||
|
||||
# Create a copy of the corresponding commands template -----------------------------------------
|
||||
_copy_commands_and_gui_scripts(
|
||||
commands_template_path, PopochiuResources.GUI_COMMANDS, script_path, scene_path
|
||||
)
|
||||
|
||||
await _wait(1.5)
|
||||
on_progress.call(80, "Assigning scripts")
|
||||
|
||||
# Update the script of the created gui.tscn so it uses the copy created above ------------------
|
||||
if _update_scene_script(script_path) != OK:
|
||||
PopochiuUtils.print_error("Couldn't update gui.tscn script")
|
||||
return
|
||||
|
||||
await _wait()
|
||||
on_progress.call(90, "Updating config file")
|
||||
|
||||
# Update the info related to the GUI template and the GUI commands script
|
||||
# in the popochiu_data.cfg file ----------------------------------------------------------------
|
||||
PopochiuResources.set_data_value("ui", "template", template_name)
|
||||
await _wait(0.8)
|
||||
|
||||
on_progress.call(100, "All in place. Thanks for your patience.")
|
||||
PopochiuUtils.print_normal("[wave]Selected GUI template successfully applied[/wave]")
|
||||
await _wait()
|
||||
await PopochiuEditorHelper.filesystem_scanned()
|
||||
|
||||
on_complete.call()
|
||||
|
||||
|
||||
static func copy_component(source_scene_path: String) -> String:
|
||||
var file_name := source_scene_path.get_file()
|
||||
var source_folder := source_scene_path.get_base_dir()
|
||||
|
||||
var target_folder := source_folder.replace(PopochiuResources.GUI_ADDON_FOLDER, "")
|
||||
target_folder = PopochiuResources.GUI_GAME_FOLDER + target_folder
|
||||
|
||||
if not DirAccess.dir_exists_absolute(target_folder):
|
||||
DirAccess.make_dir_recursive_absolute(target_folder)
|
||||
|
||||
# Make a copy of the component and save it in the graphic interface components folder
|
||||
var component_instance := (load(source_scene_path) as PackedScene).instantiate()
|
||||
var target_scene_file := "%s/%s" % [target_folder, file_name]
|
||||
|
||||
var packed_scene := PackedScene.new()
|
||||
packed_scene.pack(component_instance)
|
||||
packed_scene.resource_path = target_scene_file
|
||||
|
||||
var err := ResourceSaver.save(packed_scene, target_scene_file)
|
||||
|
||||
if err != OK:
|
||||
PopochiuUtils.print_error(
|
||||
"Couldn't create instance of %s component. Error code: %d." % [
|
||||
file_name.get_slice(".", 0).capitalize(),
|
||||
err
|
||||
]
|
||||
)
|
||||
|
||||
return ""
|
||||
|
||||
# Move the dependencies of the source scene to the graphic interface folder
|
||||
await copy_components(source_scene_path)
|
||||
|
||||
return target_scene_file
|
||||
|
||||
|
||||
## Makes a copy of the components used by the original GUI template to the
|
||||
## **res://game/gui/components/** folder so devs can play with those scenes without
|
||||
## affecting the ones in the plugin's folder.
|
||||
static func copy_components(source_scene_path: String, is_gui_game_scene := false) -> void:
|
||||
var dependencies_to_update: Array[Dictionary] = []
|
||||
|
||||
# Make a copy of the dependencies of the graphic interface
|
||||
for dep: String in ResourceLoader.get_dependencies(source_scene_path):
|
||||
var source_file_path := dep.get_slice("::", 2)
|
||||
|
||||
if (
|
||||
is_gui_game_scene and source_file_path.get_extension() == "gd"
|
||||
and source_scene_path.get_base_dir() == source_file_path.get_base_dir()
|
||||
):
|
||||
# Ignore the script of the GUI template scene file
|
||||
continue
|
||||
|
||||
var source_file_uid := ResourceUID.id_to_text(
|
||||
ResourceLoader.get_resource_uid(source_file_path)
|
||||
)
|
||||
var dependency_data := {
|
||||
source_path = source_file_path,
|
||||
source_uid = source_file_uid,
|
||||
target_path = "",
|
||||
}
|
||||
|
||||
# ---- Create the folder of the file -------------------------------------------------------
|
||||
var file_name := source_file_path.get_file()
|
||||
var source_folder := source_file_path.get_base_dir()
|
||||
|
||||
var target_folder := source_folder.replace(PopochiuResources.GUI_ADDON_FOLDER, "")
|
||||
target_folder = target_folder.replace("templates/%s/" % _template_id, "")
|
||||
target_folder = PopochiuResources.GUI_GAME_FOLDER + target_folder
|
||||
|
||||
dependency_data.target_path = "%s/%s" % [target_folder, file_name]
|
||||
|
||||
# Make sure all the copied components share the copied GUI theme
|
||||
if source_file_path.get_extension() == "tres" and "_theme" in source_file_path:
|
||||
if is_gui_game_scene and _template_theme_path.is_empty():
|
||||
# Change the name of the GUI template theme so it differs from the original one
|
||||
dependency_data.target_path = "%s/%s" % [
|
||||
target_folder, "gui_theme.tres"
|
||||
]
|
||||
_template_theme_path = dependency_data.target_path
|
||||
elif not is_gui_game_scene:
|
||||
dependency_data.target_path = _template_theme_path
|
||||
|
||||
dependencies_to_update.append(dependency_data)
|
||||
|
||||
if FileAccess.file_exists(dependency_data.target_path):
|
||||
# Ignore any file that has already been copied
|
||||
continue
|
||||
|
||||
if not DirAccess.dir_exists_absolute(target_folder):
|
||||
DirAccess.make_dir_recursive_absolute(target_folder)
|
||||
|
||||
# --- Make a copy of the original file -----------------------------------------------------
|
||||
if source_file_path.get_extension() == "gd":
|
||||
_copy_component_script(source_file_path, dependency_data.target_path)
|
||||
else:
|
||||
_copy_file(source_file_path, target_folder, dependency_data.target_path)
|
||||
|
||||
EditorInterface.get_resource_filesystem().scan()
|
||||
await EditorInterface.get_resource_filesystem().filesystem_changed
|
||||
|
||||
# Repeat the process for each of the dependencies of the .tscn resources
|
||||
if source_file_path.get_extension() == "tscn":
|
||||
await copy_components(source_file_path)
|
||||
|
||||
if is_gui_game_scene:
|
||||
_update_dependencies(PopochiuResources.GUI_GAME_SCENE, dependencies_to_update)
|
||||
else:
|
||||
var game_scene_path := source_scene_path.replace(PopochiuResources.GUI_ADDON_FOLDER, "")
|
||||
game_scene_path = game_scene_path.replace("templates/%s/" % _template_id, "")
|
||||
game_scene_path = PopochiuResources.GUI_GAME_FOLDER + game_scene_path
|
||||
|
||||
_update_dependencies(game_scene_path, dependencies_to_update)
|
||||
|
||||
EditorInterface.get_resource_filesystem().scan()
|
||||
await EditorInterface.get_resource_filesystem().filesystem_changed
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private ####################################################################################
|
||||
## Create the **gui.tscn** file as a copy of the selected GUI template scene.
|
||||
## If a template change is being made, all components of the previous template are removed along
|
||||
## with the **.tscn** file before copying the new one.
|
||||
static func _create_scene(scene_path: String) -> int:
|
||||
# Create the res://game/gui/ folder
|
||||
if not FileAccess.file_exists(PopochiuResources.GUI_GAME_SCENE):
|
||||
DirAccess.make_dir_recursive_absolute(PopochiuResources.GUI_GAME_FOLDER)
|
||||
else:
|
||||
# Remove the gui.tscn file
|
||||
DirAccess.remove_absolute(PopochiuResources.GUI_GAME_SCENE)
|
||||
EditorInterface.get_resource_filesystem().scan()
|
||||
|
||||
for dir_name: String in DirAccess.get_directories_at(PopochiuResources.GUI_GAME_FOLDER):
|
||||
_remove_components(PopochiuResources.GUI_GAME_FOLDER + dir_name)
|
||||
|
||||
# Make a copy of the selected GUI template (.tscn) and save it in
|
||||
# res://game/gui/gui.tscn ------------------------------------------
|
||||
var gi_scene := load(scene_path).duplicate(true)
|
||||
gi_scene.resource_path = PopochiuResources.GUI_GAME_SCENE
|
||||
|
||||
return ResourceSaver.save(gi_scene, PopochiuResources.GUI_GAME_SCENE)
|
||||
|
||||
|
||||
static func _remove_components(dir_path: String) -> void:
|
||||
for file_name: String in DirAccess.get_files_at(dir_path):
|
||||
DirAccess.remove_absolute(dir_path.path_join(file_name))
|
||||
EditorInterface.get_resource_filesystem().scan()
|
||||
|
||||
for dir_name: String in DirAccess.get_directories_at(dir_path):
|
||||
var sub_dir_path := dir_path.path_join(dir_name)
|
||||
_remove_components(sub_dir_path)
|
||||
|
||||
# Once the directory is empty, remove it
|
||||
DirAccess.remove_absolute(dir_path)
|
||||
EditorInterface.get_resource_filesystem().scan()
|
||||
|
||||
|
||||
## Makes a copy of a GUI component's script.
|
||||
static func _copy_component_script(
|
||||
source_file_path: String, target_file_path: String
|
||||
) -> void:
|
||||
# Make a copy of the original script -----------------------------------------------------------
|
||||
var source_file := FileAccess.open(source_file_path, FileAccess.READ)
|
||||
var source_code := source_file.get_as_text()
|
||||
source_file.close()
|
||||
|
||||
if "class_name " in source_code:
|
||||
source_code = source_code.replace("class_name Popochiu", "class_name GUI")
|
||||
|
||||
var file_write := FileAccess.open(target_file_path, FileAccess.WRITE)
|
||||
file_write.store_string(source_code)
|
||||
file_write.close()
|
||||
|
||||
# Create a script for devs to overwrite the functionality of the original's copy script --------
|
||||
file_write = FileAccess.open(target_file_path.replace(".gd", "_custom.gd"), FileAccess.WRITE)
|
||||
if "@tool" in source_code:
|
||||
file_write.store_string("@tool\n")
|
||||
file_write.store_string('extends "%s"' % target_file_path.get_file())
|
||||
|
||||
|
||||
static func _copy_file(
|
||||
source_file_path: String, target_folder: String, target_file_path: String
|
||||
) -> void:
|
||||
# ---- Create a copy of the scene file ---------------------------------------------------------
|
||||
if source_file_path.get_extension() in ["tscn", "tres"]:
|
||||
var file_resource := load(source_file_path).duplicate(true)
|
||||
file_resource.resource_path = target_file_path
|
||||
|
||||
if ResourceSaver.save(file_resource, target_file_path) != OK:
|
||||
DirAccess.remove_absolute(target_folder)
|
||||
else:
|
||||
DirAccess.copy_absolute(source_file_path, target_file_path)
|
||||
|
||||
|
||||
## Replace the UID and paths of the components in the graphic interface scene
|
||||
static func _update_dependencies(scene_path: String, dependencies_to_update: Array) -> void:
|
||||
if dependencies_to_update.is_empty():
|
||||
return
|
||||
|
||||
# ---- Update the UID and paths of the copied components ---------------------------------------
|
||||
var file_read = FileAccess.open(scene_path, FileAccess.READ)
|
||||
var text := file_read.get_as_text()
|
||||
file_read.close()
|
||||
|
||||
for dic: Dictionary in dependencies_to_update:
|
||||
var target_path: String = dic.target_path
|
||||
|
||||
if ".gd" in target_path:
|
||||
target_path = target_path.replace(".gd", "_custom.gd")
|
||||
|
||||
text = text.replace(dic.source_path, target_path)
|
||||
|
||||
var target_uid := ResourceUID.id_to_text(ResourceLoader.get_resource_uid(target_path))
|
||||
|
||||
if "invalid" in target_uid: continue
|
||||
|
||||
text = text.replace(dic.source_uid, target_uid)
|
||||
|
||||
var file_write = FileAccess.open(scene_path, FileAccess.WRITE)
|
||||
file_write.store_string(text)
|
||||
file_write.close()
|
||||
|
||||
|
||||
## Copy the commands and graphic interface scripts of the chosen GUI template. The new graphic
|
||||
## interface scripts inherits from the one originally assigned to the .tscn file of the selected
|
||||
## template.
|
||||
static func _copy_commands_and_gui_scripts(
|
||||
commands_template_path: String, commands_path: String, script_path: String, scene_path: String
|
||||
) -> void:
|
||||
DirAccess.copy_absolute(commands_template_path, commands_path)
|
||||
|
||||
# Create a copy of the graphic interface script template ---------------------------------------
|
||||
var template_path := (
|
||||
PopochiuResources.GUI_SCRIPT_TEMPLATES_FOLDER + "gui_template.gd"
|
||||
)
|
||||
var script_file := FileAccess.open(template_path, FileAccess.READ)
|
||||
var source_code := script_file.get_as_text()
|
||||
script_file.close()
|
||||
source_code = source_code.replace(
|
||||
"extends PopochiuGraphicInterface",
|
||||
'extends "%s"' % scene_path.replace(".tscn", ".gd")
|
||||
)
|
||||
script_file = FileAccess.open(script_path, FileAccess.WRITE)
|
||||
script_file.store_string(source_code)
|
||||
script_file.close()
|
||||
|
||||
|
||||
## Updates the script of the created [b]res://game/gui/gui.tscn[/b] file so it uses the one created
|
||||
## in [method _copy_commands_and_gui_scripts].
|
||||
static func _update_scene_script(script_path: String) -> int:
|
||||
# Update the script of the GUI -----------------------------------------------------------------
|
||||
var scene := (load(
|
||||
PopochiuResources.GUI_GAME_SCENE
|
||||
) as PackedScene).instantiate()
|
||||
scene.set_script(load(script_path))
|
||||
|
||||
# Set the name of the root node
|
||||
scene.name = "GUI"
|
||||
|
||||
var packed_scene: PackedScene = PackedScene.new()
|
||||
packed_scene.pack(scene)
|
||||
packed_scene.resource_path = PopochiuResources.GUI_GAME_SCENE
|
||||
|
||||
return ResourceSaver.save(packed_scene, PopochiuResources.GUI_GAME_SCENE)
|
||||
|
||||
|
||||
static func _wait(max := 1.0) -> void:
|
||||
await PopochiuEditorHelper.secs_passed(randf_range(0.5, max))
|
||||
|
||||
|
||||
#endregion
|
|
@ -0,0 +1 @@
|
|||
uid://cn6emnkso14qe
|
9
addons/popochiu/editor/helpers/popochiu_signal_bus.gd
Normal file
9
addons/popochiu/editor/helpers/popochiu_signal_bus.gd
Normal file
|
@ -0,0 +1,9 @@
|
|||
extends RefCounted
|
||||
## Helper Editor class to emit and connect to signals across different components in the plugin
|
||||
|
||||
signal main_scene_changed(scene_path: String)
|
||||
signal pc_changed(script_name: String)
|
||||
signal audio_cues_deleted(cue_file_paths: Array)
|
||||
signal main_object_added(type: int, name_to_add: String)
|
||||
signal gizmo_visibility_changed(gizmo: int, visible: bool)
|
||||
signal migrations_done
|
|
@ -0,0 +1 @@
|
|||
uid://p35cn6n5xi6r
|
Loading…
Add table
Add a link
Reference in a new issue