Draw the neon components in the editor, not just at runtime
Nothing under ui/ or vfx/ was marked @tool, so every hand-drawn control rendered as an empty rect in the editor. BuildMenu.tscn positions its buttons with hand-tuned pixel offsets (offset_left = -204) around a glyph identified only as `icon = 8` - laying out invisible boxes by number. @tool on the three scene-placed components that are safe to run in the editor, covering 23 of the 34 placements: IconButton (20 scenes), TouchJoystick (2), NeonPanel (1). Two of them mutate persisted properties on _ready, which under @tool would write computed values back into the .tscn every time the scene was opened, so both are guarded with Engine.is_editor_hint(): NeonPanel._fit_to_screen() rewrites all four offsets TouchJoystick._relayout() overwrites max_radius, which is @export IconButton's _gui_input is guarded too, so clicking a button on the editor canvas does not emit `pressed`. The autoload-heavy drawers (ResourceBar, PriceTag, QuestPanel, ResourceTransferList, SkillTreeView, FormationEditor - 6 to 16 GameState./Quests. references each) are left alone; they need their call sites guarded first. Verified: 172/172 headless, and a --headless --editor pass loads the project with no script errors. That pass only proves the scripts parse under @tool - it never opens a scene, so it does not exercise the in-editor _draw. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
This commit is contained in:
parent
7d1a584c15
commit
9872cb9930
3 changed files with 19 additions and 0 deletions
|
|
@ -1,3 +1,4 @@
|
|||
@tool
|
||||
class_name IconButton
|
||||
extends Control
|
||||
|
||||
|
|
@ -142,6 +143,11 @@ func _blocked_by_modal() -> bool:
|
|||
|
||||
|
||||
func _gui_input(event: InputEvent) -> void:
|
||||
# @tool runs this in the editor too, where a click on the canvas would
|
||||
# emit `pressed` at whatever it is wired to. The glyph is what we want
|
||||
# visible there, not the behaviour.
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
if _blocked_by_modal():
|
||||
return
|
||||
if event is InputEventScreenTouch:
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
@tool
|
||||
class_name NeonPanel
|
||||
extends Control
|
||||
|
||||
|
|
@ -39,6 +40,12 @@ var design_centre: Vector2 = Vector2.ZERO
|
|||
|
||||
|
||||
func _ready() -> void:
|
||||
# _fit_to_screen() below rewrites offset_left/right/top/bottom. Under
|
||||
# @tool that runs against the editor viewport, overwriting the authored
|
||||
# layout and dirtying the scene, so the card previews at its authored
|
||||
# size and is only ever fitted at runtime.
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
# Fitting adjusts the four offsets around a fixed centre, which is only
|
||||
# meaningful for a card pinned to a point - both anchor pairs collapsed,
|
||||
# as a centred dialog's are. A panel stretched between different anchors
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
@tool
|
||||
class_name TouchJoystick
|
||||
extends Control
|
||||
|
||||
|
|
@ -40,6 +41,11 @@ var knob_pos: Vector2 = Vector2.ZERO
|
|||
|
||||
|
||||
func _ready() -> void:
|
||||
# _relayout() writes max_radius, which is @export - under @tool that
|
||||
# would persist a computed value into the scene. The preview uses the
|
||||
# authored radius instead; only a running game refits.
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
# Dialogs release every spring-loaded stick through one compositional
|
||||
# contract, without NarrationBanner knowing scene paths or joystick roles.
|
||||
add_to_group("touch_joysticks")
|
||||
|
|
|
|||
Loading…
Reference in a new issue