@tool extends PanelContainer # UI dock for the Weapon Creator plugin # Provides tabs for weapons and bullets, with creation dialogs and logs const WeaponCreatorSettings = preload("res://addons/weapon_creator/WeaponCreatorSettings.gd") const SETTINGS_PATH = "user://weapon_creator_settings.tres" signal create_weapon_requested(weapon_data: Dictionary) signal create_bullet_requested(bullet_data: Dictionary) signal create_item_requested(item_data: Dictionary) signal create_enemy_requested(enemy_data: Dictionary) # UI elements var clear_button: Button var options_button: Button var log_output: RichTextLabel var weapon_viewer: PanelContainer var bullet_viewer: PanelContainer var item_viewer: PanelContainer var enemy_viewer: PanelContainer var tab_container: TabContainer var _is_creating: bool = false var _editor_interface: EditorInterface var settings: Resource func setup(editor_interface: EditorInterface) -> void: _editor_interface = editor_interface if ResourceLoader.exists(SETTINGS_PATH): settings = ResourceLoader.load(SETTINGS_PATH) if not settings: settings = WeaponCreatorSettings.new() func _ready() -> void: if not settings: if ResourceLoader.exists(SETTINGS_PATH): settings = ResourceLoader.load(SETTINGS_PATH) if not settings: settings = WeaponCreatorSettings.new() _build_ui() func _build_ui() -> void: # Main margin container var margin = MarginContainer.new() margin.add_theme_constant_override("margin_left", 8) margin.add_theme_constant_override("margin_top", 8) margin.add_theme_constant_override("margin_right", 8) margin.add_theme_constant_override("margin_bottom", 8) add_child(margin) # Main vbox var vbox = VBoxContainer.new() vbox.add_theme_constant_override("separation", 8) margin.add_child(vbox) # Horizontal split container for tabs and log var hsplit = HSplitContainer.new() hsplit.size_flags_vertical = Control.SIZE_EXPAND_FILL vbox.add_child(hsplit) # Log section (left side) var log_vbox = VBoxContainer.new() log_vbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL log_vbox.add_theme_constant_override("separation", 4) hsplit.add_child(log_vbox) # Right side container with tabs and options button var right_vbox = VBoxContainer.new() right_vbox.custom_minimum_size = Vector2(300, 0) right_vbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL right_vbox.add_theme_constant_override("separation", 4) hsplit.add_child(right_vbox) # Header row with options button aligned to right var header_hbox = HBoxContainer.new() header_hbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL right_vbox.add_child(header_hbox) # Spacer to push options button to the right var spacer = Control.new() spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL header_hbox.add_child(spacer) options_button = Button.new() options_button.text = "⚙ Settings" options_button.pressed.connect(_on_options_pressed) header_hbox.add_child(options_button) # Tab Container for Weapons and Bullets tab_container = TabContainer.new() tab_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL tab_container.size_flags_vertical = Control.SIZE_EXPAND_FILL right_vbox.add_child(tab_container) # Weapon Viewer Tab var weapon_viewer_script = load("res://addons/weapon_creator/WeaponViewer.gd") weapon_viewer = PanelContainer.new() weapon_viewer.set_script(weapon_viewer_script) weapon_viewer.name = "Weapons" weapon_viewer.duplicate_weapon_requested.connect(_on_weapon_data_confirmed) weapon_viewer.weapon_deleted.connect(_on_weapon_deleted) weapon_viewer.weapon_duplication_started.connect(_on_weapon_duplication_started) tab_container.add_child(weapon_viewer) # Bullet Viewer Tab var bullet_viewer_script = load("res://addons/weapon_creator/BulletViewer.gd") bullet_viewer = PanelContainer.new() bullet_viewer.set_script(bullet_viewer_script) bullet_viewer.name = "Bullets" bullet_viewer.duplicate_bullet_requested.connect(_on_bullet_data_confirmed) bullet_viewer.bullet_deleted.connect(_on_bullet_deleted) bullet_viewer.bullet_duplication_started.connect(_on_bullet_duplication_started) tab_container.add_child(bullet_viewer) # Item Viewer Tab var item_viewer_script = load("res://addons/weapon_creator/ItemViewer.gd") item_viewer = PanelContainer.new() item_viewer.set_script(item_viewer_script) item_viewer.name = "Items" item_viewer.duplicate_item_requested.connect(_on_item_data_confirmed) item_viewer.item_deleted.connect(_on_item_deleted) item_viewer.item_duplication_started.connect(_on_item_duplication_started) tab_container.add_child(item_viewer) # Enemy Viewer Tab var enemy_viewer_script = load("res://addons/weapon_creator/EnemyViewer.gd") enemy_viewer = PanelContainer.new() enemy_viewer.set_script(enemy_viewer_script) enemy_viewer.name = "Enemies" enemy_viewer.duplicate_enemy_requested.connect(_on_enemy_data_confirmed) enemy_viewer.enemy_deleted.connect(_on_enemy_deleted) enemy_viewer.enemy_duplication_started.connect(_on_enemy_duplication_started) tab_container.add_child(enemy_viewer) # Setup after adding to scene tree if _editor_interface: weapon_viewer.setup(_editor_interface, self) bullet_viewer.setup(_editor_interface, self) item_viewer.setup(_editor_interface, self) enemy_viewer.setup(_editor_interface, self) # Log header with label and clear button var log_header_hbox = HBoxContainer.new() log_vbox.add_child(log_header_hbox) var log_label = Label.new() log_label.text = "Output Log:" log_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL log_header_hbox.add_child(log_label) clear_button = Button.new() clear_button.text = "Clear Log" clear_button.pressed.connect(_on_clear_button_pressed) log_header_hbox.add_child(clear_button) var log_scroll = ScrollContainer.new() log_scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL log_vbox.add_child(log_scroll) log_output = RichTextLabel.new() log_output.bbcode_enabled = true log_output.scroll_following = true log_output.selection_enabled = true log_output.context_menu_enabled = true log_output.size_flags_horizontal = Control.SIZE_EXPAND_FILL log_output.size_flags_vertical = Control.SIZE_EXPAND_FILL log_scroll.add_child(log_output) func _on_weapon_data_confirmed(weapon_data: Dictionary) -> void: if _is_creating: return _is_creating = true log_output.clear() create_weapon_requested.emit(weapon_data) func _on_clear_button_pressed() -> void: log_output.clear() func _on_options_pressed() -> void: var settings_dialog_script = load("res://addons/weapon_creator/SettingsDialog.gd") var settings_dialog = Window.new() settings_dialog.set_script(settings_dialog_script) settings_dialog.setup(_editor_interface) add_child(settings_dialog) settings_dialog.popup_centered() # Reload settings after dialog closes settings_dialog.tree_exited.connect(func(): if ResourceLoader.exists(SETTINGS_PATH): settings = ResourceLoader.load(SETTINGS_PATH) if not settings: settings = WeaponCreatorSettings.new() # Refresh all viewers to pick up new settings if weapon_viewer: weapon_viewer.call("refresh") if bullet_viewer: bullet_viewer.call("refresh") if item_viewer: item_viewer.call("refresh") if enemy_viewer: enemy_viewer.call("refresh") ) func _on_weapon_deleted(weapon_name: String, weapon_path: String, item_path: String) -> void: pass func _on_weapon_duplication_started(weapon_name: String, is_3d: bool) -> void: pass func _on_bullet_data_confirmed(bullet_data: Dictionary) -> void: if _is_creating: return _is_creating = true create_bullet_requested.emit(bullet_data) func _on_bullet_deleted(bullet_name: String, bullet_path: String) -> void: # Logging is handled directly in BulletViewer pass func _on_bullet_duplication_started(bullet_name: String, is_3d: bool) -> void: # Logging is handled directly in BulletViewer pass func _on_item_data_confirmed(item_data: Dictionary) -> void: if _is_creating: return _is_creating = true log_output.clear() create_item_requested.emit(item_data) func _on_item_deleted(item_name: String, item_path: String) -> void: pass func _on_item_duplication_started(item_name: String) -> void: pass func _on_enemy_data_confirmed(enemy_data: Dictionary) -> void: if _is_creating: return _is_creating = true log_output.clear() create_enemy_requested.emit(enemy_data) func _on_enemy_deleted(enemy_name: String, enemy_path: String) -> void: pass func _on_enemy_duplication_started(enemy_name: String, is_3d: bool) -> void: pass func add_log(message: String, color: Color = Color.WHITE) -> void: # Add colored message to log output log_output.append_text("[color=#" + color.to_html(false) + "]" + message + "[/color]\n") func set_creation_complete() -> void: _is_creating = false if weapon_viewer: weapon_viewer.call("refresh") if bullet_viewer: bullet_viewer.call("refresh") if item_viewer: item_viewer.call("refresh") if enemy_viewer: enemy_viewer.call("refresh")