First commit 🎉

This commit is contained in:
Tony Bark 2025-07-17 01:49:18 -04:00
commit 43ea213f9b
728 changed files with 37080 additions and 0 deletions

View 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