Files
step3/scripts/ui/ui_style.gd
T

210 lines
8.6 KiB
GDScript

extends RefCounted
static var BACKGROUND := Color("121827")
static var SURFACE := Color("1d2638")
static var SURFACE_DARK := Color("151c2b")
static var SURFACE_LIGHT := Color("27334a")
static var TEXT := Color("f6f8ff")
static var MUTED := Color("aeb8ca")
static var CYAN := Color("4de1ff")
static var LIME := Color("a6ff5f")
static var MAGENTA := Color("ff4fd8")
static var AMBER := Color("ffc857")
static var RED := Color("ff5f6d")
static var BORDER := Color("33415c")
static var is_dark := true
const DARK_PALETTE := {
"background": Color("121827"), "surface": Color("1d2638"),
"surface_dark": Color("151c2b"), "surface_light": Color("27334a"),
"text": Color("f6f8ff"), "muted": Color("aeb8ca"),
"cyan": Color("4de1ff"), "lime": Color("a6ff5f"),
"magenta": Color("ff4fd8"), "amber": Color("ffc857"),
"red": Color("ff5f6d"), "border": Color("33415c")
}
const LIGHT_PALETTE := {
"background": Color("f1f5f9"), "surface": Color("ffffff"),
"surface_dark": Color("f8fafc"), "surface_light": Color("eef2f7"),
"text": Color("0f172a"), "muted": Color("64748b"),
"cyan": Color("007a99"), "lime": Color("347a18"),
"magenta": Color("a32187"), "amber": Color("986400"),
"red": Color("b42335"), "border": Color("dbe3ef")
}
const CUSTOM_DARK_TO_LIGHT := {
Color("111a2a"): Color("f8fafc"), Color("172337"): Color("fffffe"),
Color("182235"): Color("fefeff"), Color("26151a"): Color("fff1f2"),
Color("263752"): Color("aeb9c8"), Color("344463"): Color("aeb9c8"),
Color("405475"): Color("96a5b8"), Color("3b4964"): Color("aeb9c8"),
Color("303c55"): Color("b9c4d2"), Color("33425d"): Color("d2dce8"),
Color("26354f"): Color("e1e8f1"), Color("20384d"): Color("d8e8ed"),
Color("18465a"): Color("d4f2f7"), Color("20647e"): Color("b9e7ef"),
Color("153b4d"): Color("c6e8ed"), Color("21344a"): Color("d8e8ed"),
Color("202637"): Color("e5e9ef"), Color("2c3445"): Color("c8d0dc"),
Color("232b3d"): Color("e1e7ef"), Color("303b53"): Color("b7c2d0"),
Color("596982"): Color("66758a"), Color("1f7a3a"): Color("dff4e5"),
Color("8f1d2c"): Color("f8dce1"), Color("071224"): Color("ffffff"),
Color("1c2b49"): Color("dbe3ef"), Color("14255b"): Color("e8edff"),
Color("172d68"): Color("d8e5ff"), Color("07192c"): Color("ffffff"),
Color("11182e"): Color("f8faff"), Color("2a365a"): Color("cbd6e8"),
Color("0c1838"): Color("eef3ff"), Color("24366d"): Color("cbd6e8"),
Color("c1cbdd"): Color("53627a")
}
static func set_dark_mode(value: bool) -> void:
is_dark = value
var palette: Dictionary = DARK_PALETTE if value else LIGHT_PALETTE
BACKGROUND = palette.background
SURFACE = palette.surface
SURFACE_DARK = palette.surface_dark
SURFACE_LIGHT = palette.surface_light
TEXT = palette.text
MUTED = palette.muted
CYAN = palette.cyan
LIME = palette.lime
MAGENTA = palette.magenta
AMBER = palette.amber
RED = palette.red
BORDER = palette.border
static func apply_app_theme(root: Control) -> void:
var theme := Theme.new()
theme.set_color("font_color", "Label", TEXT)
theme.set_color("font_color", "Button", TEXT)
theme.set_color("font_hover_color", "Button", TEXT)
theme.set_color("font_pressed_color", "Button", TEXT)
theme.set_color("font_disabled_color", "Button", MUTED)
theme.set_color("default_color", "RichTextLabel", TEXT)
theme.set_color("font_selected_color", "RichTextLabel", TEXT)
theme.set_color("selection_color", "RichTextLabel", Color(CYAN, 0.28))
theme.set_font_size("font_size", "Label", 17)
theme.set_font_size("font_size", "Button", 16)
theme.set_stylebox("normal", "Button", button_box(SURFACE_LIGHT, Color("3b4964")))
theme.set_stylebox("hover", "Button", button_box(Color("33425d"), CYAN))
theme.set_stylebox("pressed", "Button", button_box(Color("21344a"), LIME))
theme.set_stylebox("disabled", "Button", button_box(Color("202637"), Color("2c3445")))
theme.set_stylebox("focus", "Button", StyleBoxEmpty.new())
root.theme = theme
static func panel_box(color: Color = SURFACE, border: Color = BORDER) -> StyleBoxFlat:
var box := StyleBoxFlat.new()
box.bg_color = _color_for_current_theme(color)
box.border_color = _color_for_current_theme(border)
box.set_border_width_all(1)
box.corner_radius_top_left = 8
box.corner_radius_top_right = 8
box.corner_radius_bottom_left = 8
box.corner_radius_bottom_right = 8
box.content_margin_left = 18
box.content_margin_right = 18
box.content_margin_top = 16
box.content_margin_bottom = 16
return box
static func button_box(color: Color, border: Color) -> StyleBoxFlat:
var box := StyleBoxFlat.new()
box.bg_color = _color_for_current_theme(color)
box.border_color = _color_for_current_theme(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 = 14
box.content_margin_right = 14
box.content_margin_top = 10
box.content_margin_bottom = 10
return box
static func set_label(label: Label, font_size: int, color: Color = TEXT) -> void:
label.add_theme_font_size_override("font_size", font_size)
label.add_theme_color_override("font_color", color)
static func style_primary_button(button: Button) -> void:
button.add_theme_stylebox_override("normal", button_box(Color("18465a"), CYAN))
button.add_theme_stylebox_override("hover", button_box(Color("20647e"), Color("8df1ff")))
button.add_theme_stylebox_override("pressed", button_box(Color("153b4d"), LIME))
button.add_theme_color_override("font_color", TEXT)
static func style_answer_button(button: Button) -> void:
button.add_theme_stylebox_override("normal", button_box(SURFACE_DARK, Color("303c55")))
button.add_theme_stylebox_override("hover", button_box(Color("26354f"), CYAN))
button.add_theme_stylebox_override("pressed", button_box(Color("20384d"), CYAN))
button.add_theme_color_override("font_color", TEXT)
button.add_theme_color_override("font_disabled_color", MUTED)
static func style_chip(button: Button, color: Color) -> void:
button.add_theme_stylebox_override("normal", button_box(Color(color, 0.22), color))
button.add_theme_stylebox_override("hover", button_box(Color(color, 0.34), color))
button.add_theme_color_override("font_color", TEXT)
button.add_theme_color_override("font_disabled_color", MUTED)
static func refresh_tree(root: Control, was_dark: bool) -> void:
apply_app_theme(root)
_translate_control(
root,
DARK_PALETTE if was_dark else LIGHT_PALETTE,
LIGHT_PALETTE if was_dark else DARK_PALETTE,
was_dark
)
static func _translate_control(control: Control, source: Dictionary, target: Dictionary, from_dark: bool) -> void:
if control is ColorRect:
control.color = _translate_color(control.color, source, target, from_dark)
for color_name in ["font_color", "font_hover_color", "font_pressed_color", "font_disabled_color", "font_selected_color", "default_color", "font_uneditable_color"]:
if control.has_theme_color_override(color_name):
control.add_theme_color_override(color_name, _translate_color(control.get_theme_color(color_name), source, target, from_dark))
for style_name in ["panel", "normal", "hover", "pressed", "disabled", "focus", "fill", "background", "read_only"]:
if control.has_theme_stylebox_override(style_name):
var box := control.get_theme_stylebox(style_name)
if box is StyleBoxFlat:
var translated := box.duplicate() as StyleBoxFlat
translated.bg_color = _translate_color(translated.bg_color, source, target, from_dark)
translated.border_color = _translate_color(translated.border_color, source, target, from_dark)
control.add_theme_stylebox_override(style_name, translated)
for child in control.get_children():
if child is Control:
_translate_control(child, source, target, from_dark)
static func _translate_color(color: Color, source: Dictionary, target: Dictionary, from_dark: bool) -> Color:
for key in source:
var candidate: Color = source[key]
if color.is_equal_approx(candidate):
var replacement: Color = target[key]
replacement.a = color.a
return replacement
if from_dark:
for dark_color in CUSTOM_DARK_TO_LIGHT:
if color.is_equal_approx(dark_color):
var replacement: Color = CUSTOM_DARK_TO_LIGHT[dark_color]
replacement.a = color.a
return replacement
else:
for dark_color in CUSTOM_DARK_TO_LIGHT:
var light_color: Color = CUSTOM_DARK_TO_LIGHT[dark_color]
if color.is_equal_approx(light_color):
var replacement: Color = dark_color
replacement.a = color.a
return replacement
return color
static func _color_for_current_theme(color: Color) -> Color:
if is_dark:
return color
for dark_color in CUSTOM_DARK_TO_LIGHT:
if color.is_equal_approx(dark_color):
var replacement: Color = CUSTOM_DARK_TO_LIGHT[dark_color]
replacement.a = color.a
return replacement
return color