Files
aetherbound-guild/runtime/ui/shared/shared_button.gd
T

108 lines
3.3 KiB
GDScript

class_name ABGSharedButton
extends Button
const Tokens = preload("res://foundation/ui_tokens.gd")
## Generic semantic button. It emits the built-in `pressed` intent and owns no
## game state, save behavior or page lookup.
var semantic_variant := "secondary"
var selected_state := false
var busy_state := false
var _refreshing := false
func _ready() -> void:
focus_mode = Control.FOCUS_ALL
custom_minimum_size = Tokens.touch_size(custom_minimum_size)
_refresh_style()
func configure(next_text: String, next_variant := "secondary"):
text = next_text
semantic_variant = next_variant if Tokens.is_supported_variant(next_variant) else "secondary"
_refresh_style()
return self
func set_view_state(enabled := true, selected := false, busy := false) -> void:
disabled = not enabled
selected_state = selected
busy_state = busy
_refresh_style()
func _refresh_style() -> void:
if _refreshing:
return
if not is_inside_tree() and get_parent() == null:
return
_refreshing = true
var normal_fill := Tokens.COLOR_NAVY
var hover_fill := Tokens.COLOR_NAVY_LIFT
var pressed_fill := Tokens.COLOR_NAVY_LIFT
var border := Tokens.COLOR_GOLD
if semantic_variant == "primary":
normal_fill = Color("#e8d9b7")
hover_fill = Color("#fff1c9")
pressed_fill = Color("#d7c39a")
border = Color("#806536")
elif semantic_variant == "danger":
normal_fill = Color("#4d2830")
hover_fill = Color("#68343d")
pressed_fill = Color("#3b2027")
border = Tokens.COLOR_DANGER
elif semantic_variant == "icon":
normal_fill = Color(Tokens.COLOR_NAVY, 0.72)
hover_fill = Tokens.COLOR_NAVY_LIFT
pressed_fill = Tokens.COLOR_NAVY
border = Tokens.COLOR_SKY
if selected_state:
hover_fill = Color("#34506a")
border = Tokens.COLOR_SKY
if disabled:
normal_fill = Tokens.COLOR_NAVY_DISABLED
hover_fill = normal_fill
pressed_fill = normal_fill
border = Tokens.COLOR_MUTED
var text_color := Tokens.COLOR_IVORY
if semantic_variant == "primary":
text_color = Tokens.COLOR_INK
if disabled:
text_color = Color("#a1a8aa")
add_theme_color_override("font_color", text_color)
add_theme_color_override("font_hover_color", text_color)
add_theme_color_override("font_pressed_color", text_color)
add_theme_color_override("font_focus_color", text_color)
add_theme_font_size_override("font_size", Tokens.font_size("label"))
add_theme_stylebox_override("normal", _style_box(normal_fill, border))
add_theme_stylebox_override("hover", _style_box(hover_fill, border))
add_theme_stylebox_override("pressed", _style_box(pressed_fill, border))
add_theme_stylebox_override("disabled", _style_box(normal_fill, border))
add_theme_stylebox_override("focus", _focus_box(border))
_refreshing = false
func _style_box(fill: Color, border: Color) -> StyleBoxFlat:
var box := StyleBoxFlat.new()
box.bg_color = fill
box.border_color = border
box.set_border_width_all(1)
box.corner_radius_top_left = 6
box.corner_radius_top_right = 6
box.corner_radius_bottom_left = 6
box.corner_radius_bottom_right = 6
box.content_margin_left = 12.0
box.content_margin_right = 12.0
box.content_margin_top = 8.0
box.content_margin_bottom = 8.0
return box
func _focus_box(border: Color) -> StyleBoxFlat:
var box := _style_box(Color(0, 0, 0, 0), Tokens.COLOR_SKY)
box.set_border_width_all(2)
box.shadow_color = Color(border, 0.32)
box.shadow_size = 3
return box