136 lines
4.4 KiB
GDScript
136 lines
4.4 KiB
GDScript
class_name UIScale
|
|
extends RefCounted
|
|
|
|
## Zentrale UI-Skalierung (Karte t_297221b5): EIN Faktor für den ganzen Editor.
|
|
##
|
|
## Stufen: Klein (1.0) / Mittel (1.25) / Groß (1.5). Der Faktor multipliziert
|
|
## alle Layout-Werte beim UI-Bau (Schrift, Zeilen-/Knopfhöhen, Panelbreiten,
|
|
## Thumbnail-Größe, Abstände) — bewusst als Faktor-Multiplikation und NICHT als
|
|
## stretch/canvas_items, damit (a) die 3D-Map-Ansicht pixelgenau unberührt bleibt,
|
|
## (b) nichts doppelt skaliert und (c) die Stufe vom Nutzer gewählt wird statt
|
|
## von der Fenstergröße abzuhängen.
|
|
##
|
|
## Die gewählte Stufe liegt in user://scopedvr_editor.cfg, Abschnitt [ui]
|
|
## (Key "groesse"). ConfigFile lädt+speichert die GANZE Datei — der Abschnitt
|
|
## [library] (Klapp-Zustand, Karte t_59fc0f21) bleibt dabei erhalten.
|
|
##
|
|
## Für Tests/Probes kann per Umgebungsvariable SCOPEDVR_UI_CFG eine andere
|
|
## Config-Datei erzwungen werden (hermetische Läufe ohne Nutzer-Config).
|
|
|
|
## Typografie-Ebenen (Karte t_2336c58e/U7 — verbindlich): genau ZWEI Schrift-
|
|
## Größen (Body + Klein) plus eine Überschriften-Stufe. KEINE weiteren Größen
|
|
## im Code — alles über die drei Helfer unten, skaliert mit der UI-Stufe.
|
|
const HEADING_FONT_SIZE := 20 # Überschriften (Panel-/Gruppen-Header, Titel)
|
|
const SMALL_FONT_SIZE := 13 # Nebentext (Zähler, Badges, Tile-IDs)
|
|
|
|
const CFG_PATH := "user://scopedvr_editor.cfg"
|
|
const CFG_SECTION := "ui"
|
|
const CFG_KEY := "groesse" # "klein" | "mittel" | "gross"
|
|
const WIN_SECTION := "fenster" # Fenster-Zustand (maximiert/Größe/Position)
|
|
|
|
## [key, Anzeige-Name, Faktor]
|
|
const STEPS: Array = [
|
|
["klein", "Klein", 1.0],
|
|
["mittel", "Mittel", 1.25],
|
|
["gross", "Groß", 1.5],
|
|
]
|
|
const BASE_FONT_SIZE := 16 # bisherige feste Schriftgröße (main.gd, Vorher)
|
|
|
|
static var _factor: float = -1.0 # Cache; < 0 = noch nicht aus der Config gelesen
|
|
|
|
|
|
static func cfg_path() -> String:
|
|
var env := OS.get_environment("SCOPEDVR_UI_CFG")
|
|
if not env.is_empty():
|
|
return env
|
|
return CFG_PATH
|
|
|
|
|
|
static func step_count() -> int:
|
|
return STEPS.size()
|
|
|
|
|
|
static func step_label(i: int) -> String:
|
|
return str(STEPS[clampi(i, 0, STEPS.size() - 1)][1])
|
|
|
|
|
|
static func step_key(i: int) -> String:
|
|
return str(STEPS[clampi(i, 0, STEPS.size() - 1)][0])
|
|
|
|
|
|
static func step_index_from_key(key: String) -> int:
|
|
for i in STEPS.size():
|
|
if str(STEPS[i][0]) == key:
|
|
return i
|
|
return 0 # unbekannt/leer → Klein (Vorher-Verhalten)
|
|
|
|
|
|
## Aktuelle Stufe aus der Config (ohne Cache).
|
|
static func step_index() -> int:
|
|
var cfg := ConfigFile.new()
|
|
if cfg.load(cfg_path()) != OK:
|
|
return 0 # keine Config = Klein (altes Verhalten)
|
|
return step_index_from_key(str(cfg.get_value(CFG_SECTION, CFG_KEY, "")))
|
|
|
|
|
|
## Faktor der aktuellen Stufe (cached — UI-Bau ruft das sehr oft).
|
|
static func factor() -> float:
|
|
if _factor < 0.0:
|
|
_factor = float(STEPS[step_index()][2])
|
|
return _factor
|
|
|
|
|
|
## Stufe setzen UND sofort in die Config schreiben (Abschnitte wie [library]
|
|
## bleiben erhalten — ConfigFile liest/schreibt die ganze Datei).
|
|
static func set_step_index(i: int) -> void:
|
|
i = clampi(i, 0, STEPS.size() - 1)
|
|
var cfg := ConfigFile.new()
|
|
cfg.load(cfg_path()) # fehlt die Datei: leer anfangen, Abschnitte bleiben
|
|
cfg.set_value(CFG_SECTION, CFG_KEY, str(STEPS[i][0]))
|
|
var err := cfg.save(cfg_path())
|
|
if err != OK:
|
|
push_warning("UIScale: Config nicht schreibbar (%s), Stufe nur für diese Sitzung." % err)
|
|
_factor = float(STEPS[i][2])
|
|
|
|
|
|
## Cache verwerfen und neu lesen — simuliert den Neustart (für Tests/Probes).
|
|
static func reload() -> void:
|
|
_factor = -1.0
|
|
factor()
|
|
|
|
|
|
# ------------------------------------------------------- Rechenhelfer (Bau) --
|
|
|
|
## Ganzzahliges Pixel-Maß (Höhen, Breiten, Abstände, Schriftgrößen).
|
|
static func px(v: float) -> int:
|
|
return int(round(v * factor()))
|
|
|
|
|
|
## Fließkommamaß (z. B. split_offset).
|
|
static func f(v: float) -> float:
|
|
return v * factor()
|
|
|
|
|
|
## custom_minimum_size = UIScale.v2(b, h) statt Vector2(b, h).
|
|
static func v2(x: float, y: float) -> Vector2:
|
|
return Vector2(px(x), px(y))
|
|
|
|
|
|
## Dialog-/Fenstergrößen.
|
|
static func v2i(x: float, y: float) -> Vector2i:
|
|
return Vector2i(px(x), px(y))
|
|
|
|
|
|
## Standardschriftgröße (Body-Text, bisher fest 16).
|
|
static func font_size() -> int:
|
|
return px(BASE_FONT_SIZE)
|
|
|
|
|
|
## Überschriften-Größe (Panel-/Gruppen-Header, Titel) — U7-Raster.
|
|
static func heading_font_size() -> int:
|
|
return px(HEADING_FONT_SIZE)
|
|
|
|
|
|
## Nebentext-Größe (Zähler, Badges, Tile-IDs) — U7-Raster.
|
|
static func small_font_size() -> int:
|
|
return px(SMALL_FONT_SIZE)
|