Unify action-button states across the UI
Full build / Import + headless tests (push) Successful in 39s
Full build / Full desktop build + optional release (push) Skipped

- Add UiStyles with explicit normal, hover, pressed, focus and disabled styles and apply it to every action button.
- Disable timeline Previous/Next at the first/last event and keep Close always available.
- Style settings reset-dialog buttons and cover the button-state audit in docs/ui-copy.md.
- Add shared-state and timeline-boundary regression tests.
This commit is contained in:
Gig Line Dev committed 2026-11-02 15:04:38 +01:00
1 parent 98c31fe44c
commit 9692f262f1
15 files changed
+172 -75

No files matched your search

+8 -1
View File
@@ -79,14 +79,21 @@ func test_empty_timeline_is_safe() -> bool:
func test_stepping_clamps() -> bool:
var timeline: Node = EventTimeline.new()
timeline.show_timeline(_review())
var prev: Button = timeline.find_child("PrevButton", true, false) as Button
var next: Button = timeline.find_child("NextButton", true, false) as Button
var start_prev_disabled := prev != null and prev.disabled
var start_next_enabled := next != null and not next.disabled
timeline.step(-1)
var a := TestUtils.check_eq(timeline.index, 0, "cannot step before the first event")
timeline.step(1)
var b := TestUtils.check_eq(timeline.index, 1, "next advances one event")
timeline.step(99)
var c := TestUtils.check_eq(timeline.index, 3, "cannot step past the last event")
var end_next_disabled := next != null and next.disabled
var d := TestUtils.check(start_prev_disabled and start_next_enabled and end_next_disabled,
"timeline boundary buttons disable at the ends")
timeline.free()
return a and b and c
return a and b and c and d
func test_review_records_a_shift_start_stamp() -> bool:
var coordinator: Object = Coordinator.new()
+26
View File
@@ -0,0 +1,26 @@
extends RefCounted
## Shared UI button states: every normal/hover/pressed/focus/disabled state is
## explicitly styled so the custom dark panels do not fall back to the engine
## theme when a control is focused or disabled.
const UiStyles := preload("res://src/game/ui/ui_styles.gd")
func test_shared_button_states_are_complete() -> bool:
var button := Button.new()
UiStyles.apply_button(button, 16)
var states := ["normal", "hover", "pressed", "focus", "disabled"]
var missing: Array[String] = []
for state in states:
if not button.has_theme_stylebox_override(state):
missing.append(state)
var a := TestUtils.check(missing.is_empty(),
"all five button states have explicit styles (missing: %s)" % str(missing))
var b := TestUtils.check_eq(button.get_theme_font_size("font_size"), 16,
"the shared style applies the requested font size")
var disabled := button.get_theme_stylebox("disabled")
var normal := button.get_theme_stylebox("normal")
var c := TestUtils.check(disabled != null and normal != null
and disabled.bg_color != normal.bg_color,
"the disabled state is visually distinct from normal")
button.free()
return a and b and c