package com.megatim.manuel.studio; import com.megatim.manuel.core.theme.ManuelTheme; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.Properties; /** * Charge un {@link ManuelTheme} depuis un fichier {@code .properties}. * *

Clés supportées (toutes optionnelles, défauts = charte Sirius) :

*
 * accentColor=#ffe3d0
 * buttonColor=#f6f6f6
 * buttonBorderColor=#c9b8a8
 * panelBorderColor=#d1d1d1
 * selectionColor=#ffd9c2
 * hoverColor=#fff3ea
 * textColor=#3a2c20
 * backgroundColor=#ffffff
 * appTitle=Mon Application
 * logo=chemin/vers/logo.png            (relatif au fichier .properties, ou URL)
 * viewerStylesheet=file:/.../mon.css   (remplace la CSS embarquée)
 * extraViewerStylesheets=uri1;uri2     (surcharges, séparées par ;)
 * htmlVars.html.h1=#7a2e00             (toute variable du template HTML)
 * 
*/ public final class ThemeLoader { private ThemeLoader() { } public static ManuelTheme load(Path propertiesFile) throws IOException { Properties p = new Properties(); try (InputStream in = Files.newInputStream(propertiesFile)) { p.load(new InputStreamReader(in, StandardCharsets.UTF_8)); } ManuelTheme.Builder b = ManuelTheme.builder(); set(p, "accentColor", b::accentColor); set(p, "buttonColor", b::buttonColor); set(p, "buttonBorderColor", b::buttonBorderColor); set(p, "panelBorderColor", b::panelBorderColor); set(p, "selectionColor", b::selectionColor); set(p, "hoverColor", b::hoverColor); set(p, "textColor", b::textColor); set(p, "backgroundColor", b::backgroundColor); set(p, "appTitle", b::appTitle); String logo = trimmed(p, "logo"); if (logo != null) { b.logo(toUrl(logo, propertiesFile)); } set(p, "viewerStylesheet", b::viewerStylesheet); String extras = trimmed(p, "extraViewerStylesheets"); if (extras != null) { for (String uri : extras.split(";")) { if (!uri.isBlank()) b.extraViewerStylesheet(uri.trim()); } } for (String key : p.stringPropertyNames()) { if (key.startsWith("htmlVars.")) { b.htmlVar(key.substring("htmlVars.".length()), p.getProperty(key).trim()); } } return b.build(); } private static void set(Properties p, String key, java.util.function.Consumer setter) { String v = trimmed(p, key); if (v != null) setter.accept(v); } private static String trimmed(Properties p, String key) { String v = p.getProperty(key); return (v != null && !v.trim().isEmpty()) ? v.trim() : null; } private static URL toUrl(String value, Path base) throws IOException { if (value.contains("://") || value.startsWith("file:")) { return new URL(value); } Path path = Path.of(value); if (!path.isAbsolute()) { path = base.getParent().resolve(path); } return path.toUri().toURL(); } }