refactor(shell): author shell scenes as editor-previewable node trees
Move the three shell scenes (SystemDock, NarrationBook, MainWindowShell) from build-everything-in-_ready() to authored .tscn node trees with the theme + type-variations set in the editor, so the layout previews and can be arranged in the Godot editor. Scripts keep only on-load work: @onready node refs, DM-loop wiring, the dock slide, and binding seed ShellState into the fixed authored turn-order tokens + consumable slots. Fixes the dock offset + over-long buttons (now fixed-width DockButtons in a right-anchored menu). Headless probe: root 1920x1080, world/book split 1180/740, dock at the world's right edge — no collapse. Suite 138/138. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,44 +4,37 @@ extends Control
|
||||
## buttons in/out. §2: state (owns the open toggle via ShellState). The buttons
|
||||
## are the routing seam — they emit screen_requested; the screens they open land
|
||||
## in later milestones, so the signal is currently a no-op for the shell.
|
||||
##
|
||||
## Layout is authored in SystemDock.tscn (editor-previewable). This script only
|
||||
## wires the buttons' signals, drives the slide animation, and toggles state. Each
|
||||
## dock button carries a `screen_id` StringName in its scene metadata; add/reorder
|
||||
## buttons in the editor and the wiring follows.
|
||||
|
||||
signal screen_requested(id: StringName)
|
||||
|
||||
const SCREENS := [
|
||||
[&"inventory", "Inventory", "I"],
|
||||
[&"character", "Character", "C"],
|
||||
[&"quest_log", "Quest Log", "J"],
|
||||
[&"spellbook", "Spellbook", "K"],
|
||||
[&"world_map", "World Map", "M"],
|
||||
[&"party", "Party", "P"],
|
||||
]
|
||||
const SLIDE_SECONDS := 0.32
|
||||
const HIDDEN_SHIFT := 230.0
|
||||
|
||||
var _screen_buttons: Dictionary = {}
|
||||
var _state: ShellState
|
||||
var _menu: VBoxContainer
|
||||
var _handle: Button
|
||||
var _menu_open_pos: Vector2
|
||||
|
||||
@onready var _menu: VBoxContainer = $Menu
|
||||
@onready var _handle: Button = $Handle
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_menu = VBoxContainer.new()
|
||||
_menu.add_theme_constant_override("separation", 10)
|
||||
add_child(_menu)
|
||||
for entry in SCREENS:
|
||||
var id: StringName = entry[0]
|
||||
var button := Button.new()
|
||||
button.text = "%s %s" % [entry[2], entry[1]]
|
||||
button.theme_type_variation = ThemeKeys.DOCK_BUTTON
|
||||
button.pressed.connect(func(): screen_requested.emit(id))
|
||||
_menu.add_child(button)
|
||||
_screen_buttons[id] = button
|
||||
|
||||
_handle = Button.new()
|
||||
_handle.text = "›"
|
||||
_handle.theme_type_variation = ThemeKeys.TAB_ACTIVE
|
||||
# The buttons live in the scene; harvest each one's authored screen_id so the
|
||||
# routing seam follows editor edits (add/remove/reorder needs no code change).
|
||||
for child in _menu.get_children():
|
||||
if child is Button and child.has_meta("screen_id"):
|
||||
var id: StringName = child.get_meta("screen_id")
|
||||
child.pressed.connect(func(): screen_requested.emit(id))
|
||||
_screen_buttons[id] = child
|
||||
_handle.pressed.connect(_on_handle_pressed)
|
||||
add_child(_handle)
|
||||
# Capture the authored open position so the slide is relative to wherever the
|
||||
# menu is placed in the editor — moving it in the editor just works.
|
||||
_menu_open_pos = _menu.position
|
||||
|
||||
|
||||
func setup(state: ShellState) -> void:
|
||||
@@ -57,7 +50,7 @@ func _on_handle_pressed() -> void:
|
||||
|
||||
func _apply_open(open: bool) -> void:
|
||||
_handle.text = "›" if open else "‹"
|
||||
var target := Vector2.ZERO if open else Vector2(HIDDEN_SHIFT, 0.0)
|
||||
var target := _menu_open_pos if open else _menu_open_pos + Vector2(HIDDEN_SHIFT, 0.0)
|
||||
var alpha := 1.0 if open else 0.0
|
||||
if not is_inside_tree():
|
||||
_menu.position = target
|
||||
|
||||
Reference in New Issue
Block a user