148 lines
5.6 KiB
GDScript
148 lines
5.6 KiB
GDScript
extends CanvasLayer
|
||
## Shared responsive menu shell. No native window chrome or system dialogs.
|
||
signal closed
|
||
|
||
const INK := Color("ecf2ed")
|
||
const MUTED := Color("8fa8b7")
|
||
const CYAN := Color("83d4df")
|
||
const GOLD := Color("edbc7c")
|
||
const DISPLAY_FONT := preload("res://assets/fonts/font2.ttf")
|
||
var heading := ""
|
||
var subtitle := ""
|
||
var marker := "RANDOLOOT / SYSTEMY POKŁADOWE"
|
||
var preferred_size := Vector2(780,590)
|
||
var body: VBoxContainer
|
||
var footer: HBoxContainer
|
||
var panel: PanelContainer
|
||
var _root: Control
|
||
var _closing := false
|
||
|
||
func _ready() -> void:
|
||
process_mode = Node.PROCESS_MODE_ALWAYS
|
||
layer = 140
|
||
_root = Control.new()
|
||
_root.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||
add_child(_root)
|
||
var shade := ColorRect.new()
|
||
shade.color = Color(0.005,0.012,0.025,0.78)
|
||
shade.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||
_root.add_child(shade)
|
||
panel = PanelContainer.new()
|
||
panel.add_theme_stylebox_override("panel", box(Color("0b1825"),Color("416471"),24))
|
||
_root.add_child(panel)
|
||
var column := VBoxContainer.new()
|
||
column.add_theme_constant_override("separation",16)
|
||
panel.add_child(column)
|
||
var top := HBoxContainer.new()
|
||
column.add_child(top)
|
||
var eyebrow := label(top,tr(marker),10,CYAN)
|
||
eyebrow.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
var close_button := button(top,"×",_close,false)
|
||
close_button.custom_minimum_size = Vector2(32,30)
|
||
close_button.add_theme_font_size_override("font_size",20)
|
||
close_button.tooltip_text = tr("Zamknij") + " · Esc"
|
||
var title := label(column,tr(heading),28,INK)
|
||
title.add_theme_font_override("font",DISPLAY_FONT)
|
||
if not subtitle.is_empty():
|
||
var description := label(column,tr(subtitle),13,MUTED)
|
||
description.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||
column.add_child(rule())
|
||
var scroll := ScrollContainer.new()
|
||
scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||
scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
||
column.add_child(scroll)
|
||
body = VBoxContainer.new()
|
||
body.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
body.add_theme_constant_override("separation",16)
|
||
scroll.add_child(body)
|
||
column.add_child(rule())
|
||
footer = HBoxContainer.new()
|
||
footer.alignment = BoxContainer.ALIGNMENT_END
|
||
footer.add_theme_constant_override("separation",10)
|
||
column.add_child(footer)
|
||
get_viewport().size_changed.connect(_layout)
|
||
panel.minimum_size_changed.connect(_layout)
|
||
_layout.call_deferred()
|
||
|
||
func _layout() -> void:
|
||
var viewport_size := get_viewport().get_visible_rect().size
|
||
var extent := preferred_size.min(viewport_size-Vector2(48,48))
|
||
panel.size = extent
|
||
var factor := minf(1.0,minf((viewport_size.x-48)/maxf(1,panel.size.x),(viewport_size.y-48)/maxf(1,panel.size.y)))
|
||
panel.scale = Vector2.ONE*factor
|
||
panel.position = (viewport_size-panel.size*factor)*0.5
|
||
|
||
func _unhandled_input(event: InputEvent) -> void:
|
||
if visible and event is InputEventKey and event.pressed and not event.echo and event.keycode == KEY_ESCAPE:
|
||
get_viewport().set_input_as_handled()
|
||
_close()
|
||
|
||
func _close() -> void:
|
||
if _closing: return
|
||
_closing = true
|
||
hide()
|
||
closed.emit()
|
||
queue_free()
|
||
|
||
func popup_centered() -> void:
|
||
show()
|
||
_layout()
|
||
|
||
static func box(background: Color, border: Color, margin: int = 14) -> StyleBoxFlat:
|
||
var style := StyleBoxFlat.new()
|
||
style.bg_color = background
|
||
style.border_color = border
|
||
style.set_border_width_all(1)
|
||
style.set_corner_radius_all(9)
|
||
style.set_content_margin_all(margin)
|
||
style.shadow_color = Color(0,0,0,0.25)
|
||
style.shadow_size = 12
|
||
return style
|
||
|
||
static func rule() -> ColorRect:
|
||
var line := ColorRect.new()
|
||
line.custom_minimum_size.y = 1
|
||
line.color = Color("304653")
|
||
return line
|
||
|
||
static func label(parent: Node, caption: String, font_size: int = 14, color: Color = INK) -> Label:
|
||
var node := Label.new()
|
||
node.text = caption
|
||
node.add_theme_font_override("font",ThemeDB.fallback_font)
|
||
node.add_theme_font_size_override("font_size",font_size)
|
||
node.add_theme_color_override("font_color",color)
|
||
parent.add_child(node)
|
||
return node
|
||
|
||
static func button(parent: Node, caption: String, action: Callable, primary: bool = false) -> Button:
|
||
var node := Button.new()
|
||
node.text = caption
|
||
node.custom_minimum_size = Vector2(112,42)
|
||
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",14)
|
||
style_button(node, primary)
|
||
node.pressed.connect(action)
|
||
parent.add_child(node)
|
||
return node
|
||
|
||
static func style_button(node: Button, primary: bool = false) -> void:
|
||
var accent := GOLD if primary else CYAN
|
||
node.add_theme_color_override("font_color",INK)
|
||
node.add_theme_color_override("font_hover_color",Color.WHITE)
|
||
node.add_theme_color_override("font_disabled_color",Color("617681"))
|
||
node.add_theme_stylebox_override("normal",box(Color("30291f") if primary else Color("102431"),Color(accent,0.45),10))
|
||
node.add_theme_stylebox_override("hover",box(Color("453725") if primary else Color("1b3b4a"),accent,10))
|
||
node.add_theme_stylebox_override("pressed",box(Color("3c3023") if primary else Color("183b47"),accent,10))
|
||
node.add_theme_stylebox_override("disabled",box(Color("101b24"),Color("293d48"),10))
|
||
node.add_theme_stylebox_override("focus",box(Color(0,0,0,0),accent,10))
|
||
|
||
static func input_style(node: Control) -> void:
|
||
node.add_theme_font_override("font",ThemeDB.fallback_font)
|
||
node.add_theme_font_size_override("font_size",15)
|
||
node.add_theme_color_override("font_color",INK)
|
||
if node is LineEdit:
|
||
node.add_theme_stylebox_override("normal",box(Color("07131d"),Color("345461"),12))
|
||
node.add_theme_stylebox_override("focus",box(Color("0c1e2b"),CYAN,12))
|
||
elif node is Button: style_button(node)
|