Harden UI layout for font scale and long strings
- Measure and cap the HUD target chip after each font-scale change; clip HUD top labels. - Ellipsize long action-button labels so panels cannot grow past the viewport. - Add accessibility/button layout assertions and refresh the gallery captures. - Record the font/layout pass in TODO, docs, changelog and memory.
This commit is contained in:
1 parent
26e6dd6413
commit
f6aa26e6ca
20 files changed
+69
-7
No files matched your search
@@ -82,9 +82,11 @@ func _init() -> void:
|
||||
|
||||
top_label = Label.new()
|
||||
top_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
top_label.clip_text = true
|
||||
top.add_child(top_label)
|
||||
|
||||
time_label = Label.new()
|
||||
time_label.clip_text = true
|
||||
top.add_child(time_label)
|
||||
|
||||
var spacer := Control.new()
|
||||
@@ -122,6 +124,7 @@ func _init() -> void:
|
||||
target_label = Label.new()
|
||||
target_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
target_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
target_label.clip_text = true
|
||||
target_label.add_theme_font_size_override("font_size", 17)
|
||||
_target_chip.add_child(target_label)
|
||||
|
||||
@@ -394,6 +397,17 @@ func set_target_label(text: String) -> void:
|
||||
target_label.text = text
|
||||
if _target_chip:
|
||||
_target_chip.visible = text.strip_edges() != ""
|
||||
# The chip is fixed around the crosshair; widen it for long names and
|
||||
# larger HUD font scales instead of letting the text spill over the world.
|
||||
var font := target_label.get_theme_font("font")
|
||||
var font_size := target_label.get_theme_font_size("font_size")
|
||||
var text_width := font.get_string_size(text, HORIZONTAL_ALIGNMENT_LEFT, -1.0, font_size).x
|
||||
var chip_width := clampf(text_width + 32.0, 180.0, 420.0)
|
||||
_target_chip.offset_left = -chip_width * 0.5
|
||||
_target_chip.offset_right = chip_width * 0.5
|
||||
var chip_height := maxf(40.0, font.get_height(font_size) + 16.0)
|
||||
_target_chip.offset_top = 38.0
|
||||
_target_chip.offset_bottom = 38.0 + chip_height
|
||||
|
||||
## How many people the aim-free ring (Tab / mouse wheel) can cycle through.
|
||||
func set_nearby_hint(count: int) -> void:
|
||||
@@ -447,6 +461,9 @@ func set_font_scale(scale: float) -> void:
|
||||
_base_font_sizes[label] = label.get_theme_font_size("font_size")
|
||||
var base: int = int(_base_font_sizes[label])
|
||||
label.add_theme_font_size_override("font_size", maxi(8, int(round(float(base) * clamped))))
|
||||
# Recompute the target chip after its font size changed.
|
||||
if target_label:
|
||||
set_target_label(target_label.text)
|
||||
|
||||
func _make_icon(texture: Texture2D) -> TextureRect:
|
||||
var tr := TextureRect.new()
|
||||
|
||||
@@ -21,6 +21,10 @@ static func apply_button(button: Button, font_size: int = 0, compact: bool = fal
|
||||
return
|
||||
if font_size > 0:
|
||||
button.add_theme_font_size_override("font_size", font_size)
|
||||
# Long localized labels must not push a panel past the viewport. The
|
||||
# buttons keep their existing minimum width and ellipsize if needed.
|
||||
button.clip_text = true
|
||||
button.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
|
||||
var margin_h := 12 if compact else 18
|
||||
var margin_v := 7 if compact else 10
|
||||
var normal := _box(SURFACE, margin_h, margin_v)
|
||||
|
||||
@@ -49,8 +49,18 @@ func test_font_scale_applies_to_core_labels() -> bool:
|
||||
hud.set_font_scale(9.0)
|
||||
var capped: int = hud.top_label.get_theme_font_size("font_size")
|
||||
var f := TestUtils.check(capped <= int(round(float(base_top) * 1.75)) + 1, "scale clamps at 1.75")
|
||||
# The target chip must widen with the scaled font instead of spilling over
|
||||
# the world; an extreme name is capped rather than pushing off-screen.
|
||||
hud.set_font_scale(1.75)
|
||||
hud.set_target_label("Intoxicated Pedestrian")
|
||||
var chip = hud.get("_target_chip")
|
||||
var chip_width: float = float(chip.offset_right) - float(chip.offset_left)
|
||||
var g := TestUtils.check(chip_width > 300.0, "target chip widens at max font scale")
|
||||
hud.set_target_label("An Extraordinarily Long Display Name For A Visitor In A Pseudo Locale")
|
||||
var long_width: float = float(chip.offset_right) - float(chip.offset_left)
|
||||
var h := TestUtils.check(long_width <= 420.5, "target chip caps an extreme name")
|
||||
hud.free()
|
||||
return a and b and c and d and e and f
|
||||
return a and b and c and d and e and f and g and h
|
||||
|
||||
func test_settings_font_scale_is_applied_after_ui_exists() -> bool:
|
||||
## The HUD is created after settings load, so the manager must re-apply.
|
||||
|
||||
@@ -23,8 +23,12 @@ func test_shared_button_states_are_complete() -> bool:
|
||||
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.text = "A very long localized action label that must not push the panel beyond the viewport"
|
||||
var d := TestUtils.check(button.clip_text
|
||||
and button.get_combined_minimum_size().x < 100.0,
|
||||
"long action labels ellipsize instead of forcing a wide panel")
|
||||
button.free()
|
||||
return a and b and c
|
||||
return a and b and c and d
|
||||
|
||||
func test_focus_helper_skips_hidden_and_disabled_controls() -> bool:
|
||||
var hidden := Button.new()
|
||||
|
||||
Reference in new issue
Block a user