====== Themes ====== Das Aussehen liegt **nicht** im Code der Controls, sondern in Themes. Weil Vega alles selbst zeichnet, bestimmt ein Theme wirklich alles — bis hinunter zur Titelleiste, die sonst der Fenstermanager malen würde. ===== Zwei Ebenen ===== ^ Ebene ^ Was sie bestimmt ^ Wo ^ | ''TTheme'' | Grundfarben, Schriftgröße, Metriken, Skalierung | ''Vega/Theme.lyx'' | | Stylesheet | Regeln je Controltyp, Zustand, Rolle, Klasse, Teil | ''Vega/Style.lyx'' | Ein Control fragt zuerst das Stylesheet (''ResolvedStyle''), und was dort nicht steht, kommt aus dem Theme: var st: TStyleSet := self.ResolvedStyle(); canvas.FillRect(r, st.GetOr(SP_BACKGROUND, self.Color)); st.Destroy(); ===== Der Fünf-Achsen-Selektor ===== Eine Regel greift nach fünf Merkmalen: * **Typ** — ''button'', ''listView'', ''toolBar'', … * **Zustand** — ''hover'', ''pressed'', ''checked'', ''disabled'', ''focused'', ''selected'' * **Rolle** — ''role primary'', frei vergebbar * **Klasse** — ''class gefaehrlich'', frei vergebbar * **Teil** — ''part header'', ''part thumb'', … für Controls aus mehreren Flächen Zustände dürfen geschachtelt werden; daraus wird eine Regel, die **beide** verlangt: checked { hover { background: #222222 } } Ein Teil **erbt** vom Control: was es nicht selbst sagt, kommt von dort. Ausdrücklich nicht vorhanden und nicht geplant: Selektorenketten und Rechnungen. ===== .vtheme-Dateien ===== theme "firma.dunkel" extends "vega.dark" { version 1 mode dark tokens { colors { marke: #0057B8 markeHover: #00468F } metrics { rund: 4 } } button { background: {colors.marke} hover { background: {colors.markeHover} } role primary { background: #C00000 } } listView { background: #FFFFFF part header { background: #EAEAEA hover { background: #DCDCDC } } } } * **''extends''** — alles, was nicht dasteht, kommt vom Basistheme. Eine Datei muss also nicht vollständig sein. * **Tokens** — benannte Werte, damit eine Farbe nur an einer Stelle steht. Eingesetzt wird beim **Laden**, zur Laufzeit stehen überall fertige Werte; die Kaskade wird dadurch nicht langsamer. * **Farben** als ''#RRGGBB'' oder ''#RRGGBBAA'', dazu ''rgba(r,g,b,a)''. ===== Laden ===== RegisterThemeFile("themes/mein.vtheme", true); // true = strenger Modus UseTheme("firma.dunkel"); Im **strengen** Modus ist ein Tippfehler ein Fehler mit Zeilennummer. Im toleranten wird die Zeile übersprungen und der Rest geladen. Beim Entwickeln streng, im Auslieferzustand tolerant — dieselbe Zweiteilung wie beim LFM-Lader. ===== Vorlage ===== ''themes/template.vtheme'' listet **jeden** bekannten Typ, Zustand und Teil als Kommentar. Sie wird erzeugt, nicht von Hand gepflegt: ./.build/gen-theme-template > themes/template.vtheme Ein fertiges Beispiel liegt in ''themes/corporate.vtheme'', und ''examples/theming.lyx'' zeigt das Umschalten zur Laufzeit.