extends RefCounted ## Compact industrial service UI shared by the three operational rooms. const COMPACT := preload("res://scripts/ui/compact_interface.gd") const TEXT := Color("dce1dc") const MUTED := Color("8faaa7") const GOLD := Color("dfb775") const ORDER := ["workshop","storage","hangar"] static func style(panel: PanelContainer, inset := 8, opacity := COMPACT.WINDOW_ALPHA) -> void: var box := StyleBoxFlat.new() box.bg_color = Color(Color("131e23"),minf(opacity, 0.64)) box.border_color = Color("536463") box.set_border_width_all(1) box.set_corner_radius_all(COMPACT.CORNER_RADIUS) box.set_content_margin_all(inset) box.shadow_color = Color(0,0,0,0.4) box.shadow_size = 4 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",COMPACT.font_size(font_size-2)) node.add_theme_color_override("font_color",color) node.add_theme_color_override("font_shadow_color",Color(0,0,0,0.75)) node.add_theme_constant_override("shadow_offset_y",1) 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 = 28 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.48 if state == "normal" else 0.62 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,6,COMPACT.CARD_ALPHA) 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)