Randoloot/scripts/planets/freighter_menu.gd
2026-10-18 18:47:18 +02:00

102 lines
3.9 KiB
GDScript

extends RefCounted
## Compact industrial service UI shared by the three operational rooms.
const TEXT := Color("dce1dc")
const MUTED := Color("8faaa7")
const GOLD := Color("dfb775")
const ORDER := ["workshop","storage","hangar"]
static func style(panel: PanelContainer, inset := 12, opacity := 0.86) -> void:
var box := StyleBoxFlat.new()
box.bg_color = Color(Color("131e23"),opacity)
box.border_color = Color("536463")
box.set_border_width_all(1)
box.set_corner_radius_all(7)
box.set_content_margin_all(inset)
box.shadow_color = Color(0,0,0,0.4)
box.shadow_size = 10
panel.add_theme_stylebox_override("panel",box)
static func label(parent: Node, value: String, font_size := 13, color := TEXT) -> Label:
var node := Label.new()
node.text = value
node.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
node.add_theme_font_override("font",ThemeDB.fallback_font)
node.add_theme_font_size_override("font_size",maxi(10,font_size-2))
node.add_theme_color_override("font_color",color)
parent.add_child(node)
return node
static func button(parent: Node, value: String, action: Callable, primary := false) -> Button:
var node := Button.new()
node.text = value
node.autowrap_mode = TextServer.AUTOWRAP_OFF
node.custom_minimum_size.y = 32
node.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
node.add_theme_font_override("font",ThemeDB.fallback_font)
node.add_theme_font_size_override("font_size",11)
node.add_theme_color_override("font_color",TEXT)
node.add_theme_color_override("font_disabled_color",Color("6c7b7a"))
for state in ["normal","hover","pressed","disabled","focus"]:
var box := StyleBoxFlat.new()
box.bg_color = Color("425a57") if primary else Color("25343b")
if state == "hover": box.bg_color = Color("526b64")
if state == "pressed": box.bg_color = Color("354b46")
if state == "disabled": box.bg_color = Color("1b272c")
box.bg_color.a = 0.92
box.border_color = GOLD if primary else Color("4b6569")
if state == "focus": box.border_color = GOLD
box.set_border_width_all(1)
box.set_corner_radius_all(4)
box.content_margin_left = 10
box.content_margin_right = 10
box.content_margin_top = 5
box.content_margin_bottom = 5
node.add_theme_stylebox_override(state,box)
node.pressed.connect(action)
parent.add_child(node)
return node
static func row(parent: Node) -> HBoxContainer:
var node := HBoxContainer.new()
node.add_theme_constant_override("separation",10)
parent.add_child(node)
return node
static func card(parent: Node) -> VBoxContainer:
var panel := PanelContainer.new()
panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL
style(panel,10,0.70)
parent.add_child(panel)
var stack := VBoxContainer.new()
stack.add_theme_constant_override("separation",6)
panel.add_child(stack)
return stack
static func icon(parent: Node, texture: Texture2D, edge := 40) -> TextureRect:
var node := TextureRect.new()
node.texture = texture
node.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
node.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
node.custom_minimum_size = Vector2(edge,edge)
node.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR_WITH_MIPMAPS
parent.add_child(node)
return node
static func hero(parent: Node, section: String, subtitle: String) -> void:
var texture: Texture2D = load("res://assets/freighter/section_headers.png")
var image := AtlasTexture.new()
image.atlas = texture
var extent := Vector2(texture.get_size())
var rows := [0.0,0.318,0.637,1.0]
var index := ORDER.find(section)
image.region = Rect2(Vector2(3,rows[index]*extent.y+3),Vector2(extent.x-6,(rows[index+1]-rows[index])*extent.y-6))
image.filter_clip = true
var art := TextureRect.new()
art.texture = image
art.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
art.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_COVERED
art.custom_minimum_size.y = 76 if section != "storage" else 64
art.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR_WITH_MIPMAPS
parent.add_child(art)
if not subtitle.is_empty(): label(parent,subtitle,12,MUTED)