Stop reusing one plaque for every region. The header is now a compartmented band with dividers, icons and left-aligned values; the bottom is a carved dock band with four independent command plates (icon above label, wider green primary) instead of buttons inside a long frame; the warning stack is three cards with severity icons; the summary is a parchment card with shape markers, values and pip rows; and typography uses explicit tracking and embolden so titles, values and captions read as different ranks. View contract names and z-order are unchanged.
183 lines
7.0 KiB
GDScript
183 lines
7.0 KiB
GDScript
class_name ABGPageChrome
|
|
extends Control
|
|
|
|
## Per-region drawn chrome for first-play pages.
|
|
##
|
|
## One generic plaque was previously reused as the header, the command dock,
|
|
## the warning stack and the summary, which produced large empty frames with
|
|
## floating text. Each region now gets its own structure: a compartmented
|
|
## header band, a carved command dock with independent command plates, small
|
|
## warning cards and parchment cards. Everything scales cleanly at any size and
|
|
## text stays engine-rendered.
|
|
|
|
const PAPER := Color("#f0e0bd")
|
|
const PAPER_LIGHT := Color("#faf1d8")
|
|
const PAPER_SHADE := Color("#d9c096")
|
|
const WOOD := Color("#6f4a2e")
|
|
const WOOD_LIGHT := Color("#9a6b40")
|
|
const GOLD := Color("#c2a061")
|
|
const GOLD_LIGHT := Color("#eed9a4")
|
|
const INK := Color("#2f2417")
|
|
const INK_SOFT := Color("#6a5236")
|
|
const DOCK := Color("#1d3f4a")
|
|
const DOCK_LIGHT := Color("#2d5b67")
|
|
const DOCK_DARK := Color("#12272e")
|
|
const GREEN := Color("#57813f")
|
|
const GREEN_LIGHT := Color("#7aa85f")
|
|
const STONE := Color("#4a4f52")
|
|
const RED := Color("#a8503f")
|
|
const AMBER := Color("#b98a3c")
|
|
const TEAL := Color("#4f8a8f")
|
|
const SHADOW := Color(0.05, 0.06, 0.07, 0.34)
|
|
|
|
var variant := "card"
|
|
var params: Dictionary = {}
|
|
|
|
|
|
func configure(next_variant: String, next_params: Dictionary = {}) -> ABGPageChrome:
|
|
variant = next_variant
|
|
params = next_params
|
|
return self
|
|
|
|
|
|
func _ready() -> void:
|
|
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
resized.connect(queue_redraw)
|
|
queue_redraw()
|
|
|
|
|
|
func _draw() -> void:
|
|
if size.x < 2.0 or size.y < 2.0:
|
|
return
|
|
match variant:
|
|
"header_band":
|
|
_draw_header_band()
|
|
"dock_band":
|
|
_draw_dock_band()
|
|
"command_plate":
|
|
_draw_command_plate()
|
|
"card":
|
|
_draw_card()
|
|
"warning_icon":
|
|
_draw_warning_icon()
|
|
"pip":
|
|
_draw_pip()
|
|
_:
|
|
_draw_card()
|
|
|
|
|
|
func _draw_header_band() -> void:
|
|
var rect := Rect2(2.0, 3.0, size.x - 4.0, size.y - 6.0)
|
|
_round(Rect2(rect.position + Vector2(0.0, 3.0), rect.size), 7.0, SHADOW)
|
|
_round(rect, 7.0, PAPER, GOLD, 2.0)
|
|
_round(rect.grow(-3.0), 5.0, Color(PAPER_LIGHT, 0.45), Color(PAPER_SHADE, 0.85), 1.0)
|
|
var dividers: Array = params.get("dividers", [])
|
|
for value in dividers:
|
|
var x := rect.position.x + rect.size.x * float(value)
|
|
draw_line(Vector2(x, rect.position.y + 8.0), Vector2(x, rect.end.y - 8.0), Color(GOLD, 0.75), 1.5, true)
|
|
draw_line(Vector2(rect.position.x + 10.0, rect.position.y + 1.0), Vector2(rect.end.x - 10.0, rect.position.y + 1.0), Color(PAPER_LIGHT, 0.9), 1.5, true)
|
|
|
|
|
|
func _draw_dock_band() -> void:
|
|
var rect := Rect2(0.0, 0.0, size.x, size.y)
|
|
draw_rect(Rect2(0.0, 0.0, size.x, size.y * 0.55), DOCK_LIGHT)
|
|
draw_rect(Rect2(0.0, size.y * 0.55, size.x, size.y * 0.45), DOCK)
|
|
draw_rect(Rect2(0.0, 0.0, size.x, 2.5), Color(GOLD, 0.85))
|
|
draw_rect(Rect2(0.0, 2.5, size.x, 2.0), Color(DOCK_DARK, 0.6))
|
|
draw_rect(Rect2(0.0, size.y - 3.0, size.x, 3.0), Color(DOCK_DARK, 0.7))
|
|
draw_rect(Rect2(0.0, 0.0, size.x, 1.0), Color(GOLD_LIGHT, 0.9))
|
|
|
|
|
|
func _draw_command_plate() -> void:
|
|
var state := String(params.get("state", "secondary"))
|
|
var face := PAPER
|
|
var edge := GOLD
|
|
var inner := PAPER_LIGHT
|
|
var label_line := PAPER_SHADE
|
|
match state:
|
|
"primary":
|
|
face = GREEN
|
|
edge = GOLD_LIGHT
|
|
inner = GREEN_LIGHT
|
|
label_line = Color(0.12, 0.20, 0.10, 0.35)
|
|
"disabled":
|
|
face = STONE
|
|
edge = Color("#6d7074")
|
|
inner = Color("#5c6064")
|
|
label_line = Color(0.0, 0.0, 0.0, 0.28)
|
|
var rect := Rect2(2.0, 3.0, size.x - 4.0, size.y - 7.0)
|
|
_round(Rect2(rect.position + Vector2(0.0, 4.0), rect.size), 9.0, SHADOW)
|
|
_round(rect, 9.0, WOOD, Color(0.10, 0.07, 0.05, 0.55), 1.0)
|
|
var face_rect := rect.grow(-5.0)
|
|
_round(face_rect, 6.0, face, edge, 2.0)
|
|
_round(face_rect.grow(-3.0), 4.0, Color(inner, 0.35), Color(edge, 0.55), 1.0)
|
|
draw_line(Vector2(face_rect.position.x + 8.0, face_rect.position.y + 3.0), Vector2(face_rect.end.x - 8.0, face_rect.position.y + 3.0), Color(PAPER_LIGHT, 0.55) if state != "disabled" else Color(1, 1, 1, 0.12), 1.2, true)
|
|
draw_line(Vector2(face_rect.position.x + 12.0, face_rect.end.y - 4.0), Vector2(face_rect.end.x - 12.0, face_rect.end.y - 4.0), label_line, 2.0, true)
|
|
|
|
|
|
func _draw_card() -> void:
|
|
var rect := Rect2(3.0, 3.0, size.x - 6.0, size.y - 6.0)
|
|
_round(Rect2(rect.position + Vector2(0.0, 3.0), rect.size), 7.0, SHADOW)
|
|
_round(rect, 7.0, PAPER, GOLD, 2.0)
|
|
_round(rect.grow(-3.0), 5.0, Color(PAPER_LIGHT, 0.50), Color(PAPER_SHADE, 0.85), 1.0)
|
|
draw_line(Vector2(rect.position.x + 8.0, rect.position.y + 2.0), Vector2(rect.end.x - 8.0, rect.position.y + 2.0), Color(PAPER_LIGHT, 0.85), 1.2, true)
|
|
|
|
|
|
func _draw_warning_icon() -> void:
|
|
var severity := String(params.get("severity", "warning"))
|
|
var fill := RED if severity == "warning" else AMBER if severity == "notice" else TEAL
|
|
var rect := Rect2(1.0, 1.0, size.x - 2.0, size.y - 2.0)
|
|
_round(rect, 5.0, Color(0.08, 0.06, 0.05, 0.4))
|
|
_round(rect.grow(-1.0), 4.0, fill, GOLD_LIGHT, 1.5)
|
|
var center := rect.get_center()
|
|
var bar_w := maxf(2.0, rect.size.x * 0.11)
|
|
draw_rect(Rect2(center.x - bar_w * 0.5, rect.position.y + rect.size.y * 0.26, bar_w, rect.size.y * 0.36), Color(PAPER_LIGHT, 0.95))
|
|
draw_circle(Vector2(center.x, rect.position.y + rect.size.y * 0.74), bar_w * 0.62, Color(PAPER_LIGHT, 0.95))
|
|
|
|
|
|
func _draw_pip() -> void:
|
|
var shape := String(params.get("shape", "circle"))
|
|
var filled := bool(params.get("filled", false))
|
|
var rect := Rect2(1.5, 1.5, size.x - 3.0, size.y - 3.0)
|
|
var line := Color(GOLD, 0.95) if filled else Color(GOLD, 0.55)
|
|
match shape:
|
|
"shield":
|
|
var points := PackedVector2Array([
|
|
Vector2(rect.position.x + rect.size.x * 0.5, rect.position.y),
|
|
Vector2(rect.end.x, rect.position.y + rect.size.y * 0.28),
|
|
Vector2(rect.end.x - rect.size.x * 0.16, rect.end.y),
|
|
Vector2(rect.position.x + rect.size.x * 0.16, rect.end.y),
|
|
Vector2(rect.position.x, rect.position.y + rect.size.y * 0.28)
|
|
])
|
|
if filled:
|
|
draw_colored_polygon(points, Color(GOLD, 0.35))
|
|
draw_polyline(points + PackedVector2Array([points[0]]), line, 1.6, true)
|
|
"diamond":
|
|
var center := rect.get_center()
|
|
var radius := minf(rect.size.x, rect.size.y) * 0.5
|
|
var diamond := PackedVector2Array([center + Vector2(0, -radius), center + Vector2(radius, 0), center + Vector2(0, radius), center + Vector2(-radius, 0)])
|
|
if filled:
|
|
draw_colored_polygon(diamond, Color(GOLD, 0.35))
|
|
draw_polyline(diamond + PackedVector2Array([diamond[0]]), line, 1.6, true)
|
|
_:
|
|
var center := rect.get_center()
|
|
var radius := minf(rect.size.x, rect.size.y) * 0.42
|
|
if filled:
|
|
draw_circle(center, radius * 0.8, Color(GOLD, 0.35))
|
|
draw_arc(center, radius, 0.0, TAU, 22, line, 1.6, true)
|
|
if filled:
|
|
draw_circle(rect.get_center(), 1.4, Color(GOLD, 0.95))
|
|
|
|
|
|
func _round(rect: Rect2, radius: float, fill: Color, border := Color(0, 0, 0, 0), width := 0.0) -> void:
|
|
var style := StyleBoxFlat.new()
|
|
style.bg_color = fill
|
|
style.corner_radius_top_left = int(radius)
|
|
style.corner_radius_top_right = int(radius)
|
|
style.corner_radius_bottom_left = int(radius)
|
|
style.corner_radius_bottom_right = int(radius)
|
|
if width > 0.0:
|
|
style.border_color = border
|
|
style.set_border_width_all(int(width))
|
|
draw_style_box(style, rect)
|