Align the body-camera timeline with its sidebar mockup

Draw body_camera_timeline behind a full-height narrow panel, constrain the
content to that column, wrap long event text, and scroll the event list so the
Previous/Next/Close row stays pinned at the bottom. Headless 226/226 verified in
a clean HEAD worktree.
This commit is contained in:
zwitschi committed 2026-11-01 16:30:17 +01:00
1 parent 8032999a4d
commit 06a4f5479f
2 files changed
+33 -17

No files matched your search

+1 -1
View File
@@ -58,7 +58,7 @@ and scene visuals with those mockups — verified with
- [ ] Make the HUD match the `targeting_npc` / `escalation_hud` mockups (focus ring, escalation meter, log, hints).
- [x] Align the pause, settings, and shift-review panels to their mockups.
- [x] Align the radio and wand panels to their mockups.
- [ ] Align the body-camera timeline to its mockup.
- [x] Align the body-camera timeline to its mockup.
- [ ] Align scene lighting, fog, and post-processing for `venue_overview` and `late_night_avenue`.
### Verify against the mockups
+32 -16
View File
@@ -8,6 +8,7 @@ extends CanvasLayer
signal closed()
const Strings := preload("res://src/core/strings.gd")
const UiArt := preload("res://src/game/ui/art.gd")
var events: Array[Dictionary] = []
var index := 0
@@ -29,24 +30,34 @@ func _build() -> void:
_root.mouse_filter = Control.MOUSE_FILTER_STOP
add_child(_root)
var dim := ColorRect.new()
dim.color = Color(0.02, 0.03, 0.05, 0.9)
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
dim.mouse_filter = Control.MOUSE_FILTER_IGNORE
_root.add_child(dim)
var panel_rect := Rect2(0.293, 0.0, 0.345, 1.0)
var art := UiArt.new()
if not art.add_screen_backdrop(_root, "body_camera_timeline", panel_rect):
var dim := ColorRect.new()
dim.color = Color(0.02, 0.03, 0.05, 0.9)
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
dim.mouse_filter = Control.MOUSE_FILTER_IGNORE
_root.add_child(dim)
var center := CenterContainer.new()
center.set_anchors_preset(Control.PRESET_FULL_RECT)
_root.add_child(center)
var column_host := MarginContainer.new()
column_host.set_anchor(SIDE_LEFT, panel_rect.position.x)
column_host.set_anchor(SIDE_TOP, panel_rect.position.y)
column_host.set_anchor(SIDE_RIGHT, panel_rect.position.x + panel_rect.size.x)
column_host.set_anchor(SIDE_BOTTOM, panel_rect.position.y + panel_rect.size.y)
column_host.add_theme_constant_override("margin_left", 16)
column_host.add_theme_constant_override("margin_right", 16)
column_host.add_theme_constant_override("margin_top", 18)
column_host.add_theme_constant_override("margin_bottom", 18)
_root.add_child(column_host)
var column := VBoxContainer.new()
column.custom_minimum_size = Vector2(760, 0)
column.add_theme_constant_override("separation", 8)
center.add_child(column)
column_host.add_child(column)
var title := Label.new()
title.text = Strings.lookup("timeline.title")
title.add_theme_font_size_override("font_size", 26)
title.add_theme_font_size_override("font_size", 20)
title.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
column.add_child(title)
@@ -58,17 +69,21 @@ func _build() -> void:
_detail_label = Label.new()
_detail_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
_detail_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
_detail_label.custom_minimum_size = Vector2(760, 48)
_detail_label.add_theme_font_size_override("font_size", 18)
_detail_label.custom_minimum_size = Vector2(0, 44)
_detail_label.add_theme_font_size_override("font_size", 15)
column.add_child(_detail_label)
var list_scroll := ScrollContainer.new()
list_scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
list_scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
column.add_child(list_scroll)
_list_label = Label.new()
_list_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT
_list_label.autowrap_mode = TextServer.AUTOWRAP_OFF
_list_label.custom_minimum_size = Vector2(760, 0)
_list_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
_list_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
_list_label.add_theme_font_size_override("font_size", 13)
_list_label.add_theme_color_override("font_color", Color(0.8, 0.84, 0.9))
column.add_child(_list_label)
list_scroll.add_child(_list_label)
var row := HBoxContainer.new()
row.alignment = BoxContainer.ALIGNMENT_CENTER
@@ -95,6 +110,7 @@ func _build() -> void:
var hint := Label.new()
hint.text = Strings.lookup("timeline.hint")
hint.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
hint.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
hint.add_theme_color_override("font_color", Color(0.55, 0.58, 0.65))
column.add_child(hint)