Addresses Tyre's 9 architecture items from the sprint-36 client review. - decisions/architecture.md (Tyre #1): D-192 now says "deprecate; removal tracked in #868" instead of "remove". The branch does not remove the version field or guard — that belongs in the coordinated server+client PR. The decision text now matches the code on this branch. - meta_stack.gd (#2): handle_escape() on a screen with closable_by_escape=false now consumes the event unconditionally. Was returning whatever on_escape() returned, which default-returned false and leaked ESC into main.gd's implant/settings chain — opening the settings dialog behind the loading screen. - debug_console.gd (#4): drop the direct KEY_ESCAPE branch in _unhandled_input. ESC now falls through to main.gd → MetaStack, which finds the console on top of the stack and closes it via the normal path. Other keys are still consumed so movement/action can't leak. - main.gd (#6, #10): extract the ESC priority chain into _handle_menu_key() so "MetaStack → implant → settings" is a named thing. Add a comment near connect_to_sim explaining that GameState.bookmark_catalog survives the Option A scene transition via the autoload. - main_menu.gd (#7): header comment documenting the double LoadingScreen lifecycle — safe today because main_menu.tscn and main.tscn never co-exist, noted for future promotion to autoload if that changes. - meta_screen.gd (#8): apply captures_input symmetrically in open()/ close() — was set in open() only, so a screen changing the flag between open+close kept the opened value forever. - meta_screen.gd (#9): on_escape() docstring clarifies the tri-state (consume-and-hold / consume-and-close / ignore) — and that closable_by_escape=false is the screen-wide way to say "consume-and-hold". - bug_report_dialog.gd (#11): capture_cancelled now emits from on_close() (covers any close path — ESC, MetaStack pop, programmatic close) rather than only on_escape(). A new _completed flag distinguishes completion from cancel so the two signals stay mutually exclusive.
70 lines
1.8 KiB
GDScript
70 lines
1.8 KiB
GDScript
class_name MetaScreen
|
|
extends Control
|
|
## Base class for all meta-UI screens (#618, #680).
|
|
## Scene-root screens (main_menu, character_creation) extend this for the
|
|
## lifecycle contract. Overlay screens (settings, debug_console, bug_report,
|
|
## loading_screen) extend this AND push onto MetaStack.
|
|
|
|
signal closed
|
|
signal escape_pressed
|
|
|
|
enum Phase { HIDDEN, OPENING, OPEN, CLOSING }
|
|
|
|
@export var pauses_sim: bool = false
|
|
@export var closable_by_escape: bool = true
|
|
@export var captures_input: bool = true
|
|
|
|
var _phase: Phase = Phase.HIDDEN
|
|
|
|
|
|
func open() -> void:
|
|
if _phase != Phase.HIDDEN:
|
|
return
|
|
_phase = Phase.OPENING
|
|
visible = true
|
|
mouse_filter = Control.MOUSE_FILTER_STOP if captures_input else Control.MOUSE_FILTER_IGNORE
|
|
on_open()
|
|
_phase = Phase.OPEN
|
|
|
|
|
|
func close() -> void:
|
|
if _phase != Phase.OPEN:
|
|
return
|
|
_phase = Phase.CLOSING
|
|
on_close()
|
|
visible = false
|
|
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
_phase = Phase.HIDDEN
|
|
closed.emit()
|
|
|
|
|
|
func is_open() -> bool:
|
|
return _phase == Phase.OPEN
|
|
|
|
|
|
## Called by MetaStack when ESC is pressed with this screen on top.
|
|
##
|
|
## Return true: consumed-and-held — keep this screen open (e.g. "are you sure"
|
|
## prompt was shown, do not close the underlying screen).
|
|
## Return false: did nothing internally — let MetaStack close this screen.
|
|
##
|
|
## To express "consume-and-hold" — the screen must remain open and ESC must NOT
|
|
## fall through to gameplay/implant — set `closable_by_escape = false` instead.
|
|
## MetaStack treats that as: call on_escape (to let the screen react), do not
|
|
## pop, return true so the event stops here. Returning true from `on_escape` is
|
|
## the per-event variant; setting the flag is the screen-wide variant.
|
|
func on_escape() -> bool:
|
|
escape_pressed.emit()
|
|
return false
|
|
|
|
|
|
# --- Lifecycle hooks — subclasses override ---
|
|
|
|
|
|
func on_open() -> void:
|
|
pass
|
|
|
|
|
|
func on_close() -> void:
|
|
pass
|