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)