Files
settled-reach/client/ui/news_ticker.gd
T
jpmschweitzerandClaude Opus 4.6 4eb54a6f7a fix(client): resolve all gdlint warnings — zero warnings policy
Fix 354 gdlint warnings across 65 files: 194 class-definitions-order
(reorder declarations), 138 max-line-length (split long lines),
22 code issues (unused args, no-else-return, naming). Update .gdlintrc
to exclude addons/ and raise max-public-methods for test files.
No logic changes — declaration order, whitespace, and naming only.

Ticket: #783

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 09:59:56 +02:00

60 lines
1.9 KiB
GDScript

extends Control
## #592: News ticker — scrolling horizontal headline bar, active in The Last Shift zone.
## Lives on UILayer (z-layer 7 per D-049). Not suppressed by insert_active (D-013):
## the ticker is a real-world screen the player can see regardless of insert state.
## Text scrolls left at SCROLL_SPEED px/sec. When current_ticker is null, hides.
const BG_COLOR := Color(0.05, 0.05, 0.07, 0.75)
const TEXT_COLOR := Color(0.784, 0.816, 0.878, 1.0) # INSERT_COLOR_TEXT
const FONT_SIZE := 13
const SCROLL_SPEED := 60.0 # pixels per second
const BAR_HEIGHT := 28
var _text: String = ""
var _scroll_x: float = 0.0
var _content_width: float = 0.0
@onready var _label: Label = $TickerLabel
func _ready() -> void:
mouse_filter = Control.MOUSE_FILTER_IGNORE
_label.add_theme_font_size_override("font_size", FONT_SIZE)
_label.add_theme_color_override("font_color", TEXT_COLOR)
visible = false
func update_from_state() -> void:
var ticker: Variant = GameState.current_snapshot.get("current_ticker")
if ticker == null or not ticker is Dictionary:
visible = false
return
var new_text: String = ticker.get("text", "")
if new_text.is_empty():
visible = false
return
if new_text != _text:
_text = new_text
_label.text = _text
# Reset scroll to start from right edge on new headline.
# Defer width read by one frame: get_minimum_size() returns stale
# data if called before the layout pass that follows text assignment.
_scroll_x = size.x
_content_width = 0.0 # will be updated after layout in _process
call_deferred("_update_content_width")
visible = true
func _update_content_width() -> void:
_content_width = _label.get_minimum_size().x
func _process(delta: float) -> void:
if not visible:
return
_scroll_x -= SCROLL_SPEED * delta
# Restart from right edge when text has fully exited left.
if _scroll_x + _content_width < 0.0:
_scroll_x = size.x
_label.position.x = _scroll_x