added theming bug needs bug fix

This commit is contained in:
2025-04-22 14:49:44 -05:00
parent ad54ed63f3
commit 98330ed8a9
9 changed files with 310 additions and 18 deletions
@@ -7,6 +7,7 @@ import net.minecraft.client.gui.screen.TitleScreen;
import org.saturnclient.saturnclient.auth.Auth;
import org.saturnclient.saturnclient.config.ConfigManager;
import org.saturnclient.saturnclient.config.ThemeManager;
import org.saturnclient.saturnclient.cosmetics.Hats;
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
import org.saturnclient.saturnclient.event.KeyInputHandler;
@@ -31,8 +32,9 @@ public class SaturnClient implements ModInitializer {
LOGGER.info("Initializing " + MOD_ID);
ModManager.init();
ConfigManager.load();
ThemeManager.load();
ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save());
ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> {ConfigManager.save(); ThemeManager.save();});
ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
if (SaturnClientConfig.saturnTitleScreen.value && screen instanceof TitleScreen
&& !(screen instanceof SaturnMenu)) {
@@ -139,4 +139,15 @@ public class Property<T> {
public static boolean valueIsNamespace(Object obj) {
return obj instanceof Map;
}
@SuppressWarnings("unchecked")
public void setValue(Object value) {
this.value = (T) value;
}
@SuppressWarnings("unchecked")
public void setValue(Object value, Object defaultValue) {
this.value = (T) value;
this.defaultValue = (T) defaultValue;
}
}
@@ -0,0 +1,31 @@
package org.saturnclient.saturnclient.config;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.LinkedHashMap;
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.JsonParser;
import com.google.gson.JsonPrimitive;
import net.minecraft.client.MinecraftClient;
public class Theme {
private Map<String, Property<?>> currentMap;
public void setProperty(String name, Property<?> value) {
currentMap.put(name, value);
}
public Property<?> getProperty(String name) {
return currentMap.get(name);
}
}
@@ -0,0 +1,226 @@
package org.saturnclient.saturnclient.config;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.LinkedHashMap;
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.JsonParser;
import com.google.gson.JsonPrimitive;
import net.minecraft.client.MinecraftClient;
public class ThemeManager {
private static File themeFile = new File(
MinecraftClient.getInstance().runDirectory,
"saturn.theme.json");
private static Map<String, Map<String, Property<?>>> properties = new HashMap<>();
// private Map<String, Map<String, Property<?>>> states;
private Map<String, Property<?>> currentStyling;
private String state;
private String[] states;
private String namespace;
public ThemeManager(String namespace, String... states) {
// this.states = new LinkedHashMap<>();
this.namespace = namespace;
this.states = states;
currentStyling = new LinkedHashMap<>();
properties.put(namespace, new LinkedHashMap<>());
for (String s : states) {
properties.put(namespace+"@"+s, new LinkedHashMap<>());
}
}
public void setState(String state) {
this.state = state;
if (this.state != null) {
for (Map.Entry<String, Property<?>> tProp : properties.get(namespace+"@"+state).entrySet()) {
currentStyling.get(tProp.getKey()).setValue(tProp.getValue().value);
}
} else {
for (Map.Entry<String, Property<?>> tProp : properties.get(namespace).entrySet()) {
currentStyling.get(tProp.getKey()).setValue(tProp.getValue().value);
}
}
}
// Generic method to store any type of property
public <T> Property<T> property(String name, Property<T> prop) {
for (String state : states) {
properties.get(namespace+"@"+state).put(name, new Property<T>(prop.value));
}
properties.get(namespace).put(name, new Property<T>(prop.value));
currentStyling.put(name, prop);
return prop;
}
public <T> void propertyStateDefault(String state, String name, T value) {
properties.get(namespace+"@"+state).get(name).setValue(value, value); // sets the current and default value
}
public static void load() {
try {
SaturnClient.LOGGER.info("Starting to load theme...");
if (!themeFile.exists()) {
themeFile.createNewFile();
Files.write(themeFile.toPath(), "{}".getBytes());
}
JsonObject jsonObject = JsonParser.parseString(
new String(Files.readAllBytes(themeFile.toPath()))).getAsJsonObject();
for (String namespace : properties.keySet()) {
JsonElement themeElement = jsonObject.get(namespace);
if (themeElement == null)
continue;
JsonObject theme = jsonObject.get(namespace).getAsJsonObject();
if (theme == null) {
continue;
}
Map<String, Property<?>> propertyMap = properties.get(namespace);
loadProperties(theme, propertyMap);
}
} catch (IOException e) {
SaturnClient.LOGGER.error("Error reading the theme file", e);
}
}
@SuppressWarnings("unchecked")
private static void loadProperties(JsonObject theme, Map<String, Property<?>> propertyMap) {
for (String propertyName : propertyMap.keySet()) {
JsonElement c = theme.get(propertyName);
if (c == null) {
continue;
}
Property<?> p = propertyMap.get(propertyName);
if (p.matchesJson(c)) {
if (p.getType() == Property.PropertyType.NAMESPACE) {
// Handle nested namespace
JsonObject nestedTheme = c.getAsJsonObject();
Map<String, Property<?>> nestedProperties = p.getNamespaceValue();
loadProperties(nestedTheme, nestedProperties);
} else {
// Handle regular properties
switch (p.getType()) {
case BOOLEAN:
((Property<Boolean>) p).value = c.getAsBoolean();
break;
case INTEGER:
((Property<Integer>) p).value = c.getAsInt();
break;
case FLOAT:
((Property<Float>) p).value = c.getAsFloat();
break;
case STRING:
((Property<String>) p).value = c.getAsString();
break;
case HEX:
((Property<Integer>) p).value = c.getAsInt();
break;
default:
break;
}
}
} else {
SaturnClient.LOGGER.warn(
"Property does not match JSON: " + propertyName);
}
}
}
public static void save() {
try {
SaturnClient.LOGGER.info("Starting to save theme...");
JsonObject jsonObject = new JsonObject();
// Iterate through all namespaces and their properties
for (String namespace : properties.keySet()) {
JsonObject namespaceTheme = new JsonObject();
Map<String, Property<?>> propertyMap = properties.get(namespace);
// Save properties for this namespace
saveProperties(namespaceTheme, propertyMap);
// Add the namespace theme to the main JSON object
jsonObject.add(namespace, namespaceTheme);
}
// Format the json so it can easily be edited
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String formattedJson = gson.toJson(jsonObject);
// Write the JSON object to the theme file
Files.write(themeFile.toPath(), formattedJson.getBytes());
SaturnClient.LOGGER.info("Theme saved successfully.");
} catch (IOException e) {
SaturnClient.LOGGER.error("Error saving the theme file", e);
}
}
@SuppressWarnings("unchecked")
private static void saveProperties(JsonObject theme, Map<String, Property<?>> propertyMap) {
// Iterate through each property in the namespace
for (String propertyName : propertyMap.keySet()) {
Property<?> property = propertyMap.get(propertyName);
JsonElement propertyValue = null;
if (property.getType() == Property.PropertyType.NAMESPACE) {
// Handle nested namespace
JsonObject nestedTheme = new JsonObject();
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) property.value;
saveProperties(nestedTheme, nestedProperties);
propertyValue = nestedTheme;
} else {
// Convert the property value based on its type
switch (property.getType()) {
case BOOLEAN:
propertyValue = new JsonPrimitive((Boolean) property.value);
break;
case INTEGER:
propertyValue = new JsonPrimitive((Integer) property.value);
break;
case FLOAT:
propertyValue = new JsonPrimitive((Float) property.value);
break;
case STRING:
propertyValue = new JsonPrimitive((String) property.value);
break;
case HEX:
propertyValue = new JsonPrimitive((Integer) property.value);
break;
default:
SaturnClient.LOGGER.warn(
"Unknown property type for: " + propertyName);
break;
}
}
if (propertyValue != null) {
theme.add(propertyName, propertyValue);
}
}
}
}
@@ -10,6 +10,6 @@ public class SaturnMenu extends SaturnScreen {
@Override
public void ui() {
draw(new Button("Settings", false).center(width, height));
draw(new Button("Settings").center(width, height));
}
}
@@ -5,9 +5,8 @@ public class Element {
protected int y;
protected int width;
protected int height;
protected int color;
public void render(RenderScope renderScope) {
public void render(RenderScope renderScope, boolean hovering) {
}
public final void dimensions(int width, int height) {
@@ -3,6 +3,7 @@ package org.saturnclient.ui2;
import java.util.ArrayList;
import java.util.List;
import org.saturnclient.saturnclient.config.ThemeManager;
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
import net.minecraft.client.gui.DrawContext;
@@ -11,9 +12,11 @@ import net.minecraft.text.Text;
public class SaturnScreen extends Screen {
protected List<Element> elements = new ArrayList<>();
private int hoveringIndex;
public SaturnScreen(String title) {
super(Text.literal(title));
ThemeManager.load();
}
public void draw(Element element) {
@@ -41,14 +44,22 @@ public class SaturnScreen extends Screen {
renderScope.matrices.push();
for (Element element : elements) {
renderScope.setOpacity(0.5f);
for (int i = 0; i < elements.size(); i++) {
Element element = elements.get(i);
renderScope.matrices.push();
renderScope.matrices.translate(element.x, element.y, 0);
element.render(renderScope);
element.render(renderScope, isMouseInside(mouseX, mouseY, element));
renderScope.matrices.pop();
}
renderScope.matrices.pop();
}
public static boolean isMouseInside(int mouseX, int mouseY, Element element) {
return mouseX >= element.x &&
mouseX <= (element.x + element.width) &&
mouseY >= element.y &&
mouseY <= (element.y + element.height);
}
}
@@ -1,5 +1,7 @@
package org.saturnclient.ui2.elements;
import org.saturnclient.saturnclient.config.Property;
import org.saturnclient.saturnclient.config.ThemeManager;
import org.saturnclient.ui2.Element;
import org.saturnclient.ui2.RenderScope;
import org.saturnclient.ui2.resources.Fonts;
@@ -7,22 +9,33 @@ import org.saturnclient.ui2.resources.Fonts;
import net.minecraft.util.Identifier;
public class Button extends Element {
private static ThemeManager theme = new ThemeManager("Button", "testing");
private static Property<Integer> bgColor = theme.property("bg-color", new Property<Integer>(0xFF000000));
private static Property<Integer> fgColor = theme.property("fg-color", new Property<Integer>(0xFFFFFFFF));
private static Property<Boolean> bold = theme.property("fg-bold", new Property<Boolean>(false));
static {
theme.propertyStateDefault("hovering", "fg-color", 0xFFFF0000);
}
private String text;
private boolean bold;
private Identifier font;
public Button(String text, boolean bold) {
public Button(String text) {
this.text = text;
this.bold = bold;
this.font = Fonts.getFont(bold);
this.font = Fonts.getFont(bold.value);
this.dimensions(Fonts.getWidth(text, font)+ 25 , Fonts.getHeight() + 10);
this.color = 0xFFFFFFFF;
}
@Override
public void render(RenderScope renderScope) {
renderScope.drawRoundedRectangle(0, 0, width, height, 10, 0xFF000000);
public void render(RenderScope renderScope, boolean hovering) {
if (hovering) {
theme.setState("hovering");
} else {
theme.setState(null);
}
renderScope.drawRoundedRectangle(0, 0, width, height, 10, bgColor.value);
renderScope.drawText(text, width / 2 - Fonts.getWidth(text, font) / 2, height / 2 - Fonts.getHeight() / 2, bold, color);
renderScope.drawText(text, width / 2 - Fonts.getWidth(text, font) / 2, height / 2 - Fonts.getHeight() / 2, bold.value, fgColor.value);
}
}
@@ -8,11 +8,10 @@ public class Text extends Element {
public Text(String text) {
this.text = text;
this.color = 0xFFFFFFFF;
}
@Override
public void render(RenderScope renderScope) {
renderScope.drawText(this.text, this.x, this.y, false, this.color);
public void render(RenderScope renderScope, boolean hovering) {
renderScope.drawText(this.text, this.x, this.y, false, 0xFFFFFFFF);
}
}