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:
@@ -5,75 +5,30 @@ extends Control
|
||||
## written back to the canon log (§11). Prose-only this milestone: the numbered
|
||||
## response choices and the "describe your own action" line are faithful but inert
|
||||
## (no action system yet); one in-world refire affordance re-runs narration.
|
||||
##
|
||||
## Layout is authored in NarrationBook.tscn (editor-previewable). This script only
|
||||
## binds the header, drives the narrate loop, and swaps prose text.
|
||||
|
||||
var last_degraded: bool = false
|
||||
|
||||
var _service: DmService
|
||||
var _log: CanonLog
|
||||
var _state: ShellState
|
||||
var _header: Label
|
||||
var _prose: RichTextLabel
|
||||
var _status: Label
|
||||
var _refire: Button
|
||||
var _degraded_tag: Label
|
||||
var _indicator: ConsideringIndicator
|
||||
|
||||
@onready var _header: Label = $Margin/Col/Header
|
||||
@onready var _prose: RichTextLabel = $Margin/Col/Prose
|
||||
@onready var _degraded_tag: Label = $Margin/Col/DegradedTag
|
||||
@onready var _refire: Button = $Margin/Col/Refire
|
||||
@onready var _status: Label = $Margin/Col/Status
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var col := VBoxContainer.new()
|
||||
col.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
col.add_theme_constant_override("separation", 18)
|
||||
add_child(col)
|
||||
|
||||
_header = Label.new()
|
||||
_header.theme_type_variation = ThemeKeys.ACCENT
|
||||
col.add_child(_header)
|
||||
|
||||
_prose = RichTextLabel.new()
|
||||
_prose.bbcode_enabled = true
|
||||
_prose.fit_content = true
|
||||
_prose.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
_prose.custom_minimum_size = Vector2(660, 320)
|
||||
col.add_child(_prose)
|
||||
|
||||
_degraded_tag = Label.new()
|
||||
_degraded_tag.theme_type_variation = ThemeKeys.MONO
|
||||
_degraded_tag.text = "THE MASTER'S VOICE COMES THIN" # shown only when degraded
|
||||
_degraded_tag.visible = false
|
||||
col.add_child(_degraded_tag)
|
||||
|
||||
# Faithful-but-inert placeholders (charter: prose-only this milestone).
|
||||
var prompt := Label.new()
|
||||
prompt.theme_type_variation = ThemeKeys.ACCENT
|
||||
prompt.text = "▸ Your turn. What do you do?"
|
||||
col.add_child(prompt)
|
||||
for line in [
|
||||
"1 · Pay the fence double and keep your hand where he can see it",
|
||||
"2 · Draw your blade — he's closer than his guards",
|
||||
"3 · Lie — tell him the rest is coming with your dwarf"]:
|
||||
var choice := Button.new()
|
||||
choice.theme_type_variation = ThemeKeys.PARCHMENT_BUTTON
|
||||
choice.text = line
|
||||
choice.disabled = true # inert until combat/dialogue give choices meaning
|
||||
col.add_child(choice)
|
||||
var free_text := Label.new()
|
||||
free_text.theme_type_variation = ThemeKeys.MONO
|
||||
free_text.text = "⌨ …or describe your own action"
|
||||
col.add_child(free_text)
|
||||
|
||||
# The one live control: refire the narration.
|
||||
_refire = Button.new()
|
||||
_refire.theme_type_variation = ThemeKeys.PARCHMENT_BUTTON
|
||||
_refire.text = "▸ The Master continues…"
|
||||
_refire.pressed.connect(_on_refire_pressed)
|
||||
col.add_child(_refire)
|
||||
|
||||
_status = Label.new()
|
||||
_status.theme_type_variation = ThemeKeys.MONO
|
||||
col.add_child(_status)
|
||||
|
||||
# The considering indicator is a non-visual Node (a Timer + label driver), so
|
||||
# it stays code-created rather than authored in the scene.
|
||||
_indicator = ConsideringIndicator.new()
|
||||
add_child(_indicator)
|
||||
_refire.pressed.connect(_on_refire_pressed)
|
||||
|
||||
|
||||
func setup(service: DmService, log: CanonLog, state: ShellState) -> void:
|
||||
|
||||
Reference in New Issue
Block a user