diff --git a/src/main/java/org/saturnclient/saturnclient/SaturnClient.java b/src/main/java/org/saturnclient/saturnclient/SaturnClient.java index 02f5685..0b9d836 100644 --- a/src/main/java/org/saturnclient/saturnclient/SaturnClient.java +++ b/src/main/java/org/saturnclient/saturnclient/SaturnClient.java @@ -39,9 +39,9 @@ public class SaturnClient implements ModInitializer { client = MinecraftClient.getInstance(); SaturnClientConfig.init(); ModManager.init(); - + ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save()); - + SpecialModelLoaderEvents.LOAD_SCOPE.register(() -> { return (resourceManager, location) -> MOD_ID.equals(location.getNamespace()); }); @@ -49,11 +49,12 @@ public class SaturnClient implements ModInitializer { ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> { if (screen != null && !(screen instanceof TitleMenu)) { if (screen instanceof SaturnScreen) { - ((SaturnScreen) screen).draw(new ImageTexture(Textures.LOGO_TEXT_BIG).dimensions(180, 18).position(screen.width - 180 - 20, screen.height - 18 - 20)); + ((SaturnScreen) screen).draw(new ImageTexture(Textures.LOGO_TEXT_BIG).dimensions(180, 18) + .position(screen.width - 180 - 20, screen.height - 18 - 20)); } else { ScreenEvents.afterRender(screen).register((screen1, context, mouseX, mouseY, tickDelta) -> { RenderScope renderScope = new RenderScope(context.getMatrices(), - ((DrawContextAccessor) context).getVertexConsumers()); + ((DrawContextAccessor) context).getVertexConsumers()); int width = context.getScaledWindowWidth(); int height = context.getScaledWindowHeight(); @@ -71,7 +72,7 @@ public class SaturnClient implements ModInitializer { } } }); - + KeyInputHandler.register(); Emotes.initialize(); if (Auth.authenticate()) { diff --git a/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java b/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java index 3c269c7..a13ec16 100644 --- a/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java +++ b/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java @@ -46,7 +46,6 @@ public class ConfigManager { // Generic method to store any type of property public Property property(String name, Property value) { - System.out.println("Adding property: " + name); currentMap.put(name, value); loadProp(name, value); return value; @@ -98,7 +97,6 @@ public class ConfigManager { new String(Files.readAllBytes(configFile.toPath()))).getAsJsonObject(); for (String namespace : properties.keySet()) { - SaturnClient.LOGGER.info("Loading namespace: " + namespace); JsonElement configElement = jsonObject.get(namespace); if (configElement == null) @@ -120,8 +118,6 @@ public class ConfigManager { @SuppressWarnings("unchecked") private static void loadProperties(JsonObject config, Map> propertyMap) { - SaturnClient.LOGGER.info("Loading properties: " + propertyMap); - for (String propertyName : propertyMap.keySet()) { JsonElement c = config.get(propertyName); diff --git a/src/main/java/org/saturnclient/saturnclient/config/Property.java b/src/main/java/org/saturnclient/saturnclient/config/Property.java index c8baf9f..28ac3de 100644 --- a/src/main/java/org/saturnclient/saturnclient/config/Property.java +++ b/src/main/java/org/saturnclient/saturnclient/config/Property.java @@ -50,6 +50,10 @@ public class Property { } } + public Property copy() { + return new Property<>(this.value, this.type); + } + public static Property font(int value) { return select(value, "Default", "Inter", "Inter bold"); } @@ -160,12 +164,8 @@ public class Property { return true; if (value instanceof String && primitive.isString()) return true; - - // Check if JSON string represents a valid hex integer - if (value instanceof String && primitive.isString()) { - String str = primitive.getAsString(); - return str.matches("0x[0-9A-Fa-f]+"); - } + if (type == PropertyType.HEX && primitive.isString()) + return true; } else if (element.isJsonObject()) { return isNamespace(value); } @@ -211,4 +211,48 @@ public class Property { wasPressedLastTick = isPressed && !wasPressedLastTick; return wasPressedLastTick; } + + @SuppressWarnings("unchecked") + public void load(String name, JsonElement element) { + if (element != null && element.isJsonObject()) { + JsonElement value = element.getAsJsonObject().get(name); + if (value != null) { + switch (this.getType()) { + case BOOLEAN: + ((Property) this).setValue(value.getAsBoolean()); + break; + case INTEGER: + JsonPrimitive primitive = value.getAsJsonPrimitive(); + if (primitive.isNumber()) + ((Property) this).setValue(value.getAsInt()); + else if (primitive.isString()) + ((Property) this).setValue(parseHexToInt(value.getAsString())); + break; + case FLOAT: + ((Property) this).setValue(value.getAsFloat()); + break; + case STRING: + ((Property) this).setValue(value.getAsString()); + break; + case HEX: + ((Property) this).setValue(parseHexToInt(value.getAsString())); + break; + default: + break; + } + } + } + } + + public static int parseHexToInt(String hex) { + hex = hex.replaceAll("#", ""); + + if (hex.length() == 6) { + hex = "FF" + hex; + } else if (hex.length() != 8) { + throw new IllegalArgumentException("Hex string must be 6 or 8 characters long"); + } + + return (int) Long.parseLong(hex, 16); + } } diff --git a/src/main/java/org/saturnclient/saturnclient/config/ThemeManager.java b/src/main/java/org/saturnclient/saturnclient/config/ThemeManager.java index b3bb32f..0bcc14b 100644 --- a/src/main/java/org/saturnclient/saturnclient/config/ThemeManager.java +++ b/src/main/java/org/saturnclient/saturnclient/config/ThemeManager.java @@ -4,61 +4,90 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.ArrayList; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.saturnclient.saturnclient.SaturnClient; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; +import com.google.gson.JsonParser; public class ThemeManager { - // public static List theme = new ArrayList<>(); + private static File themeFile = new File( + SaturnClient.client.runDirectory, + "saturn.theme.json"); + private static List theme = new ArrayList<>(); + private static JsonObject cachedThemeJson = null; - private String[] stateList; - private Map>> states; + private Map> states; private Map> currentStyling; private String namespace; public ThemeManager(String namespace, String... states) { - this.stateList = states; - this.states = new LinkedHashMap<>(); this.namespace = namespace; - currentStyling = new LinkedHashMap<>(); + this.states = new LinkedHashMap<>(); + this.currentStyling = new LinkedHashMap<>(); this.states.put(null, new LinkedHashMap<>()); for (String s : states) { this.states.put(s, new LinkedHashMap<>()); } + theme.add(this); } public void setState(String state) { - for (Map.Entry> tProp : states.get(state).entrySet()) { - currentStyling.get(tProp.getKey()).setValue(tProp.getValue().value); + for (Map.Entry tProp : states.get(state).entrySet()) { + currentStyling.get(tProp.getKey()).setValue(tProp.getValue()); } } public void applyState(String state) { + for (Map.Entry tProp : states.get(state).entrySet()) { + if (!states.get(null).get(tProp.getKey()).equals(tProp.getValue())) + currentStyling.get(tProp.getKey()).setValue(tProp.getValue()); + } } public Property property(String name, Property prop) { - for (String state : stateList) { - Property property = Property.from(prop.value); - states.get(state).put(name, property); + for (Map.Entry> state : this.states.entrySet()) { + Property property = prop.copy(); + if (cachedThemeJson == null) { + load(); + } + String stateName = state.getKey(); + property.load(name, cachedThemeJson.get(stateName != null ? namespace + "@" + stateName : namespace)); + state.getValue().put(name, property.value); } - states.get(null).put(name, Property.from(prop.value)); currentStyling.put(name, prop); return prop; } public void propertyStateDefault(String state, String name, T value) { - Property prop = states.get(state).get(name); + Property prop = currentStyling.get(name).copy(); prop.setValue(value, value); + if (cachedThemeJson == null) { + load(); + } + prop.load(name, cachedThemeJson.get(state != null ? namespace + "@" + state : namespace)); + states.get(state).put(name, prop.value); + } + + public static void load() { + try { + SaturnClient.LOGGER.info("Starting to load theme..."); + if (!themeFile.exists()) { + themeFile.createNewFile(); + Files.write(themeFile.toPath(), "{}".getBytes()); + } + + cachedThemeJson = JsonParser.parseString( + new String(Files.readAllBytes(themeFile.toPath()))).getAsJsonObject(); + + SaturnClient.LOGGER.info("Theme loaded"); + } catch (IOException e) { + SaturnClient.LOGGER.error("Error reading the theme file", e); + } } } diff --git a/src/main/java/org/saturnclient/ui2/components/inputs/Toggle.java b/src/main/java/org/saturnclient/ui2/components/inputs/Toggle.java index 166c38a..5436d42 100644 --- a/src/main/java/org/saturnclient/ui2/components/inputs/Toggle.java +++ b/src/main/java/org/saturnclient/ui2/components/inputs/Toggle.java @@ -33,6 +33,10 @@ public class Toggle extends Element { theme.setState("enabled"); } + if (ctx.isHovering()) { + theme.applyState("hovering"); + } + renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value); renderScope.drawRoundedRectangle(prop.value ? 30 : 0, 0, 30, 30, 30, fgColor.value);