Merge pull request #23 from saturnclientmc/new-ui-theme-and-animations
New UI theme and animations
This commit is contained in:
@@ -2,7 +2,7 @@ package org.saturnclient.modules;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.NamedProperty;
|
import org.saturnclient.saturnclient.config.Property.NamedProperty;
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
|
||||||
public class ModDimensions {
|
public class ModDimensions {
|
||||||
@@ -26,11 +26,11 @@ public class ModDimensions {
|
|||||||
"Background Color", bgColor,
|
"Background Color", bgColor,
|
||||||
"Foreground Color", fgColor,
|
"Foreground Color", fgColor,
|
||||||
"Corner Radius", radius,
|
"Corner Radius", radius,
|
||||||
"Font", font
|
"Font", font)).named("In-Game Display");
|
||||||
)).named("In-Game Display");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModDimensions() {}
|
public ModDimensions() {
|
||||||
|
}
|
||||||
|
|
||||||
public ModDimensions(int width, int height) {
|
public ModDimensions(int width, int height) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package org.saturnclient.modules;
|
package org.saturnclient.modules;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||||
import org.saturnclient.saturnclient.config.NamedProperty;
|
|
||||||
import org.saturnclient.ui2.resources.Textures;
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.saturnclient.config.Property.NamedProperty;
|
||||||
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
@@ -19,8 +19,11 @@ public abstract class Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(RenderScope scope) {}
|
public void render(RenderScope scope) {
|
||||||
public void tick() {}
|
}
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
}
|
||||||
|
|
||||||
public abstract boolean isEnabled();
|
public abstract boolean isEnabled();
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import net.minecraft.client.util.math.MatrixStack;
|
|||||||
import org.saturnclient.modules.ModManager;
|
import org.saturnclient.modules.ModManager;
|
||||||
import org.saturnclient.saturnclient.client.ServiceClient;
|
import org.saturnclient.saturnclient.client.ServiceClient;
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||||
|
import org.saturnclient.saturnclient.config.SaturnClientConfig;
|
||||||
import org.saturnclient.saturnclient.cosmetics.Emotes;
|
import org.saturnclient.saturnclient.cosmetics.Emotes;
|
||||||
import org.saturnclient.saturnclient.cosmetics.Hats;
|
import org.saturnclient.saturnclient.cosmetics.Hats;
|
||||||
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
||||||
@@ -40,6 +41,10 @@ public class SaturnClient implements ModInitializer {
|
|||||||
SaturnClientConfig.init();
|
SaturnClientConfig.init();
|
||||||
ModManager.init();
|
ModManager.init();
|
||||||
|
|
||||||
|
client.execute(() -> {
|
||||||
|
SaturnScreen.preload(client);
|
||||||
|
});
|
||||||
|
|
||||||
ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save());
|
ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save());
|
||||||
|
|
||||||
SpecialModelLoaderEvents.LOAD_SCOPE.register(() -> {
|
SpecialModelLoaderEvents.LOAD_SCOPE.register(() -> {
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
package org.saturnclient.saturnclient;
|
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
|
||||||
import org.saturnclient.ui2.resources.Textures;
|
|
||||||
|
|
||||||
import net.minecraft.util.Formatting;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
|
|
||||||
public class SaturnClientConfig {
|
|
||||||
public static ConfigManager config;
|
|
||||||
|
|
||||||
public static Property<Boolean> realisticLogo = Property.bool(false);
|
|
||||||
public static Property<Boolean> saturnTitleScreen = Property.bool(true);
|
|
||||||
public static Property<Boolean> bendyCloaks = Property.bool(true);
|
|
||||||
public static Property<Integer> openEmoteWheel = Property.keybinding(GLFW.GLFW_KEY_B);
|
|
||||||
|
|
||||||
static enum Role {
|
|
||||||
OWNER,
|
|
||||||
ADMIN,
|
|
||||||
PARTNER,
|
|
||||||
CONTRIBUTOR
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Map<UUID, Role> ROLES = Map.of(
|
|
||||||
UUID.fromString("d362a042-28bd-49e1-a807-ae74dbe8aba9"),
|
|
||||||
Role.OWNER);
|
|
||||||
|
|
||||||
public static Identifier getLogo() {
|
|
||||||
return realisticLogo.value ? Textures.REALISTIC_LOGO : Textures.LOGO;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getSaturnIndicator() {
|
|
||||||
return realisticLogo.value ? "" : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Gets the icon color of a specific individual, here are the different colors
|
|
||||||
*
|
|
||||||
* - Owner: Dark Red
|
|
||||||
* - Admin: Red
|
|
||||||
* - Partners: Gold
|
|
||||||
* - Contributor: Aqua
|
|
||||||
* - Other/player: White
|
|
||||||
*/
|
|
||||||
public static Formatting getIconColor(UUID uuid) {
|
|
||||||
Role role = ROLES.get(uuid);
|
|
||||||
|
|
||||||
if (role == null) {
|
|
||||||
return Formatting.WHITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (role) {
|
|
||||||
case OWNER:
|
|
||||||
return Formatting.DARK_RED;
|
|
||||||
|
|
||||||
case ADMIN:
|
|
||||||
return Formatting.RED;
|
|
||||||
|
|
||||||
case PARTNER:
|
|
||||||
return Formatting.GOLD;
|
|
||||||
|
|
||||||
case CONTRIBUTOR:
|
|
||||||
return Formatting.AQUA;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return Formatting.WHITE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void init() {
|
|
||||||
config = new ConfigManager("Saturn Client");
|
|
||||||
config.property("Realistic logo", realisticLogo);
|
|
||||||
config.property("Saturn client title screen", saturnTitleScreen);
|
|
||||||
config.property("Open Emote Wheel", openEmoteWheel);
|
|
||||||
config.property("Bendy Cloaks", bendyCloaks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package org.saturnclient.saturnclient.client.player;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.SaturnClientConfig;
|
||||||
|
|
||||||
|
import net.minecraft.util.Formatting;
|
||||||
|
|
||||||
|
public class Roles {
|
||||||
|
static enum Role {
|
||||||
|
OWNER,
|
||||||
|
ADMIN,
|
||||||
|
PARTNER,
|
||||||
|
CONTRIBUTOR
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Map<UUID, Role> ROLES = Map.of(
|
||||||
|
UUID.fromString("d362a042-28bd-49e1-a807-ae74dbe8aba9"),
|
||||||
|
Role.OWNER);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gets the icon color of a specific individual, here are the different colors
|
||||||
|
*
|
||||||
|
* - Owner: Dark Red
|
||||||
|
* - Admin: Red
|
||||||
|
* - Partners: Gold
|
||||||
|
* - Contributor: Aqua
|
||||||
|
* - Other/player: White
|
||||||
|
*/
|
||||||
|
public static Formatting getIconColor(UUID uuid) {
|
||||||
|
Role role = ROLES.get(uuid);
|
||||||
|
|
||||||
|
if (role == null) {
|
||||||
|
return Formatting.WHITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case OWNER:
|
||||||
|
return Formatting.DARK_RED;
|
||||||
|
|
||||||
|
case ADMIN:
|
||||||
|
return Formatting.RED;
|
||||||
|
|
||||||
|
case PARTNER:
|
||||||
|
return Formatting.GOLD;
|
||||||
|
|
||||||
|
case CONTRIBUTOR:
|
||||||
|
return Formatting.AQUA;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return Formatting.WHITE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSaturnIndicator() {
|
||||||
|
return SaturnClientConfig.realisticLogo.value ? "" : "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.saturnclient.saturnclient.client.ServiceClient;
|
import org.saturnclient.saturnclient.client.ServiceClient;
|
||||||
|
|
||||||
public class SaturnPlayer {
|
public class SaturnPlayer {
|
||||||
@@ -22,14 +23,17 @@ public class SaturnPlayer {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public static SaturnPlayer get() {
|
public static SaturnPlayer get() {
|
||||||
return PLAYERS.get(ServiceClient.uuid);
|
return PLAYERS.get(ServiceClient.uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public static SaturnPlayer get(UUID uuid) {
|
public static SaturnPlayer get(UUID uuid) {
|
||||||
return PLAYERS.get(uuid);
|
return PLAYERS.get(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public static SaturnPlayer get(String name) {
|
public static SaturnPlayer get(String name) {
|
||||||
UUID uuid = PLAYER_NAMES.get(name);
|
UUID uuid = PLAYER_NAMES.get(name);
|
||||||
if (uuid == null)
|
if (uuid == null)
|
||||||
|
|||||||
@@ -1,107 +1,94 @@
|
|||||||
package org.saturnclient.saturnclient.config;
|
package org.saturnclient.saturnclient.config;
|
||||||
|
|
||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.*;
|
import java.util.LinkedHashMap;
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ConfigManager {
|
public class ConfigManager {
|
||||||
|
|
||||||
private static final File configFile = new File(SaturnClient.client.runDirectory, "saturn.json");
|
private static final File configFile = new File(SaturnClient.client.runDirectory, "saturn.json");
|
||||||
private static final Map<String, Map<String, Property<?>>> properties = new HashMap<>();
|
|
||||||
private static JsonObject cachedThemeJson = null;
|
// SINGLE ROOT TREE
|
||||||
|
private static final Map<String, Property<?>> ROOT = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
private static JsonObject cachedJson = null;
|
||||||
|
|
||||||
private final Map<String, Property<?>> currentMap;
|
private final Map<String, Property<?>> currentMap;
|
||||||
private final String namespace;
|
|
||||||
|
|
||||||
|
private final String[] path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a root namespace
|
||||||
|
*/
|
||||||
public ConfigManager(String namespace) {
|
public ConfigManager(String namespace) {
|
||||||
this.namespace = namespace;
|
|
||||||
this.currentMap = new LinkedHashMap<>();
|
this.currentMap = new LinkedHashMap<>();
|
||||||
properties.put(namespace, currentMap);
|
this.path = new String[] { namespace }; // Path is just ["namespace"]
|
||||||
System.out.println("Created namespace: " + namespace);
|
ROOT.put(namespace, Property.namespace(currentMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a sub-namespace inside a parent
|
||||||
|
*/
|
||||||
public ConfigManager(ConfigManager parent, String namespace) {
|
public ConfigManager(ConfigManager parent, String namespace) {
|
||||||
this.namespace = namespace;
|
|
||||||
this.currentMap = new LinkedHashMap<>();
|
this.currentMap = new LinkedHashMap<>();
|
||||||
Property<Map<String, Property<?>>> nsProp = Property.namespace(currentMap);
|
|
||||||
parent.property(namespace, nsProp);
|
|
||||||
System.out.println("Created sub-namespace: " + namespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sub(String name) {
|
// Build new path: parent path + current namespace
|
||||||
property(name, Property.namespace(new LinkedHashMap<>()));
|
this.path = new String[parent.path.length + 1];
|
||||||
|
System.arraycopy(parent.path, 0, this.path, 0, parent.path.length);
|
||||||
|
this.path[this.path.length - 1] = namespace;
|
||||||
|
|
||||||
|
parent.property(namespace, Property.namespace(currentMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a property
|
||||||
|
*/
|
||||||
public <T> Property<T> property(String name, Property<T> value) {
|
public <T> Property<T> property(String name, Property<T> value) {
|
||||||
currentMap.put(name, value);
|
currentMap.put(name, value);
|
||||||
loadProp(name, value);
|
loadSingleProperty(name, value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> void loadProp(String name, Property<T> prop) {
|
/**
|
||||||
JsonObject source = cachedThemeJson != null ? cachedThemeJson : loadAndCache();
|
* Add empty namespace
|
||||||
if (source == null)
|
*/
|
||||||
return;
|
public ConfigManager sub(String name) {
|
||||||
|
return new ConfigManager(this, name);
|
||||||
JsonElement namespaceJson = source.get(namespace);
|
|
||||||
if (namespaceJson == null || !namespaceJson.isJsonObject())
|
|
||||||
return;
|
|
||||||
|
|
||||||
JsonElement value = namespaceJson.getAsJsonObject().get(name);
|
|
||||||
if (value != null)
|
|
||||||
prop.loadFromJson(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static JsonObject loadAndCache() {
|
|
||||||
try {
|
|
||||||
if (!configFile.exists()) {
|
|
||||||
Files.writeString(configFile.toPath(), "{}");
|
|
||||||
return new JsonObject();
|
|
||||||
}
|
|
||||||
String json = Files.readString(configFile.toPath());
|
|
||||||
cachedThemeJson = JsonParser.parseString(json).getAsJsonObject();
|
|
||||||
return cachedThemeJson;
|
|
||||||
} catch (IOException e) {
|
|
||||||
SaturnClient.LOGGER.error("Error reading config file", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load entire config
|
||||||
|
*/
|
||||||
public static void load() {
|
public static void load() {
|
||||||
SaturnClient.LOGGER.info("Loading config...");
|
SaturnClient.LOGGER.info("Loading config...");
|
||||||
|
|
||||||
JsonObject json = loadAndCache();
|
JsonObject json = loadAndCache();
|
||||||
if (json == null)
|
if (json == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
properties.forEach((namespace, map) -> {
|
loadRecursive(json, ROOT);
|
||||||
JsonElement nsElement = json.get(namespace);
|
|
||||||
if (nsElement != null && nsElement.isJsonObject()) {
|
|
||||||
loadProperties(nsElement.getAsJsonObject(), map);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void loadProperties(JsonObject json, Map<String, Property<?>> props) {
|
|
||||||
props.forEach((name, prop) -> {
|
|
||||||
JsonElement el = json.get(name);
|
|
||||||
if (el != null)
|
|
||||||
prop.loadFromJson(el);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save entire config
|
||||||
|
*/
|
||||||
public static void save() {
|
public static void save() {
|
||||||
SaturnClient.LOGGER.info("Saving config...");
|
SaturnClient.LOGGER.info("Saving config...");
|
||||||
JsonObject root = new JsonObject();
|
|
||||||
properties.forEach((namespace, map) -> {
|
JsonObject rootJson = new JsonObject();
|
||||||
JsonObject nsJson = new JsonObject();
|
saveRecursive(rootJson, ROOT);
|
||||||
saveProperties(nsJson, map);
|
|
||||||
root.add(namespace, nsJson);
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String formatted = new GsonBuilder().setPrettyPrinting().create().toJson(root);
|
String formatted = new GsonBuilder()
|
||||||
|
.setPrettyPrinting()
|
||||||
|
.create()
|
||||||
|
.toJson(rootJson);
|
||||||
|
|
||||||
Files.writeString(configFile.toPath(), formatted);
|
Files.writeString(configFile.toPath(), formatted);
|
||||||
SaturnClient.LOGGER.info("Config saved successfully.");
|
SaturnClient.LOGGER.info("Config saved successfully.");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -109,8 +96,83 @@ public class ConfigManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void saveProperties(JsonObject json, Map<String, Property<?>> props) {
|
/**
|
||||||
props.forEach((name, prop) -> json.add(name, prop.toJson()));
|
* Recursive save
|
||||||
|
*/
|
||||||
|
private static void saveRecursive(JsonObject json, Map<String, Property<?>> map) {
|
||||||
|
map.forEach((name, prop) -> {
|
||||||
|
if (prop.isNamespace()) {
|
||||||
|
JsonObject child = new JsonObject();
|
||||||
|
saveRecursive(child, prop.getNamespaceMap());
|
||||||
|
json.add(name, child);
|
||||||
|
} else {
|
||||||
|
json.add(name, prop.toJson());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive load
|
||||||
|
*/
|
||||||
|
private static void loadRecursive(JsonObject json, Map<String, Property<?>> map) {
|
||||||
|
map.forEach((name, prop) -> {
|
||||||
|
JsonElement element = json.get(name);
|
||||||
|
if (element == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (prop.isNamespace() && element.isJsonObject()) {
|
||||||
|
loadRecursive(element.getAsJsonObject(), prop.getNamespaceMap());
|
||||||
|
} else {
|
||||||
|
prop.loadFromJson(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load only a single property immediately after creation,
|
||||||
|
* traversing the JSON tree based on this manager's path.
|
||||||
|
*/
|
||||||
|
private void loadSingleProperty(String name, Property<?> prop) {
|
||||||
|
JsonObject source = cachedJson != null ? cachedJson : loadAndCache();
|
||||||
|
if (source == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Traverse the tree to the correct namespace
|
||||||
|
JsonObject currentScope = source;
|
||||||
|
for (String segment : path) {
|
||||||
|
JsonElement next = currentScope.get(segment);
|
||||||
|
if (next != null && next.isJsonObject()) {
|
||||||
|
currentScope = next.getAsJsonObject();
|
||||||
|
} else {
|
||||||
|
return; // Path doesn't exist in config yet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now look for the property inside the correctly nested object
|
||||||
|
JsonElement element = currentScope.get(name);
|
||||||
|
if (element != null) {
|
||||||
|
prop.loadFromJson(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads file and caches json
|
||||||
|
*/
|
||||||
|
private static JsonObject loadAndCache() {
|
||||||
|
try {
|
||||||
|
if (!configFile.exists()) {
|
||||||
|
Files.writeString(configFile.toPath(), "{}");
|
||||||
|
return new JsonObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
String json = Files.readString(configFile.toPath());
|
||||||
|
cachedJson = JsonParser.parseString(json).getAsJsonObject();
|
||||||
|
return cachedJson;
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
SaturnClient.LOGGER.error("Error reading config file", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Property<?>> getProperties() {
|
public Map<String, Property<?>> getProperties() {
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
package org.saturnclient.saturnclient.config;
|
|
||||||
|
|
||||||
public class NamedProperty<T> {
|
|
||||||
public String name;
|
|
||||||
public Property<T> prop;
|
|
||||||
|
|
||||||
public NamedProperty(String name, Property<T> value) {
|
|
||||||
this.name = name;
|
|
||||||
this.prop = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,6 +10,15 @@ import com.google.gson.JsonObject;
|
|||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
|
|
||||||
public class Property<T> {
|
public class Property<T> {
|
||||||
|
public static class NamedProperty<T> {
|
||||||
|
public String name;
|
||||||
|
public Property<T> prop;
|
||||||
|
|
||||||
|
public NamedProperty(String name, Property<T> value) {
|
||||||
|
this.name = name;
|
||||||
|
this.prop = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum PropertyType {
|
public enum PropertyType {
|
||||||
BOOLEAN,
|
BOOLEAN,
|
||||||
@@ -277,4 +286,13 @@ public class Property<T> {
|
|||||||
if (value != null)
|
if (value != null)
|
||||||
this.loadFromJson(value);
|
this.loadFromJson(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isNamespace() {
|
||||||
|
return type == PropertyType.NAMESPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Map<String, Property<?>> getNamespaceMap() {
|
||||||
|
return isNamespace() ? (Map<String, Property<?>>) (Object) value : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.saturnclient.saturnclient.config;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class SaturnClientConfig {
|
||||||
|
public static ConfigManager config;
|
||||||
|
|
||||||
|
public static Property<Boolean> realisticLogo = Property.bool(false);
|
||||||
|
public static Property<Boolean> saturnTitleScreen = Property.bool(true);
|
||||||
|
public static Property<Boolean> bendyCloaks = Property.bool(true);
|
||||||
|
public static Property<Integer> openEmoteWheel = Property.keybinding(GLFW.GLFW_KEY_B);
|
||||||
|
public static Property<Boolean> stagger = Property.bool(true);
|
||||||
|
|
||||||
|
public static Identifier getLogo() {
|
||||||
|
return realisticLogo.value ? Textures.REALISTIC_LOGO : Textures.LOGO;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
config = new ConfigManager("Saturn Client");
|
||||||
|
config.property("Realistic logo", realisticLogo);
|
||||||
|
config.property("Saturn client title screen", saturnTitleScreen);
|
||||||
|
config.property("Open Emote Wheel", openEmoteWheel);
|
||||||
|
config.property("Bendy Cloaks", bendyCloaks);
|
||||||
|
config.property("Stagger Animations", stagger);
|
||||||
|
|
||||||
|
// Initialize a sub namespace for theme
|
||||||
|
Theme.init(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package org.saturnclient.saturnclient.config;
|
||||||
|
|
||||||
|
public class Theme {
|
||||||
|
// Main UI background (slightly warm dark to match Saturn tone)
|
||||||
|
public static final Property<Integer> BACKGROUND = Property.color(0xFF12100D);
|
||||||
|
|
||||||
|
// Default text color
|
||||||
|
public static final Property<Integer> FOREGROUND = Property.color(0xFFF2E6D2);
|
||||||
|
|
||||||
|
// Widget default background (normal state)
|
||||||
|
public static final Property<Integer> PRIMARY = Property.color(0xFF1C1915);
|
||||||
|
|
||||||
|
// Widget text color
|
||||||
|
public static final Property<Integer> PRIMARY_FG = Property.color(0xFFEAD9B8);
|
||||||
|
|
||||||
|
// Saturn brand color (hovered / enabled / selected)
|
||||||
|
public static final Property<Integer> ACCENT = Property.color(0xFFE2BF7D);
|
||||||
|
|
||||||
|
// Text/icons shown on accent background
|
||||||
|
public static final Property<Integer> ACCENT_FG = Property.color(0xFF1A140A);
|
||||||
|
|
||||||
|
// Misc colors
|
||||||
|
public static final Property<Integer> SCROLL = Property.color(0xFFE2BF7D);
|
||||||
|
|
||||||
|
// UI metrics
|
||||||
|
public static final Property<Integer> BG_RADIUS = Property.integer(12);
|
||||||
|
public static final Property<Integer> WIDGET_RADIUS = Property.integer(10);
|
||||||
|
|
||||||
|
// Font (keeping your current system)
|
||||||
|
public static Property<Integer> FONT = Property.font(1);
|
||||||
|
|
||||||
|
public static void init(ConfigManager parent) {
|
||||||
|
ConfigManager config = new ConfigManager(parent, "UI Style");
|
||||||
|
config.property("Background", BACKGROUND);
|
||||||
|
config.property("Foreground", FOREGROUND);
|
||||||
|
config.property("Primary", PRIMARY);
|
||||||
|
config.property("Primary Foreground", PRIMARY_FG);
|
||||||
|
config.property("Accent", ACCENT);
|
||||||
|
config.property("Accent Foreground", ACCENT_FG);
|
||||||
|
config.property("Scrollbar Color", SCROLL);
|
||||||
|
|
||||||
|
config.property("Background Radius", BG_RADIUS);
|
||||||
|
config.property("Widget Radius", WIDGET_RADIUS);
|
||||||
|
|
||||||
|
config.property("Font", FONT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* primary by default, accent if true
|
||||||
|
*/
|
||||||
|
public static int getBg(boolean hover) {
|
||||||
|
return hover ? ACCENT.value : PRIMARY.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Foreground) primary by default, accent if true
|
||||||
|
*/
|
||||||
|
public static int getFg(boolean hover) {
|
||||||
|
return hover ? ACCENT_FG.value : PRIMARY_FG.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplies existing alpha with 0–255 alpha.
|
||||||
|
*/
|
||||||
|
public static int withAlpha(int alpha, int color) {
|
||||||
|
alpha = Math.max(0, Math.min(255, alpha));
|
||||||
|
|
||||||
|
int originalAlpha = (color >>> 24) & 0xFF;
|
||||||
|
|
||||||
|
// Merge (multiply) alphas
|
||||||
|
int merged = (originalAlpha * alpha) / 255;
|
||||||
|
|
||||||
|
return (color & 0x00FFFFFF) | (merged << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplies existing alpha with 0.0–1.0 alpha.
|
||||||
|
*/
|
||||||
|
public static int withAlpha(float alpha, int color) {
|
||||||
|
alpha = Math.max(0f, Math.min(1f, alpha));
|
||||||
|
|
||||||
|
int originalAlpha = (color >>> 24) & 0xFF;
|
||||||
|
|
||||||
|
int merged = (int) (originalAlpha * alpha);
|
||||||
|
|
||||||
|
return (color & 0x00FFFFFF) | (merged << 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
package org.saturnclient.saturnclient.config;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
|
|
||||||
public class ThemeManager {
|
|
||||||
private static File themeFile = new File(
|
|
||||||
SaturnClient.client.runDirectory,
|
|
||||||
"saturn.theme.json");
|
|
||||||
private static List<ThemeManager> theme = new ArrayList<>();
|
|
||||||
private static JsonObject cachedThemeJson = null;
|
|
||||||
|
|
||||||
private Map<String, Map<String, Object>> states;
|
|
||||||
private Map<String, Property<?>> currentStyling;
|
|
||||||
private String namespace;
|
|
||||||
|
|
||||||
public ThemeManager(String namespace, String... states) {
|
|
||||||
this.namespace = namespace;
|
|
||||||
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<String, Object> tProp : states.get(state).entrySet()) {
|
|
||||||
currentStyling.get(tProp.getKey()).setValue(tProp.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void applyState(String state) {
|
|
||||||
for (Map.Entry<String, Object> tProp : states.get(state).entrySet()) {
|
|
||||||
if (!states.get(null).get(tProp.getKey()).equals(tProp.getValue()))
|
|
||||||
currentStyling.get(tProp.getKey()).setValue(tProp.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> Property<T> property(String name, Property<T> prop) {
|
|
||||||
for (Map.Entry<String, Map<String, Object>> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
currentStyling.put(name, prop);
|
|
||||||
|
|
||||||
return prop;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> void propertyStateDefault(String state, String name, T value) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.saturnclient.saturnclient.cosmetics;
|
package org.saturnclient.saturnclient.cosmetics;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
|
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
|
||||||
|
import org.saturnclient.saturnclient.config.SaturnClientConfig;
|
||||||
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
||||||
|
|
||||||
import net.minecraft.client.render.OverlayTexture;
|
import net.minecraft.client.render.OverlayTexture;
|
||||||
@@ -283,14 +283,16 @@ public class CloakFeatureRenderer extends FeatureRenderer<PlayerEntityRenderStat
|
|||||||
|
|
||||||
public void render(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light,
|
public void render(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light,
|
||||||
PlayerEntityRenderState playerEntityRenderState, float f, float g) {
|
PlayerEntityRenderState playerEntityRenderState, float f, float g) {
|
||||||
if (playerEntityRenderState.invisible || !playerEntityRenderState.capeVisible) {
|
if (playerEntityRenderState.invisible || !playerEntityRenderState.capeVisible
|
||||||
|
|| playerEntityRenderState.skinTextures.capeTexture() != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playerEntityRenderState.skinTextures.capeTexture() != null) {
|
SaturnPlayer player = SaturnPlayer.get(playerEntityRenderState.name);
|
||||||
|
|
||||||
|
if (player == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SaturnPlayer player = SaturnPlayer.get(playerEntityRenderState.name);
|
|
||||||
|
|
||||||
Identifier customCape = Cloaks.getCurrentCloakTexture(player.uuid);
|
Identifier customCape = Cloaks.getCurrentCloakTexture(player.uuid);
|
||||||
if (customCape == null || this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack,
|
if (customCape == null || this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack,
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import net.minecraft.client.option.KeyBinding;
|
|||||||
import net.minecraft.client.util.InputUtil;
|
import net.minecraft.client.util.InputUtil;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.client.ServiceClient;
|
import org.saturnclient.saturnclient.client.ServiceClient;
|
||||||
|
import org.saturnclient.saturnclient.config.SaturnClientConfig;
|
||||||
import org.saturnclient.ui2.screens.EmoteWheel;
|
import org.saturnclient.ui2.screens.EmoteWheel;
|
||||||
import org.saturnclient.ui2.screens.ShiftMenu;
|
import org.saturnclient.ui2.screens.ShiftMenu;
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import net.minecraft.text.Text;
|
|||||||
import net.minecraft.util.Formatting;
|
import net.minecraft.util.Formatting;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
import org.saturnclient.saturnclient.client.player.Roles;
|
||||||
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
|
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -43,8 +43,8 @@ public abstract class NameTagMixin<S extends EntityRenderState> {
|
|||||||
UUID uuid = isSaturn(state);
|
UUID uuid = isSaturn(state);
|
||||||
|
|
||||||
if (uuid != null) {
|
if (uuid != null) {
|
||||||
MutableText iconText = Text.literal(SaturnClientConfig.getSaturnIndicator())
|
MutableText iconText = Text.literal(Roles.getSaturnIndicator())
|
||||||
.styled(style -> style.withColor(SaturnClientConfig.getIconColor(uuid)));
|
.styled(style -> style.withColor(Roles.getIconColor(uuid)));
|
||||||
|
|
||||||
Text nameText = text.copy().styled(style -> style.withColor(Formatting.WHITE));
|
Text nameText = text.copy().styled(style -> style.withColor(Formatting.WHITE));
|
||||||
|
|
||||||
@@ -59,8 +59,10 @@ public abstract class NameTagMixin<S extends EntityRenderState> {
|
|||||||
if (state instanceof PlayerEntityRenderState) {
|
if (state instanceof PlayerEntityRenderState) {
|
||||||
String name = ((PlayerEntityRenderState) state).name;
|
String name = ((PlayerEntityRenderState) state).name;
|
||||||
SaturnPlayer player = SaturnPlayer.get(name);
|
SaturnPlayer player = SaturnPlayer.get(name);
|
||||||
|
if (player != null) {
|
||||||
return player.uuid;
|
return player.uuid;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.saturnclient.saturnclient.mixin;
|
package org.saturnclient.saturnclient.mixin;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
import org.saturnclient.saturnclient.config.SaturnClientConfig;
|
||||||
import org.saturnclient.ui2.screens.TitleMenu;
|
import org.saturnclient.ui2.screens.TitleMenu;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.saturnclient.saturnclient.mixin;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
import org.saturnclient.ui2.resources.Textures;
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -40,11 +41,8 @@ public abstract class SplashOverlayMixin {
|
|||||||
@Shadow(remap = false)
|
@Shadow(remap = false)
|
||||||
private float progress;
|
private float progress;
|
||||||
|
|
||||||
private static int withAlpha(int color, int alpha) {
|
|
||||||
return color & 0xFFFFFF | alpha << 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @author SaturnClient
|
||||||
* @reason Replace vanilla splash rendering completely but keep exit logic
|
* @reason Replace vanilla splash rendering completely but keep exit logic
|
||||||
*/
|
*/
|
||||||
@Overwrite
|
@Overwrite
|
||||||
@@ -80,19 +78,17 @@ public abstract class SplashOverlayMixin {
|
|||||||
if (fadeOutProgress >= 1.0F) {
|
if (fadeOutProgress >= 1.0F) {
|
||||||
renderCurrentScreen(context, mouseX, mouseY, delta);
|
renderCurrentScreen(context, mouseX, mouseY, delta);
|
||||||
int overlayAlpha = computeOverlayAlpha(fadeOutProgress - 1f);
|
int overlayAlpha = computeOverlayAlpha(fadeOutProgress - 1f);
|
||||||
// context.fill(0, 0, screenWidth, screenHeight,
|
|
||||||
// withAlpha(0x53389E, overlayAlpha));
|
|
||||||
scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight,
|
scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight,
|
||||||
withAlpha(0xFFFFFF, overlayAlpha));
|
Theme.withAlpha(overlayAlpha, 0xFFFFFFFF));
|
||||||
} else if (reloading) {
|
} else if (reloading) {
|
||||||
if (reloadProgress < 1.0F) {
|
if (reloadProgress < 1.0F) {
|
||||||
renderCurrentScreen(context, mouseX, mouseY, delta);
|
renderCurrentScreen(context, mouseX, mouseY, delta);
|
||||||
}
|
}
|
||||||
scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight,
|
scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight,
|
||||||
withAlpha(0xFFFFFF, alpha));
|
Theme.withAlpha(alpha, 0xFFFFFFFF));
|
||||||
} else {
|
} else {
|
||||||
scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight,
|
scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight,
|
||||||
withAlpha(0xFFFFFF, alpha));
|
Theme.withAlpha(alpha, 0xFFFFFFFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
float u = this.reload.getProgress();
|
float u = this.reload.getProgress();
|
||||||
@@ -120,18 +116,19 @@ public abstract class SplashOverlayMixin {
|
|||||||
/** Draw the main logo centered */
|
/** Draw the main logo centered */
|
||||||
private void drawLogo(RenderScope scope, int screenWidth, int screenHeight, int alpha) {
|
private void drawLogo(RenderScope scope, int screenWidth, int screenHeight, int alpha) {
|
||||||
scope.drawTexture(Textures.LOGO, (screenWidth - 60) / 2, ((screenHeight - 60) / 2) - 20, 0, 0, 60, 60,
|
scope.drawTexture(Textures.LOGO, (screenWidth - 60) / 2, ((screenHeight - 60) / 2) - 20, 0, 0, 60, 60,
|
||||||
withAlpha(0xFFFFFF, alpha));
|
Theme.withAlpha(alpha, 0xFFFFFFFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderProgressBar(RenderScope scope, DrawContext context, int screenWidth, int screenHeight,
|
private void renderProgressBar(RenderScope scope, DrawContext context, int screenWidth, int screenHeight,
|
||||||
int alpha) {
|
int alpha) {
|
||||||
int progressY = ((screenHeight - 5) / 2) + 25;
|
int progressY = ((screenHeight - 5) / 2) + 25;
|
||||||
context.drawBorder((screenWidth - 120) / 2, progressY, 120, 5, withAlpha(0xFFFFFF, alpha));
|
context.drawBorder((screenWidth - 120) / 2, progressY, 120, 5, Theme.withAlpha(alpha, 0xFFFFFFFF));
|
||||||
|
|
||||||
int progressWidth = Math.min((int) (progress * 120), 120);
|
int progressWidth = Math.min((int) (progress * 120), 120);
|
||||||
int progressX = (screenWidth - 120) / 2;
|
int progressX = (screenWidth - 120) / 2;
|
||||||
|
|
||||||
context.fill(progressX, progressY, progressX + progressWidth, progressY + 5, withAlpha(0xFFFFFF, alpha));
|
context.fill(progressX, progressY, progressX + progressWidth, progressY + 5,
|
||||||
|
Theme.withAlpha(alpha, 0xFFFFFFFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Compute overlay alpha from fade progress */
|
/** Compute overlay alpha from fade progress */
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import net.minecraft.util.Formatting;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
import org.saturnclient.saturnclient.client.player.Roles;
|
||||||
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
|
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
@@ -34,8 +34,8 @@ public abstract class TabListMixin {
|
|||||||
UUID uuid = profile.getId();
|
UUID uuid = profile.getId();
|
||||||
|
|
||||||
if (SaturnPlayer.get(uuid) != null) {
|
if (SaturnPlayer.get(uuid) != null) {
|
||||||
return Text.literal(SaturnClientConfig.getSaturnIndicator())
|
return Text.literal(Roles.getSaturnIndicator())
|
||||||
.styled(style -> style.withColor(SaturnClientConfig.getIconColor(uuid)))
|
.styled(style -> style.withColor(Roles.getIconColor(uuid)))
|
||||||
.append(Text.literal(name).styled(style -> style.withColor(Formatting.WHITE)));
|
.append(Text.literal(name).styled(style -> style.withColor(Formatting.WHITE)));
|
||||||
}
|
}
|
||||||
return Text.literal(name);
|
return Text.literal(name);
|
||||||
|
|||||||
@@ -32,6 +32,22 @@ public class Element {
|
|||||||
public void charTyped(char typedChar) {
|
public void charTyped(char typedChar) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playAnimationFrame(long elapsed) {
|
||||||
|
if (this.animation != null && elapsed >= this.animation.delay) {
|
||||||
|
this.animation.tick(this.curve
|
||||||
|
.apply(Math.min(1.0, (double) (elapsed - this.animation.delay) / this.animation.duration)), this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Element dimensions(int width, int height) {
|
public Element dimensions(int width, int height) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
|
|||||||
@@ -4,13 +4,15 @@ public class ElementContext {
|
|||||||
public int mouseX, mouseY;
|
public int mouseX, mouseY;
|
||||||
public int elementWidth, elementHeight;
|
public int elementWidth, elementHeight;
|
||||||
public float elementScale;
|
public float elementScale;
|
||||||
|
public long elapsed;
|
||||||
|
|
||||||
public ElementContext(int mouseX, int mouseY, Element e) {
|
public ElementContext(long elapsed, int mouseX, int mouseY, Element e) {
|
||||||
this.mouseX = mouseX - e.x;
|
this.mouseX = mouseX - e.x;
|
||||||
this.mouseY = mouseY - e.y;
|
this.mouseY = mouseY - e.y;
|
||||||
this.elementWidth = e.width;
|
this.elementWidth = e.width;
|
||||||
this.elementHeight = e.height;
|
this.elementHeight = e.height;
|
||||||
this.elementScale = e.scale;
|
this.elementScale = e.scale;
|
||||||
|
this.elapsed = elapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHovering() {
|
public boolean isHovering() {
|
||||||
|
|||||||
@@ -398,4 +398,45 @@ public class RenderScope {
|
|||||||
sprite.getMinV(), sprite.getMaxV(), color);
|
sprite.getMinV(), sprite.getMaxV(), color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void fill(int x1, int y1, int x2, int y2, int color) {
|
||||||
|
this.fill(x1, y1, x2, y2, 0, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fill(int x1, int y1, int x2, int y2, int z, int color) {
|
||||||
|
this.fill(RenderLayer.getGui(), x1, y1, x2, y2, z, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int color) {
|
||||||
|
this.fill(layer, x1, y1, x2, y2, 0, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int z, int color) {
|
||||||
|
Matrix4f matrix4f = this.matrices.peek().getPositionMatrix();
|
||||||
|
int i;
|
||||||
|
if (x1 < x2) {
|
||||||
|
i = x1;
|
||||||
|
x1 = x2;
|
||||||
|
x2 = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y1 < y2) {
|
||||||
|
i = y1;
|
||||||
|
y1 = y2;
|
||||||
|
y2 = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(layer);
|
||||||
|
vertexConsumer.vertex(matrix4f, (float) x1, (float) y1, (float) z).color(color);
|
||||||
|
vertexConsumer.vertex(matrix4f, (float) x1, (float) y2, (float) z).color(color);
|
||||||
|
vertexConsumer.vertex(matrix4f, (float) x2, (float) y2, (float) z).color(color);
|
||||||
|
vertexConsumer.vertex(matrix4f, (float) x2, (float) y1, (float) z).color(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawBorder(int x, int y, int width, int height, int color) {
|
||||||
|
this.fill(x, y, x + width, y + 1, color);
|
||||||
|
this.fill(x, y + height - 1, x + width, y + height, color);
|
||||||
|
this.fill(x, y + 1, x + 1, y + height - 1, color);
|
||||||
|
this.fill(x + width - 1, y + 1, x + width, y + height - 1, color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package org.saturnclient.ui2;
|
package org.saturnclient.ui2;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
||||||
import org.saturnclient.ui2.anim.Animation;
|
|
||||||
import org.saturnclient.ui2.anim.SlideXAbsolute;
|
|
||||||
import org.saturnclient.ui2.components.ElementRenderer;
|
import org.saturnclient.ui2.components.ElementRenderer;
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
@@ -15,6 +15,8 @@ import net.minecraft.client.gui.DrawContext;
|
|||||||
import net.minecraft.client.gui.RotatingCubeMapRenderer;
|
import net.minecraft.client.gui.RotatingCubeMapRenderer;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
import net.minecraft.client.render.DefaultFramebufferSet;
|
import net.minecraft.client.render.DefaultFramebufferSet;
|
||||||
|
import net.minecraft.client.texture.ResourceTexture;
|
||||||
|
import net.minecraft.client.texture.TextureManager;
|
||||||
import net.minecraft.client.util.Pool;
|
import net.minecraft.client.util.Pool;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
@@ -23,12 +25,12 @@ public abstract class SaturnScreen extends Screen {
|
|||||||
private final Pool pool = new Pool(3);
|
private final Pool pool = new Pool(3);
|
||||||
protected List<Element> elements = new ArrayList<>();
|
protected List<Element> elements = new ArrayList<>();
|
||||||
protected float backgroundOpacity = 1.0f;
|
protected float backgroundOpacity = 1.0f;
|
||||||
public int blurDuration = 700;
|
protected Instant start = null;
|
||||||
public float blurProgress = 0.0f;
|
|
||||||
public int backgroundBlur = 10;
|
public int backgroundBlur = 10;
|
||||||
|
|
||||||
protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer(
|
protected static final Identifier PANORAMA = Identifier.of("saturnclient",
|
||||||
Identifier.of("saturnclient", "textures/gui/title/background/panorama"));
|
"textures/gui/title/background/panorama");
|
||||||
|
protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer(PANORAMA);
|
||||||
|
|
||||||
public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER;
|
public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER;
|
||||||
|
|
||||||
@@ -36,41 +38,24 @@ public abstract class SaturnScreen extends Screen {
|
|||||||
ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER);
|
ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void preload(MinecraftClient client) {
|
||||||
|
TextureManager textureManager = client.getTextureManager();
|
||||||
|
|
||||||
|
// Force upload each texture to GPU
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
String var10001 = PANORAMA.getPath();
|
||||||
|
Identifier tex = PANORAMA.withPath(var10001 + "_" + i + ".png");
|
||||||
|
ResourceTexture resourceTexture = new ResourceTexture(tex);
|
||||||
|
textureManager.registerTexture(tex, resourceTexture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public SaturnScreen(String title) {
|
public SaturnScreen(String title) {
|
||||||
super(Text.literal(title));
|
super(Text.literal(title));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(Element element) {
|
public void draw(Element element) {
|
||||||
synchronized (elements) {
|
ElementRenderer.draw(elements, element);
|
||||||
elements.add(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.animation != null) {
|
|
||||||
element.animation.init(element);
|
|
||||||
|
|
||||||
Animation.execute((Float progress) -> {
|
|
||||||
element.animation.tick(progress, element);
|
|
||||||
}, element.animation.duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.duration != null) {
|
|
||||||
new Thread(() -> {
|
|
||||||
try {
|
|
||||||
Animation fadeOut = new SlideXAbsolute(700, -(width - element.x));
|
|
||||||
Thread.sleep(element.duration);
|
|
||||||
fadeOut.init(element);
|
|
||||||
Animation.executeSync((Float progress) -> {
|
|
||||||
fadeOut.tick(progress, element);
|
|
||||||
}, fadeOut.duration);
|
|
||||||
synchronized (elements) {
|
|
||||||
elements.remove(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -79,10 +64,6 @@ public abstract class SaturnScreen extends Screen {
|
|||||||
width *= 2;
|
width *= 2;
|
||||||
height *= 2;
|
height *= 2;
|
||||||
ui(); // abstraction to render the saturn ui and also render extra stuff here
|
ui(); // abstraction to render the saturn ui and also render extra stuff here
|
||||||
|
|
||||||
Animation.execute((Float progress) -> {
|
|
||||||
blurProgress = progress;
|
|
||||||
}, blurDuration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void ui();
|
public abstract void ui();
|
||||||
@@ -90,6 +71,11 @@ public abstract class SaturnScreen extends Screen {
|
|||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||||
|
if (start == null) {
|
||||||
|
start = Instant.now();
|
||||||
|
}
|
||||||
|
long elapsed = Duration.between(start, Instant.now()).toMillis();
|
||||||
|
|
||||||
mouseX *= 2;
|
mouseX *= 2;
|
||||||
mouseY *= 2;
|
mouseY *= 2;
|
||||||
|
|
||||||
@@ -100,8 +86,9 @@ public abstract class SaturnScreen extends Screen {
|
|||||||
PostEffectProcessor postEffectProcessor = this.client.getShaderLoader().loadPostEffect(
|
PostEffectProcessor postEffectProcessor = this.client.getShaderLoader().loadPostEffect(
|
||||||
Identifier.ofVanilla("blur"),
|
Identifier.ofVanilla("blur"),
|
||||||
DefaultFramebufferSet.MAIN_ONLY);
|
DefaultFramebufferSet.MAIN_ONLY);
|
||||||
|
|
||||||
if (postEffectProcessor != null) {
|
if (postEffectProcessor != null) {
|
||||||
postEffectProcessor.setUniforms("Radius", backgroundBlur * blurProgress);
|
postEffectProcessor.setUniforms("Radius", backgroundBlur * Math.min((float) elapsed / 700, 1.0f));
|
||||||
postEffectProcessor.render(this.client.getFramebuffer(), this.pool);
|
postEffectProcessor.render(this.client.getFramebuffer(), this.pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +101,7 @@ public abstract class SaturnScreen extends Screen {
|
|||||||
|
|
||||||
renderScope.matrices.scale(0.5f, 0.5f, 0.5f);
|
renderScope.matrices.scale(0.5f, 0.5f, 0.5f);
|
||||||
|
|
||||||
ElementRenderer.render(new ArrayList<>(elements), renderScope, mouseX, mouseY);
|
ElementRenderer.render(new ArrayList<>(elements), elapsed, renderScope, mouseX, mouseY);
|
||||||
|
|
||||||
renderScope.matrices.pop();
|
renderScope.matrices.pop();
|
||||||
}
|
}
|
||||||
@@ -129,6 +116,26 @@ public abstract class SaturnScreen extends Screen {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
|
||||||
|
mouseX *= 2;
|
||||||
|
mouseY *= 2;
|
||||||
|
|
||||||
|
ElementRenderer.mouseDragged(elements, mouseX, mouseY, button, deltaX, deltaY);
|
||||||
|
|
||||||
|
return super.mouseReleased(mouseX, mouseY, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mouseReleased(double mouseX, double mouseY, int button) {
|
||||||
|
mouseX *= 2;
|
||||||
|
mouseY *= 2;
|
||||||
|
|
||||||
|
ElementRenderer.mouseReleased(elements, mouseX, mouseY, button);
|
||||||
|
|
||||||
|
return super.mouseReleased(mouseX, mouseY, button);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean mouseScrolled(
|
public boolean mouseScrolled(
|
||||||
double mouseX,
|
double mouseX,
|
||||||
|
|||||||
@@ -1,75 +1,16 @@
|
|||||||
package org.saturnclient.ui2.anim;
|
package org.saturnclient.ui2.anim;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
|
|
||||||
public abstract class Animation {
|
public abstract class Animation {
|
||||||
public int duration;
|
public int duration;
|
||||||
|
public int delay = 0;
|
||||||
|
|
||||||
Animation(int duration) {
|
Animation(int duration) {
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void tick(float progress, Element element);
|
public abstract void tick(double progress, Element element);
|
||||||
|
|
||||||
public abstract void init(Element element);
|
public abstract void init(Element element);
|
||||||
|
|
||||||
public static void execute(Consumer<Float> tick, int duration) {
|
|
||||||
new Thread(() -> {
|
|
||||||
Function<Double, Double> curveFunction = Curve::easeInOutCubic;
|
|
||||||
float progress = 0.0f;
|
|
||||||
double incremental = (1000 - duration) / 10000.0;
|
|
||||||
|
|
||||||
for (int i = 0; i <= 100; i++) {
|
|
||||||
float newProgress = (float) (double) curveFunction.apply(i / 100.0);
|
|
||||||
|
|
||||||
while (Math.abs(newProgress - progress) > 1e-6) {
|
|
||||||
if (progress < newProgress) {
|
|
||||||
progress += incremental;
|
|
||||||
if (progress > newProgress) progress = newProgress;
|
|
||||||
} else {
|
|
||||||
progress -= incremental;
|
|
||||||
if (progress < newProgress) progress = newProgress;
|
|
||||||
}
|
|
||||||
|
|
||||||
tick.accept(newProgress);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(duration / 100);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void executeSync(Consumer<Float> tick, int duration) {
|
|
||||||
Function<Double, Double> curveFunction = Curve::easeInOutCubic;
|
|
||||||
float progress = 0.0f;
|
|
||||||
double incremental = (1000 - duration) / 10000.0;
|
|
||||||
|
|
||||||
for (int i = 0; i <= 100; i++) {
|
|
||||||
float newProgress = (float) (double) curveFunction.apply(i / 100.0);
|
|
||||||
|
|
||||||
while (Math.abs(newProgress - progress) > 1e-6) {
|
|
||||||
if (progress < newProgress) {
|
|
||||||
progress += incremental;
|
|
||||||
if (progress > newProgress) progress = newProgress;
|
|
||||||
} else {
|
|
||||||
progress -= incremental;
|
|
||||||
if (progress < newProgress) progress = newProgress;
|
|
||||||
}
|
|
||||||
|
|
||||||
tick.accept(newProgress);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(duration / 100);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ public class Fade extends Animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(float progress, Element element) {
|
public void tick(double progress, Element element) {
|
||||||
element.opacity = targetOpacity * progress;
|
element.opacity = Math.max(0.1f, targetOpacity * (float) progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Element element) {
|
public void init(Element element) {
|
||||||
targetOpacity = element.opacity;
|
targetOpacity = element.opacity;
|
||||||
element.opacity = 0;
|
element.opacity = 0.1f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ public class FadeOut extends Animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(float progress, Element element) {
|
public void tick(double progress, Element element) {
|
||||||
element.opacity = targetOpacity - progress;
|
element.opacity = targetOpacity - (float) progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.saturnclient.ui2.anim;
|
||||||
|
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
|
||||||
|
public class SlideFade extends Animation {
|
||||||
|
public Fade fade;
|
||||||
|
public SlideY slideY;
|
||||||
|
|
||||||
|
public SlideFade(int duration, int offset) {
|
||||||
|
super(duration);
|
||||||
|
this.fade = new Fade(duration);
|
||||||
|
this.slideY = new SlideY(duration, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(double progress, Element element) {
|
||||||
|
fade.delay = this.delay;
|
||||||
|
fade.duration = this.duration;
|
||||||
|
|
||||||
|
slideY.delay = this.delay;
|
||||||
|
slideY.duration = this.duration;
|
||||||
|
|
||||||
|
fade.tick(progress, element);
|
||||||
|
slideY.tick(progress, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Element element) {
|
||||||
|
fade.init(element);
|
||||||
|
slideY.init(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ public class SlideX extends Animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(float progress, Element element) {
|
public void tick(double progress, Element element) {
|
||||||
element.x = elementX + (int) (offset * progress);
|
element.x = elementX + (int) (offset * progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class SlideXAbsolute extends Animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(float progress, Element element) {
|
public void tick(double progress, Element element) {
|
||||||
element.x = elementX + (int) (offset * progress);
|
element.x = elementX + (int) (offset * progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import org.saturnclient.ui2.Element;
|
|||||||
public class SlideY extends Animation {
|
public class SlideY extends Animation {
|
||||||
int offset = 20;
|
int offset = 20;
|
||||||
int maxOffset = 20;
|
int maxOffset = 20;
|
||||||
int elementY;
|
double startY;
|
||||||
|
|
||||||
public SlideY(int duration) {
|
public SlideY(int duration) {
|
||||||
super(duration);
|
super(duration);
|
||||||
@@ -26,13 +26,14 @@ public class SlideY extends Animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(float progress, Element element) {
|
public void init(Element element) {
|
||||||
element.y = elementY + (int) (offset * progress);
|
startY = element.y - offset;
|
||||||
|
element.y = (int) startY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Element element) {
|
public void tick(double progress, Element element) {
|
||||||
element.y -= offset;
|
double currentY = startY + offset * progress;
|
||||||
elementY = element.y;
|
element.y = (int) currentY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.saturnclient.ui2.components;
|
package org.saturnclient.ui2.components;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
@@ -10,13 +9,7 @@ import net.minecraft.client.render.RenderLayer;
|
|||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
public class CosmeticPreview extends Element {
|
public class CosmeticPreview extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("CosmeticPreview", "selected", "hovering");
|
static int padding = 14;
|
||||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0x89000000));
|
|
||||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
|
||||||
private static Property<Integer> padding = theme.property("padding", Property.integer(14));
|
|
||||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
|
||||||
|
|
||||||
static {}
|
|
||||||
|
|
||||||
Identifier sprite;
|
Identifier sprite;
|
||||||
private Runnable onClick;
|
private Runnable onClick;
|
||||||
@@ -33,22 +26,16 @@ public class CosmeticPreview extends Element {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
if (ctx.isHovering()) {
|
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value,
|
||||||
theme.setState("hovering");
|
isSelected ? Theme.ACCENT.value : Theme.PRIMARY.value);
|
||||||
} else if (isSelected) {
|
|
||||||
theme.setState("selected");
|
|
||||||
}
|
|
||||||
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
|
||||||
|
|
||||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
|
|
||||||
int texWidth = width - padding.value;
|
int texWidth = width - padding;
|
||||||
int texHeight = height - padding.value;
|
int texHeight = height - padding;
|
||||||
|
|
||||||
renderScope.drawTexture(sprite, padding.value / 2, padding.value / 2, 0, 0, texWidth, texHeight, fgColor.value);
|
renderScope.drawTexture(sprite, padding / 2, padding / 2, 0, 0, texWidth, texHeight,
|
||||||
|
Theme.FOREGROUND.value);
|
||||||
theme.setState(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import org.saturnclient.ui2.Element;
|
|||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
import org.saturnclient.ui2.Utils;
|
import org.saturnclient.ui2.Utils;
|
||||||
import org.saturnclient.ui2.anim.Animation;
|
|
||||||
|
|
||||||
public class ElementRenderer {
|
public class ElementRenderer {
|
||||||
public static void draw(List<Element> elements, Element element) {
|
public static void draw(List<Element> elements, Element element) {
|
||||||
@@ -17,20 +16,18 @@ public class ElementRenderer {
|
|||||||
|
|
||||||
if (element.animation != null) {
|
if (element.animation != null) {
|
||||||
element.animation.init(element);
|
element.animation.init(element);
|
||||||
|
|
||||||
Animation.execute((Float progress) -> {
|
|
||||||
element.animation.tick(progress, element);
|
|
||||||
}, element.animation.duration);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void render(List<Element> elements, RenderScope renderScope, int mouseX, int mouseY) {
|
public static void render(List<Element> elements, long elapsed, RenderScope renderScope, int mouseX, int mouseY) {
|
||||||
for (Element element : elements) {
|
for (Element element : elements) {
|
||||||
|
element.playAnimationFrame(elapsed);
|
||||||
|
|
||||||
renderScope.matrices.push();
|
renderScope.matrices.push();
|
||||||
renderScope.setOpacity(element.opacity);
|
renderScope.setOpacity(element.opacity);
|
||||||
renderScope.matrices.translate(element.x, element.y, 0);
|
renderScope.matrices.translate(element.x, element.y, 0);
|
||||||
renderScope.matrices.scale(element.scale, element.scale, 1.0f);
|
renderScope.matrices.scale(element.scale, element.scale, 1.0f);
|
||||||
element.render(renderScope, new ElementContext(mouseX, mouseY, element));
|
element.render(renderScope, new ElementContext(elapsed, mouseX, mouseY, element));
|
||||||
renderScope.matrices.pop();
|
renderScope.matrices.pop();
|
||||||
renderScope.setRenderLayer(null);
|
renderScope.setRenderLayer(null);
|
||||||
}
|
}
|
||||||
@@ -44,7 +41,10 @@ public class ElementRenderer {
|
|||||||
int adjustedMouseX = (int) mouseX - element.x;
|
int adjustedMouseX = (int) mouseX - element.x;
|
||||||
int adjustedMouseY = (int) mouseY - element.y;
|
int adjustedMouseY = (int) mouseY - element.y;
|
||||||
|
|
||||||
if (element.opacity > 0 && Utils.isHovering(adjustedMouseX, adjustedMouseY, element.width, element.height, element.scale)) {
|
element.mouseClicked(adjustedMouseX * element.scale, adjustedMouseY * element.scale, button);
|
||||||
|
|
||||||
|
if (element.opacity > 0 && Utils.isHovering(adjustedMouseX, adjustedMouseY, element.width,
|
||||||
|
element.height, element.scale)) {
|
||||||
element.focused = true;
|
element.focused = true;
|
||||||
element.click((int) (adjustedMouseX * element.scale), (int) (adjustedMouseY * element.scale));
|
element.click((int) (adjustedMouseX * element.scale), (int) (adjustedMouseY * element.scale));
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,8 @@ public class ElementRenderer {
|
|||||||
double horizontalAmount,
|
double horizontalAmount,
|
||||||
double verticalAmount) {
|
double verticalAmount) {
|
||||||
for (Element element : new ArrayList<>(elements)) {
|
for (Element element : new ArrayList<>(elements)) {
|
||||||
if (Utils.isHovering((int) mouseX - element.x, (int) mouseY - element.y, element.width, element.height, element.scale)) {
|
if (Utils.isHovering((int) mouseX - element.x, (int) mouseY - element.y, element.width, element.height,
|
||||||
|
element.scale)) {
|
||||||
element.scroll(
|
element.scroll(
|
||||||
(int) mouseX - element.x,
|
(int) mouseX - element.x,
|
||||||
(int) mouseY - element.y,
|
(int) mouseY - element.y,
|
||||||
@@ -81,4 +82,17 @@ public class ElementRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void mouseDragged(List<Element> elements, double mouseX, double mouseY, int button, double deltaX,
|
||||||
|
double deltaY) {
|
||||||
|
for (Element element : new ArrayList<>(elements)) {
|
||||||
|
element.mouseDragged(mouseX - element.x, mouseY - element.y, button, deltaX, deltaY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void mouseReleased(List<Element> elements, double mouseX, double mouseY, int button) {
|
||||||
|
for (Element element : new ArrayList<>(elements)) {
|
||||||
|
element.mouseReleased(mouseX - element.x, mouseY - element.y, button);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ package org.saturnclient.ui2.components;
|
|||||||
|
|
||||||
import org.saturnclient.modules.Module;
|
import org.saturnclient.modules.Module;
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
|
||||||
import org.saturnclient.ui2.resources.Fonts;
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
import org.saturnclient.ui2.resources.Textures;
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
@@ -15,23 +14,12 @@ import org.saturnclient.ui2.screens.ConfigEditor;
|
|||||||
import net.minecraft.client.render.RenderLayer;
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
|
||||||
public class SaturnModule extends Element {
|
public class SaturnModule extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("Module", "enabled", "hovering");
|
|
||||||
private static Property<Integer> bgColor = theme.property("bg", Property.color(0xFF1d202d));
|
|
||||||
private static Property<Integer> fgColor = theme.property("fg", Property.color(0xFFA1A2B8));
|
|
||||||
private static Property<Integer> iconFg = theme.property("icon-fg", Property.color(0xFFA1A2B8));
|
|
||||||
private static Property<Integer> iconBg = theme.property("icon-bg", Property.color(0xFF2e3248));
|
|
||||||
private static Property<Integer> tagBg = theme.property("tag-bg", Property.color(0xFF2e3248));
|
|
||||||
private static Property<Integer> iconRadius = theme.property("icon-radius", Property.color(10));
|
|
||||||
private static Property<Integer> font = theme.property("font", Property.font(1));
|
|
||||||
private static Property<Integer> radius = theme.property("radius", Property.color(10));
|
|
||||||
|
|
||||||
static {
|
private final Module mod;
|
||||||
theme.propertyStateDefault("enabled", "bg", 0xFF1d202d);
|
|
||||||
theme.propertyStateDefault("enabled", "icon-bg", 0xFF845eee);
|
|
||||||
theme.propertyStateDefault("hovering", "fg", 0xFF845eee);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Module mod;
|
static int p = 10; // padding
|
||||||
|
static int s = 14; // settings icon size
|
||||||
|
static int expand = 5; // settings icon click area
|
||||||
|
|
||||||
public SaturnModule(Module mod) {
|
public SaturnModule(Module mod) {
|
||||||
this.mod = mod;
|
this.mod = mod;
|
||||||
@@ -41,60 +29,137 @@ public class SaturnModule extends Element {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
int p = 10;
|
boolean hovered = ctx.isHovering();
|
||||||
int s = 14;
|
boolean enabled = mod.isEnabled();
|
||||||
boolean settingsHover = false;
|
|
||||||
|
int iconX = width - s - p;
|
||||||
|
int iconY = height - s - p;
|
||||||
|
|
||||||
|
boolean settingsHover = ctx.isHovering(
|
||||||
|
getSettingsX(),
|
||||||
|
getSettingsY(),
|
||||||
|
getSettingsHitBox(),
|
||||||
|
getSettingsHitBox());
|
||||||
|
|
||||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
|
|
||||||
if (mod.isEnabled()) {
|
// Resolve theme colors
|
||||||
theme.setState("enabled");
|
int bgColor = Theme.PRIMARY.value;
|
||||||
}
|
int fgColor = hovered && !settingsHover ? Theme.ACCENT.value : Theme.PRIMARY_FG.value;
|
||||||
|
|
||||||
if (ctx.isHovering(width - s - p - 5, height - s - p - 5, s + 10, s + 10)) {
|
int iconBg = enabled ? Theme.ACCENT.value : Theme.PRIMARY.value;
|
||||||
settingsHover = true;
|
int iconFg = enabled ? Theme.ACCENT_FG.value : fgColor;
|
||||||
} else if (ctx.isHovering()) {
|
|
||||||
theme.applyState("hovering");
|
|
||||||
}
|
|
||||||
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, radius.value, bgColor.value);
|
int settingsColor = settingsHover
|
||||||
|
? Theme.ACCENT.value
|
||||||
|
: Theme.withAlpha(160, fgColor);
|
||||||
|
|
||||||
int h = height - (p * 2);
|
int h = height - (p * 2);
|
||||||
|
|
||||||
renderScope.drawRoundedRectangle(p, p, h, h, iconRadius.value, iconBg.value);
|
// Main background
|
||||||
|
renderScope.drawRoundedRectangle(
|
||||||
|
0, 0,
|
||||||
|
width, height,
|
||||||
|
Theme.WIDGET_RADIUS.value,
|
||||||
|
bgColor);
|
||||||
|
|
||||||
renderScope.drawTexture(mod.getIconTexture(), p + (p / 2), p + (p / 2), 0, 0, h - p, h - p, iconFg.value);
|
// Icon background
|
||||||
|
renderScope.drawRoundedRectangle(
|
||||||
|
p, p,
|
||||||
|
h, h,
|
||||||
|
Theme.WIDGET_RADIUS.value,
|
||||||
|
iconBg);
|
||||||
|
|
||||||
renderScope.drawText(0.6f, mod.getName(), p+h+4, p + 1, font.value, fgColor.value);
|
// Icon
|
||||||
|
renderScope.drawTexture(
|
||||||
|
mod.getIconTexture(),
|
||||||
|
p + (p / 2),
|
||||||
|
p + (p / 2),
|
||||||
|
0, 0,
|
||||||
|
h - p,
|
||||||
|
h - p,
|
||||||
|
iconFg);
|
||||||
|
|
||||||
renderScope.drawText(0.35f, mod.getVersion(), width - p - (int) (Fonts.getWidth(mod.getVersion(), font.value) * 0.35f), p + 1, font.value, fgColor.value);
|
// Module name
|
||||||
|
renderScope.drawText(
|
||||||
|
0.6f,
|
||||||
|
mod.getName(),
|
||||||
|
p + h + 4,
|
||||||
|
p + 1,
|
||||||
|
Theme.FONT.value,
|
||||||
|
fgColor);
|
||||||
|
|
||||||
|
// Version (right aligned)
|
||||||
|
String version = mod.getVersion();
|
||||||
|
int versionWidth = (int) (Fonts.getWidth(version, Theme.FONT.value) * 0.35f);
|
||||||
|
|
||||||
|
renderScope.drawText(
|
||||||
|
0.35f,
|
||||||
|
version,
|
||||||
|
width - p - versionWidth,
|
||||||
|
p + 1,
|
||||||
|
Theme.FONT.value,
|
||||||
|
fgColor);
|
||||||
|
|
||||||
|
// Tags
|
||||||
int xt = p + h + 4;
|
int xt = p + h + 4;
|
||||||
for (String tag : mod.getTags()) {
|
for (String tag : mod.getTags()) {
|
||||||
int xtb = (int) (Fonts.getWidth(tag, font.value) * 0.4f);
|
int tagWidth = (int) (Fonts.getWidth(tag, Theme.FONT.value) * 0.4f);
|
||||||
renderScope.drawRoundedRectangle(xt, p + (h/2), xtb + 6, 12, 5, tagBg.value);
|
|
||||||
renderScope.drawText(0.4f, tag, xt+2, p + (h/2) + 3, font.value, fgColor.value);
|
renderScope.drawRoundedRectangle(
|
||||||
xt += xtb + 9;
|
xt,
|
||||||
|
p + (h / 2),
|
||||||
|
tagWidth + 6,
|
||||||
|
12,
|
||||||
|
5,
|
||||||
|
Theme.ACCENT.value);
|
||||||
|
|
||||||
|
renderScope.drawText(
|
||||||
|
0.4f,
|
||||||
|
tag,
|
||||||
|
xt + 2,
|
||||||
|
p + (h / 2) + 3,
|
||||||
|
Theme.FONT.value,
|
||||||
|
Theme.ACCENT_FG.value);
|
||||||
|
|
||||||
|
xt += tagWidth + 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settingsHover) {
|
// Settings icon
|
||||||
theme.setState("hovering");
|
renderScope.drawTexture(
|
||||||
}
|
Textures.SETTINGS,
|
||||||
|
iconX,
|
||||||
renderScope.drawTexture(Textures.SETTINGS, width - s - p, height - s - p, 0, 0, s, s, fgColor.value);
|
iconY,
|
||||||
|
0, 0,
|
||||||
theme.setState(null);
|
s, s,
|
||||||
|
settingsColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void click(int mouseX, int mouseY) {
|
public void click(int mouseX, int mouseY) {
|
||||||
int p = 10;
|
boolean settingsHover = Utils.isHovering(
|
||||||
int s = 14;
|
mouseX - getSettingsX(),
|
||||||
|
mouseY - getSettingsY(),
|
||||||
|
getSettingsHitBox(),
|
||||||
|
getSettingsHitBox(),
|
||||||
|
1.0f);
|
||||||
|
|
||||||
if (Utils.isHovering(mouseX - (width - s - p - 5), mouseY - (height - s - p - 5), s + 10, s + 10, 1.0f)) {
|
if (settingsHover) {
|
||||||
SaturnClient.client.setScreen(new ConfigEditor(mod.getConfig()));
|
SaturnClient.client.setScreen(new ConfigEditor(mod.getConfig()));
|
||||||
} else {
|
} else {
|
||||||
mod.setEnabled(!mod.isEnabled());
|
mod.setEnabled(!mod.isEnabled());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getSettingsX() {
|
||||||
|
return width - s - p - expand;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getSettingsY() {
|
||||||
|
return height - s - p - expand;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getSettingsHitBox() {
|
||||||
|
return s + expand * 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
package org.saturnclient.ui2.components;
|
package org.saturnclient.ui2.components;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
import org.saturnclient.saturnclient.config.SaturnClientConfig;
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
|
||||||
import org.saturnclient.ui2.resources.Textures;
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
@@ -18,19 +17,6 @@ import net.minecraft.client.render.RenderLayer;
|
|||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
public class Sidebar extends Element {
|
public class Sidebar extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("SideBar", "hovering");
|
|
||||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0x90000000));
|
|
||||||
private static Property<Integer> iconFg = theme.property("icon-fg", Property.color(0xFFFFFFFF));
|
|
||||||
private static Property<Integer> iconBg = theme.property("icon-bg", Property.color(0x00000000));
|
|
||||||
|
|
||||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
|
||||||
private static Property<Integer> iconRadius = theme.property("icon-radius", Property.integer(10));
|
|
||||||
private static Property<Integer> padding = theme.property("padding", Property.integer(10));
|
|
||||||
|
|
||||||
static {
|
|
||||||
theme.propertyStateDefault("hovering", "icon-bg", -7643914);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SidebarComponent {
|
public static class SidebarComponent {
|
||||||
Runnable onClick;
|
Runnable onClick;
|
||||||
boolean end;
|
boolean end;
|
||||||
@@ -79,36 +65,29 @@ public class Sidebar extends Element {
|
|||||||
int bottomRow = 0;
|
int bottomRow = 0;
|
||||||
|
|
||||||
int gap = 5; // 5px gap between icons
|
int gap = 5; // 5px gap between icons
|
||||||
int sp = 30 - padding.value + gap;
|
int padding = 10;
|
||||||
int s = 30 - (padding.value * 2);
|
int sp = 30 - padding + gap;
|
||||||
int s2 = s + padding.value;
|
int s = 30 - (padding * 2);
|
||||||
|
int s2 = s + padding;
|
||||||
|
|
||||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.BG_RADIUS.value, Theme.BACKGROUND.value);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (SidebarComponent component : components) {
|
for (SidebarComponent component : components) {
|
||||||
|
int y = component.end ? ((height - (sp * bottomRow)) - (s * 2)) : (padding + (sp * topRow));
|
||||||
|
boolean selected = ctx.isHovering(0, y - (padding / 2), s2, s2) || active == i;
|
||||||
|
|
||||||
|
renderScope.drawRoundedRectangle(padding / 2, y - (padding / 2), s + padding,
|
||||||
|
s + padding, Theme.WIDGET_RADIUS.value, Theme.getBg(selected));
|
||||||
|
|
||||||
|
renderScope.drawTexture(component.sprite, padding, y, 0, 0, s, s, Theme.getFg(selected));
|
||||||
|
|
||||||
if (component.end) {
|
if (component.end) {
|
||||||
int y = (height - (sp * bottomRow)) - (s * 2);
|
|
||||||
if (ctx.isHovering(0, y - (padding.value / 2), s2, s2) || active == i) {
|
|
||||||
theme.setState("hovering");
|
|
||||||
} else {
|
|
||||||
theme.setState(null);
|
|
||||||
}
|
|
||||||
renderScope.drawRoundedRectangle(padding.value / 2, y - (padding.value / 2), s + padding.value, s + padding.value, iconRadius.value, iconBg.value);
|
|
||||||
renderScope.drawTexture(component.sprite, padding.value, y, 0, 0, s, s, iconFg.value);
|
|
||||||
bottomRow += 1;
|
bottomRow += 1;
|
||||||
} else {
|
} else {
|
||||||
int y = padding.value + (sp * topRow);
|
|
||||||
if (ctx.isHovering(0, y - (padding.value / 2), s2, s2) || active == i) {
|
|
||||||
theme.setState("hovering");
|
|
||||||
} else {
|
|
||||||
theme.setState(null);
|
|
||||||
}
|
|
||||||
renderScope.drawRoundedRectangle(padding.value / 2, y - (padding.value / 2), s + padding.value, s + padding.value, iconRadius.value, iconBg.value);
|
|
||||||
renderScope.drawTexture(component.sprite, padding.value, y, 0, 0, s, s, iconFg.value);
|
|
||||||
topRow += 1;
|
topRow += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,25 +100,24 @@ public class Sidebar extends Element {
|
|||||||
int topRow = 0;
|
int topRow = 0;
|
||||||
int bottomRow = 0;
|
int bottomRow = 0;
|
||||||
|
|
||||||
int gap = 5; // same 5px gap here
|
int gap = 5;
|
||||||
int sp = 30 - padding.value + gap;
|
int padding = 10;
|
||||||
int s = 30 - (padding.value * 2);
|
int sp = 30 - padding + gap;
|
||||||
int s2 = s + padding.value;
|
int s = 30 - (padding * 2);
|
||||||
|
int s2 = s + padding;
|
||||||
|
|
||||||
for (SidebarComponent component : components) {
|
for (SidebarComponent component : components) {
|
||||||
if (component.end) {
|
int y = component.end ? ((height - (sp * bottomRow)) - (s * 2)) : (padding + (sp * topRow));
|
||||||
int y = (height - (sp * bottomRow)) - (s * 2);
|
boolean hovering = Utils.isHovering(mouseX - (padding / 2), mouseY - (y - (padding / 2)), s2, s2, scale);
|
||||||
if (Utils.isHovering(mouseX - (padding.value / 2), mouseY - (y - (padding.value / 2)), s2, s2, scale)) {
|
|
||||||
|
if (hovering) {
|
||||||
component.onClick.run();
|
component.onClick.run();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (component.end) {
|
||||||
bottomRow += 1;
|
bottomRow += 1;
|
||||||
} else {
|
} else {
|
||||||
int y = padding.value + (sp * topRow);
|
|
||||||
if (Utils.isHovering(mouseX - (padding.value / 2), mouseY - (y - (padding.value / 2)), s2, s2, scale)) {
|
|
||||||
component.onClick.run();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
topRow += 1;
|
topRow += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,246 +0,0 @@
|
|||||||
package org.saturnclient.ui2.components.dialog;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
|
||||||
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
|
||||||
import org.saturnclient.ui2.RenderScope;
|
|
||||||
import org.saturnclient.ui2.SaturnScreen;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
|
||||||
|
|
||||||
public class ColorDialog extends SaturnScreen {
|
|
||||||
private Property<Integer> prop;
|
|
||||||
private SaturnScreen parent;
|
|
||||||
private static final int PICKER_WIDTH = 200;
|
|
||||||
private static final int PICKER_HEIGHT = 200;
|
|
||||||
private static final int SLIDER_WIDTH = 200;
|
|
||||||
private static final int SLIDER_HEIGHT = 10;
|
|
||||||
private static final int HUE_SLIDER_HEIGHT = 10;
|
|
||||||
private float hue = 0.0f;
|
|
||||||
|
|
||||||
private int selectedX = 0;
|
|
||||||
private int selectedY = 0;
|
|
||||||
|
|
||||||
private float opacity = 1.0f;
|
|
||||||
private boolean dragging = false;
|
|
||||||
|
|
||||||
public ColorDialog(Property<Integer> prop , SaturnScreen parent) {
|
|
||||||
super("Color Dialog");
|
|
||||||
this.prop = prop;
|
|
||||||
this.parent = parent;
|
|
||||||
|
|
||||||
int alpha = (prop.value >> 24) & 0xFF;
|
|
||||||
if (alpha == 0) alpha = 255; // fallback if no alpha specified
|
|
||||||
this.opacity = alpha / 255.0f;
|
|
||||||
syncFromColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void ui() {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
SaturnClient.client.setScreen(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
|
||||||
super.render(context, mouseX, mouseY, delta);
|
|
||||||
RenderScope renderScope = new RenderScope(context.getMatrices(),
|
|
||||||
((DrawContextAccessor) context).getVertexConsumers());
|
|
||||||
|
|
||||||
renderScope.matrices.push();
|
|
||||||
|
|
||||||
renderScope.matrices.scale(0.5f, 0.5f, 0.5f);
|
|
||||||
|
|
||||||
int xStart = (width - PICKER_WIDTH) / 2;
|
|
||||||
int yStart = (height - PICKER_HEIGHT) / 2;
|
|
||||||
|
|
||||||
// Draw the HSV saturation/value square (with current hue)
|
|
||||||
for (int x = 0; x < PICKER_WIDTH; x++) {
|
|
||||||
for (int y = 0; y < PICKER_HEIGHT; y++) {
|
|
||||||
float saturation = x / (float) PICKER_WIDTH;
|
|
||||||
float value = 1.0f - y / (float) PICKER_HEIGHT;
|
|
||||||
int color = Color.HSBtoRGB(hue, saturation, value);
|
|
||||||
context.fill(xStart + x, yStart + y, xStart + x + 1, yStart + y + 1, 0xFF000000 | color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int x = (xStart + selectedX) - 4;
|
|
||||||
int y = (yStart + selectedY) - 4;
|
|
||||||
context.fill(x, y, x+8, y+8, 0xFF000000 | prop.value);
|
|
||||||
context.drawBorder(x, y, 8, 8, 0xFFffffff);
|
|
||||||
|
|
||||||
renderSlider(context, mouseX, mouseY, delta);
|
|
||||||
renderHueSlider(context);
|
|
||||||
|
|
||||||
renderScope.matrices.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void renderSlider(DrawContext context, int mouseX, int mouseY, float delta) {
|
|
||||||
int xStart = (width - SLIDER_WIDTH) / 2;
|
|
||||||
int yStart = (height - SLIDER_HEIGHT - PICKER_HEIGHT) / 2 - 10;
|
|
||||||
|
|
||||||
// Draw slider background (left = transparent, right = white)
|
|
||||||
for (int x = 0; x < SLIDER_WIDTH; x++) {
|
|
||||||
float localOpacity = x / (float) SLIDER_WIDTH;
|
|
||||||
int alpha = (int)(localOpacity * 255) & 0xFF;
|
|
||||||
int color = (alpha << 24) | (prop.value & 0xFFFFFF);
|
|
||||||
context.fill(xStart + x, yStart, xStart + x + 1, yStart + SLIDER_HEIGHT, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw current value as a marker (thin black line)
|
|
||||||
int knobX = xStart + (int)(opacity * SLIDER_WIDTH);
|
|
||||||
context.fill(knobX - 1, yStart - 2, knobX + 1, yStart + SLIDER_HEIGHT + 2, 0xFF000000);
|
|
||||||
|
|
||||||
// Draw opacity text
|
|
||||||
// context.drawText(textRenderer, String.format("Opacity: %.2f", opacity), xStart, yStart - 15, 0xFFFFFF, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderHueSlider(DrawContext context) {
|
|
||||||
int xStart = (width - SLIDER_WIDTH) / 2;
|
|
||||||
int yStart = (height + PICKER_HEIGHT) / 2 + 10;
|
|
||||||
|
|
||||||
for (int x = 0; x < SLIDER_WIDTH; x++) {
|
|
||||||
float localHue = x / (float) SLIDER_WIDTH;
|
|
||||||
int color = Color.HSBtoRGB(localHue, 1.0f, 1.0f);
|
|
||||||
context.fill(xStart + x, yStart, xStart + x + 1, yStart + HUE_SLIDER_HEIGHT, 0xFF000000 | color);
|
|
||||||
}
|
|
||||||
|
|
||||||
int knobX = xStart + (int)(hue * SLIDER_WIDTH);
|
|
||||||
context.fill(knobX - 1, yStart - 2, knobX + 1, yStart + HUE_SLIDER_HEIGHT + 2, 0xFF000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
|
||||||
mouseX *= 2;
|
|
||||||
mouseY *= 2;
|
|
||||||
|
|
||||||
int xStart = (width - PICKER_WIDTH) / 2;
|
|
||||||
int yStart = (height - PICKER_HEIGHT) / 2;
|
|
||||||
|
|
||||||
int relX = (int) mouseX - xStart;
|
|
||||||
int relY = (int) mouseY - yStart;
|
|
||||||
|
|
||||||
if (relX >= 0 && relX < PICKER_WIDTH && relY >= 0 && relY < PICKER_HEIGHT) {
|
|
||||||
float saturation = relX / (float) PICKER_WIDTH;
|
|
||||||
float value = 1.0f - relY / (float) PICKER_HEIGHT;
|
|
||||||
prop.value = Color.HSBtoRGB(hue, saturation, value);
|
|
||||||
|
|
||||||
int alpha = (int)(opacity * 255) & 0xFF;
|
|
||||||
prop.value = (alpha << 24) | (prop.value & 0xFFFFFF);
|
|
||||||
|
|
||||||
selectedX = relX;
|
|
||||||
selectedY = relY;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else if (isInSlider(mouseX, mouseY)) {
|
|
||||||
updateOpacity(mouseX);
|
|
||||||
dragging = true;
|
|
||||||
return true;
|
|
||||||
} else if (isInHueSlider(mouseX, mouseY)) {
|
|
||||||
updateHue(mouseX);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.mouseClicked(mouseX, mouseY, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean mouseReleased(double mouseX, double mouseY, int button) {
|
|
||||||
dragging = false;
|
|
||||||
return super.mouseReleased(mouseX, mouseY, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
|
|
||||||
mouseX *= 2;
|
|
||||||
mouseY *= 2;
|
|
||||||
|
|
||||||
if (isInHueSlider(mouseX, mouseY)) {
|
|
||||||
updateHue(mouseX);
|
|
||||||
return true;
|
|
||||||
} else if (dragging) {
|
|
||||||
updateOpacity(mouseX);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
int xStart = (width - PICKER_WIDTH) / 2;
|
|
||||||
int yStart = (height - PICKER_HEIGHT) / 2;
|
|
||||||
|
|
||||||
int relX = (int) mouseX - xStart;
|
|
||||||
int relY = (int) mouseY - yStart;
|
|
||||||
|
|
||||||
if (relX >= 0 && relX < PICKER_WIDTH && relY >= 0 && relY < PICKER_HEIGHT) {
|
|
||||||
float saturation = relX / (float) PICKER_WIDTH;
|
|
||||||
float value = 1.0f - relY / (float) PICKER_HEIGHT;
|
|
||||||
prop.value = Color.HSBtoRGB(hue, saturation, value);
|
|
||||||
|
|
||||||
int alpha = (int)(opacity * 255) & 0xFF;
|
|
||||||
prop.value = (alpha << 24) | (prop.value & 0xFFFFFF);
|
|
||||||
|
|
||||||
selectedX = relX;
|
|
||||||
selectedY = relY;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isInSlider(double mouseX, double mouseY) {
|
|
||||||
int xStart = (width - SLIDER_WIDTH) / 2;
|
|
||||||
int yStart = (height - SLIDER_HEIGHT - PICKER_HEIGHT) / 2 - 10;
|
|
||||||
return mouseX >= xStart && mouseX <= xStart + SLIDER_WIDTH &&
|
|
||||||
mouseY >= yStart && mouseY <= yStart + SLIDER_HEIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isInHueSlider(double mouseX, double mouseY) {
|
|
||||||
int xStart = (width - SLIDER_WIDTH) / 2;
|
|
||||||
int yStart = (height + PICKER_HEIGHT) / 2 + 10;
|
|
||||||
return mouseX >= xStart && mouseX <= xStart + SLIDER_WIDTH &&
|
|
||||||
mouseY >= yStart && mouseY <= yStart + HUE_SLIDER_HEIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateOpacity(double mouseX) {
|
|
||||||
int xStart = (width - SLIDER_WIDTH) / 2;
|
|
||||||
float newOpacity = (float)((mouseX - xStart) / SLIDER_WIDTH);
|
|
||||||
opacity = Math.max(0.0f, Math.min(1.0f, newOpacity));
|
|
||||||
|
|
||||||
int alpha = (int)(opacity * 255) & 0xFF;
|
|
||||||
prop.value = (alpha << 24) | (prop.value & 0xFFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateHue(double mouseX) {
|
|
||||||
int xStart = (width - SLIDER_WIDTH) / 2;
|
|
||||||
float newHue = (float)((mouseX - xStart) / SLIDER_WIDTH);
|
|
||||||
hue = Math.max(0.0f, Math.min(1.0f, newHue));
|
|
||||||
|
|
||||||
float saturation = selectedX / (float) PICKER_WIDTH;
|
|
||||||
float value = 1.0f - selectedY / (float) PICKER_HEIGHT;
|
|
||||||
prop.value = Color.HSBtoRGB(hue, saturation, value);
|
|
||||||
|
|
||||||
int alpha = (int)(opacity * 255) & 0xFF;
|
|
||||||
prop.value = (alpha << 24) | (prop.value & 0xFFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void syncFromColor() {
|
|
||||||
int rgb = prop.value & 0xFFFFFF;
|
|
||||||
float[] hsb = Color.RGBtoHSB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF, null);
|
|
||||||
|
|
||||||
this.hue = hsb[0];
|
|
||||||
|
|
||||||
float saturation = hsb[1];
|
|
||||||
float value = hsb[2];
|
|
||||||
|
|
||||||
this.selectedX = (int)(saturation * PICKER_WIDTH);
|
|
||||||
this.selectedY = (int)((1.0f - value) * PICKER_HEIGHT);
|
|
||||||
|
|
||||||
// Extract alpha and convert to opacity float
|
|
||||||
int alpha = (prop.value >> 24) & 0xFF;
|
|
||||||
if (alpha == 0) alpha = 255;
|
|
||||||
this.opacity = alpha / 255.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +1,183 @@
|
|||||||
package org.saturnclient.ui2.components.inputs;
|
package org.saturnclient.ui2.components.inputs;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import java.awt.Color;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
import org.saturnclient.ui2.SaturnScreen;
|
|
||||||
import org.saturnclient.ui2.components.dialog.ColorDialog;
|
|
||||||
|
|
||||||
public class HexInput extends Element {
|
public class HexInput extends Element {
|
||||||
public Property<Integer> prop;
|
public Property<Integer> prop;
|
||||||
public SaturnScreen screen;
|
|
||||||
|
|
||||||
public HexInput(Property<Integer> prop, SaturnScreen screen) {
|
// Picker state
|
||||||
|
private boolean open = false;
|
||||||
|
private float hue = 0f;
|
||||||
|
private float opacity = 1f;
|
||||||
|
private int selectedX = 0;
|
||||||
|
private int selectedY = 0;
|
||||||
|
|
||||||
|
private boolean draggingOpacity = false;
|
||||||
|
|
||||||
|
// Dimensions
|
||||||
|
private static final int PICKER_WIDTH = 100;
|
||||||
|
private static final int PICKER_HEIGHT = 100;
|
||||||
|
private static final int SLIDER_WIDTH = 100;
|
||||||
|
private static final int SLIDER_HEIGHT = 10;
|
||||||
|
private static final int HUE_SLIDER_HEIGHT = 10;
|
||||||
|
|
||||||
|
public HexInput(Property<Integer> prop) {
|
||||||
|
this.prop = prop;
|
||||||
this.width = 58;
|
this.width = 58;
|
||||||
this.height = 20;
|
this.height = 20;
|
||||||
this.prop = prop;
|
syncFromColor();
|
||||||
this.scale = 0.8f;
|
|
||||||
this.screen = screen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void click(int mouseX, int mouseY) {
|
public void click(int mouseX, int mouseY) {
|
||||||
SaturnClient.client.setScreen(new ColorDialog(prop, screen));
|
open = !open;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||||
|
if (open) {
|
||||||
|
handlePickerClick(mouseX - width - 8, mouseY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
|
||||||
|
if (open) {
|
||||||
|
handlePickerDrag(mouseX - width - 8, mouseY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||||
|
draggingOpacity = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, 17, prop.value);
|
// Draw the main color rectangle
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, width, height, 6, prop.value);
|
||||||
|
|
||||||
|
if (!open)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Draw the picker relative to (width + 8, 0)
|
||||||
|
int pickerX = width + 8;
|
||||||
|
int pickerY = 0;
|
||||||
|
|
||||||
|
renderColorSquare(renderScope, pickerX, pickerY);
|
||||||
|
renderOpacitySlider(renderScope, pickerX, pickerY - SLIDER_HEIGHT - 10);
|
||||||
|
renderHueSlider(renderScope, pickerX, pickerY + PICKER_HEIGHT + 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderColorSquare(RenderScope renderScope, int xStart, int yStart) {
|
||||||
|
for (int x = 0; x < PICKER_WIDTH; x++) {
|
||||||
|
for (int y = 0; y < PICKER_HEIGHT; y++) {
|
||||||
|
float saturation = x / (float) PICKER_WIDTH;
|
||||||
|
float value = 1f - y / (float) PICKER_HEIGHT;
|
||||||
|
int color = Color.HSBtoRGB(hue, saturation, value);
|
||||||
|
int alpha = (int) (opacity * 255) & 0xFF;
|
||||||
|
color = (alpha << 24) | (color & 0xFFFFFF);
|
||||||
|
renderScope.fill(xStart + x, yStart + y, xStart + x + 1, yStart + y + 1, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw selection square
|
||||||
|
int selX = xStart + selectedX - 4;
|
||||||
|
int selY = yStart + selectedY - 4;
|
||||||
|
renderScope.fill(selX, selY, selX + 8, selY + 8, 0xFF000000 | prop.value);
|
||||||
|
renderScope.drawBorder(selX, selY, 8, 8, 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderOpacitySlider(RenderScope renderScope, int xStart, int yStart) {
|
||||||
|
for (int x = 0; x < SLIDER_WIDTH; x++) {
|
||||||
|
float localOpacity = x / (float) SLIDER_WIDTH;
|
||||||
|
int alpha = (int) (localOpacity * 255) & 0xFF;
|
||||||
|
int color = (alpha << 24) | (prop.value & 0xFFFFFF);
|
||||||
|
renderScope.fill(xStart + x, yStart, xStart + x + 1, yStart + SLIDER_HEIGHT, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
int knobX = xStart + (int) (opacity * SLIDER_WIDTH);
|
||||||
|
renderScope.fill(knobX - 1, yStart - 2, knobX + 1, yStart + SLIDER_HEIGHT + 2, 0xFF000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderHueSlider(RenderScope renderScope, int xStart, int yStart) {
|
||||||
|
for (int x = 0; x < SLIDER_WIDTH; x++) {
|
||||||
|
float localHue = x / (float) SLIDER_WIDTH;
|
||||||
|
int color = Color.HSBtoRGB(localHue, 1f, 1f);
|
||||||
|
renderScope.fill(xStart + x, yStart, xStart + x + 1, yStart + HUE_SLIDER_HEIGHT, 0xFF000000 | color);
|
||||||
|
}
|
||||||
|
|
||||||
|
int knobX = xStart + (int) (hue * SLIDER_WIDTH);
|
||||||
|
renderScope.fill(knobX - 1, yStart - 2, knobX + 1, yStart + HUE_SLIDER_HEIGHT + 2, 0xFF000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handlePickerClick(double mouseX, double mouseY) {
|
||||||
|
// Color square
|
||||||
|
if (mouseX >= 0 && mouseX < PICKER_WIDTH && mouseY >= 0 && mouseY < PICKER_HEIGHT) {
|
||||||
|
selectedX = (int) mouseX;
|
||||||
|
selectedY = (int) mouseY;
|
||||||
|
updateColorFromSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opacity slider
|
||||||
|
int opY = -SLIDER_HEIGHT - 10;
|
||||||
|
if (mouseX >= 0 && mouseX < SLIDER_WIDTH && mouseY >= opY && mouseY <= opY + SLIDER_HEIGHT) {
|
||||||
|
updateOpacity(mouseX);
|
||||||
|
draggingOpacity = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hue slider
|
||||||
|
int hueY = PICKER_HEIGHT + 10;
|
||||||
|
if (mouseX >= 0 && mouseX < SLIDER_WIDTH && mouseY >= hueY && mouseY <= hueY + HUE_SLIDER_HEIGHT) {
|
||||||
|
updateHue(mouseX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handlePickerDrag(double mouseX, double mouseY) {
|
||||||
|
// Opacity
|
||||||
|
if (draggingOpacity)
|
||||||
|
updateOpacity(mouseX);
|
||||||
|
|
||||||
|
// Color square
|
||||||
|
if (mouseX >= 0 && mouseX < PICKER_WIDTH && mouseY >= 0 && mouseY < PICKER_HEIGHT) {
|
||||||
|
selectedX = (int) mouseX;
|
||||||
|
selectedY = (int) mouseY;
|
||||||
|
updateColorFromSelection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateColorFromSelection() {
|
||||||
|
float saturation = selectedX / (float) PICKER_WIDTH;
|
||||||
|
float value = 1f - selectedY / (float) PICKER_HEIGHT;
|
||||||
|
int color = Color.HSBtoRGB(hue, saturation, value);
|
||||||
|
int alpha = (int) (opacity * 255) & 0xFF;
|
||||||
|
prop.value = (alpha << 24) | (color & 0xFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateHue(double mouseX) {
|
||||||
|
hue = (float) Math.max(0, Math.min(1, mouseX / SLIDER_WIDTH));
|
||||||
|
updateColorFromSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateOpacity(double mouseX) {
|
||||||
|
opacity = (float) Math.max(0, Math.min(1, mouseX / SLIDER_WIDTH));
|
||||||
|
updateColorFromSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void syncFromColor() {
|
||||||
|
int rgb = prop.value & 0xFFFFFF;
|
||||||
|
float[] hsb = Color.RGBtoHSB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF, null);
|
||||||
|
hue = hsb[0];
|
||||||
|
selectedX = (int) (hsb[1] * PICKER_WIDTH);
|
||||||
|
selectedY = (int) ((1f - hsb[2]) * PICKER_HEIGHT);
|
||||||
|
int alpha = (prop.value >> 24) & 0xFF;
|
||||||
|
if (alpha == 0)
|
||||||
|
alpha = 255;
|
||||||
|
opacity = alpha / 255f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,21 +2,20 @@ package org.saturnclient.ui2.components.inputs;
|
|||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
import org.saturnclient.ui2.resources.Fonts;
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
|
||||||
public abstract class Input extends Element {
|
public abstract class Input extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("Input");
|
|
||||||
private static Property<Integer> font = theme.property("font", Property.font(1));
|
|
||||||
|
|
||||||
String text = "";
|
String text = "";
|
||||||
public int cursorPosition = 0;
|
public int cursorPosition = 0;
|
||||||
|
|
||||||
public abstract void checkReset();
|
public abstract void checkReset();
|
||||||
|
|
||||||
public abstract void backspace();
|
public abstract void backspace();
|
||||||
|
|
||||||
public boolean validateBackspace() {
|
public boolean validateBackspace() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -71,11 +70,12 @@ public abstract class Input extends Element {
|
|||||||
int scrollOffset = getScrollOffset();
|
int scrollOffset = getScrollOffset();
|
||||||
String visibleText = getVisibleText(scrollOffset);
|
String visibleText = getVisibleText(scrollOffset);
|
||||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||||
renderScope.drawText(0.6f, visibleText, 4, 4, font.value, textColor);
|
renderScope.drawText(0.6f, visibleText, 4, 4, Theme.FONT.value, textColor);
|
||||||
|
|
||||||
if (focused) {
|
if (focused) {
|
||||||
int cursorX = 4 +
|
int cursorX = 4 +
|
||||||
(int) (Fonts.getWidth(visibleText.substring(0, cursorPosition - scrollOffset), font.value) * 0.6f);
|
(int) (Fonts.getWidth(visibleText.substring(0, cursorPosition - scrollOffset), Theme.FONT.value)
|
||||||
|
* 0.6f);
|
||||||
|
|
||||||
renderScope.drawRect(cursorX, 2, 1, height - 4, 0xFFFFFFFF);
|
renderScope.drawRect(cursorX, 2, 1, height - 4, 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
@@ -90,7 +90,7 @@ public abstract class Input extends Element {
|
|||||||
int maxWidth = width - 4; // Available width for text
|
int maxWidth = width - 4; // Available width for text
|
||||||
while (offset < cursorPosition) { // Ensure cursor remains visible
|
while (offset < cursorPosition) { // Ensure cursor remains visible
|
||||||
String visibleText = text.substring(offset, cursorPosition);
|
String visibleText = text.substring(offset, cursorPosition);
|
||||||
if (Fonts.getWidth(visibleText, font.value) > maxWidth) {
|
if (Fonts.getWidth(visibleText, Theme.FONT.value) > maxWidth) {
|
||||||
offset++;
|
offset++;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@@ -104,7 +104,7 @@ public abstract class Input extends Element {
|
|||||||
|
|
||||||
// Ensure text does not overflow past the available width
|
// Ensure text does not overflow past the available width
|
||||||
for (int i = 1; i <= visibleText.length(); i++) {
|
for (int i = 1; i <= visibleText.length(); i++) {
|
||||||
if (Fonts.getWidth(visibleText.substring(0, i), font.value) > width - 4) {
|
if (Fonts.getWidth(visibleText.substring(0, i), Theme.FONT.value) > width - 4) {
|
||||||
return visibleText.substring(0, i - 1); // Trim overflow
|
return visibleText.substring(0, i - 1); // Trim overflow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,13 @@ package org.saturnclient.ui2.components.inputs;
|
|||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
import org.saturnclient.ui2.resources.Fonts;
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
|
||||||
public class KeybindingSelector extends Element {
|
public class KeybindingSelector extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("Input");
|
|
||||||
private static Property<Integer> font = theme.property("font", Property.font(1));
|
|
||||||
Property<Integer> prop;
|
Property<Integer> prop;
|
||||||
|
|
||||||
public KeybindingSelector(Property<Integer> prop) {
|
public KeybindingSelector(Property<Integer> prop) {
|
||||||
@@ -23,9 +21,12 @@ public class KeybindingSelector extends Element {
|
|||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, 10, 0xFF000000);
|
renderScope.drawRoundedRectangle(0, 0, width, height, 10, 0xFF000000);
|
||||||
renderScope.drawText(0.6f, prop.value == -1 ? "<NONE>" :
|
String name = GLFW.glfwGetKeyName(prop.value, GLFW.glfwGetKeyScancode(prop.value));
|
||||||
GLFW.glfwGetKeyName(prop.value, GLFW.glfwGetKeyScancode(prop.value)).toUpperCase(),
|
|
||||||
4, 4, font.value, textColor);
|
renderScope.drawText(0.6f,
|
||||||
|
prop.value == -1 ? "<NONE>"
|
||||||
|
: name != null ? name.toUpperCase() : "<Invalid-Key>",
|
||||||
|
4, 4, Theme.FONT.value, textColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.saturnclient.ui2.components.inputs;
|
package org.saturnclient.ui2.components.inputs;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
@@ -10,11 +10,6 @@ import org.saturnclient.ui2.resources.Fonts;
|
|||||||
import net.minecraft.client.render.RenderLayer;
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
|
||||||
public class Select extends Element {
|
public class Select extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("Toggle");
|
|
||||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xAAAAAA));
|
|
||||||
private static Property<Integer> arrowColor = theme.property("arrow-color", Property.color(0xff8B5CF6));
|
|
||||||
private static Property<Integer> font = theme.property("font", Property.font(1));
|
|
||||||
|
|
||||||
private Property<Integer> prop;
|
private Property<Integer> prop;
|
||||||
|
|
||||||
public Select(Property<Integer> prop) {
|
public Select(Property<Integer> prop) {
|
||||||
@@ -27,15 +22,14 @@ public class Select extends Element {
|
|||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
|
|
||||||
renderScope.drawText(0.8f, "<", 0, 0, font.value, arrowColor.value);
|
renderScope.drawText(0.8f, "<", 0, 0, Theme.FONT.value, Theme.FOREGROUND.value);
|
||||||
|
|
||||||
String text = prop.getSelection();
|
String text = prop.getSelection();
|
||||||
|
|
||||||
renderScope.drawText(0.6f, text, (int) (width - ((float) Fonts.getWidth(text, font.value) * 0.6f)) / 2, 1, font.value, fgColor.value);
|
renderScope.drawText(0.6f, text, (int) (width - ((float) Fonts.getWidth(text, Theme.FONT.value) * 0.6f)) / 2, 1,
|
||||||
|
Theme.FONT.value, Theme.FOREGROUND.value);
|
||||||
|
|
||||||
renderScope.drawText(0.8f, ">", width - 10, 0, font.value, arrowColor.value);
|
renderScope.drawText(0.8f, ">", width - 10, 0, Theme.FONT.value, Theme.FOREGROUND.value);
|
||||||
|
|
||||||
theme.setState(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,22 +1,12 @@
|
|||||||
package org.saturnclient.ui2.components.inputs;
|
package org.saturnclient.ui2.components.inputs;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
|
||||||
public class Toggle extends Element {
|
public class Toggle extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("Toggle", "hovering", "enabled");
|
|
||||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0xFF808080));
|
|
||||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFF909090));
|
|
||||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(30));
|
|
||||||
|
|
||||||
static {
|
|
||||||
theme.propertyStateDefault("enabled", "bg-color", 0xaf8B5CF6);
|
|
||||||
theme.propertyStateDefault("enabled", "fg-color", 0xff8B5CF6);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Property<Boolean> prop;
|
private Property<Boolean> prop;
|
||||||
|
|
||||||
public Toggle(Property<Boolean> prop) {
|
public Toggle(Property<Boolean> prop) {
|
||||||
@@ -27,19 +17,10 @@ public class Toggle extends Element {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
theme.setState(null);
|
renderScope.drawRoundedRectangle(0, 0, width, height, height,
|
||||||
|
Theme.withAlpha(0.5f, prop.value ? Theme.ACCENT.value : Theme.PRIMARY.value));
|
||||||
if (prop.value) {
|
renderScope.drawRoundedRectangle(prop.value ? 30 : 0, 0, 30, 30, 30,
|
||||||
theme.setState("enabled");
|
prop.value ? Theme.ACCENT.value : Theme.PRIMARY.value);
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.saturnclient.saturnclient.config.SaturnClientConfig;
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
import org.saturnclient.ui2.ElementContext;
|
||||||
|
import org.saturnclient.ui2.RenderScope;
|
||||||
|
import org.saturnclient.ui2.components.ElementRenderer;
|
||||||
|
|
||||||
|
public class AnimationStagger extends Element {
|
||||||
|
protected List<Element> children = new ArrayList<>();
|
||||||
|
public int delay;
|
||||||
|
|
||||||
|
public AnimationStagger(int delay) {
|
||||||
|
this.delay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Element element) {
|
||||||
|
if (!SaturnClientConfig.stagger.value) {
|
||||||
|
element.animation = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.animation != null) {
|
||||||
|
element.animation.delay = delay * children.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
ElementRenderer.draw(children, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
|
ElementRenderer.render(children, ctx.elapsed, renderScope,
|
||||||
|
ctx.mouseX,
|
||||||
|
ctx.mouseY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||||
|
ElementRenderer.mouseClicked(children, mouseX, mouseY, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||||
|
ElementRenderer.keyPressed(children, keyCode, scanCode, modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
|
||||||
|
ElementRenderer.mouseDragged(children, mouseX, mouseY, button, deltaX, deltaY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||||
|
ElementRenderer.mouseReleased(children, mouseX, mouseY, button);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,43 +1,29 @@
|
|||||||
package org.saturnclient.ui2.elements;
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
import org.saturnclient.ui2.resources.Fonts;
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
|
||||||
public class Button extends Element {
|
public class Button extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("Button", "hovering");
|
|
||||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0xFF000000));
|
|
||||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
|
||||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
|
||||||
private static Property<Integer> font = theme.property("font", Property.font(1));
|
|
||||||
|
|
||||||
static {
|
|
||||||
theme.propertyStateDefault("hovering", "fg-color", 0xFF845eee);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String text;
|
private String text;
|
||||||
private Runnable onClick;
|
private Runnable onClick;
|
||||||
|
|
||||||
public Button(String text, Runnable onClick) {
|
public Button(String text, Runnable onClick) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.onClick = onClick;
|
this.onClick = onClick;
|
||||||
this.dimensions(Fonts.getWidth(text, font.value) + 50, 38);
|
this.dimensions(Fonts.getWidth(text, Theme.FONT.value) + 50, 38);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
if (ctx.isHovering()) {
|
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value,
|
||||||
theme.setState("hovering");
|
ctx.isHovering() ? Theme.ACCENT.value : Theme.PRIMARY.value);
|
||||||
} else {
|
|
||||||
theme.setState(null);
|
|
||||||
}
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
|
||||||
|
|
||||||
// renderScope.drawText(text, (width - Fonts.getWidth(text, font)) / 2, (height - Fonts.getHeight()) / 2, bold.value, fgColor.value);
|
renderScope.drawText(text, Fonts.centerX(width, text, Theme.FONT.value), Fonts.centerY(height),
|
||||||
renderScope.drawText(text, Fonts.centerX(width, text, font.value), Fonts.centerY(height), font.value, fgColor.value);
|
Theme.FONT.value,
|
||||||
|
ctx.isHovering() ? Theme.ACCENT_FG.value : Theme.PRIMARY_FG.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.saturnclient.ui2.elements;
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
@@ -10,9 +9,6 @@ import net.minecraft.client.render.RenderLayer;
|
|||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
public class ClickableTexture extends Element {
|
public class ClickableTexture extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("ClickableTexture", "hovering");
|
|
||||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
|
||||||
|
|
||||||
Identifier sprite;
|
Identifier sprite;
|
||||||
private Runnable onClick;
|
private Runnable onClick;
|
||||||
|
|
||||||
@@ -23,14 +19,9 @@ public class ClickableTexture extends Element {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
if (ctx.isHovering()) {
|
|
||||||
theme.setState("hovering");
|
|
||||||
} else {
|
|
||||||
theme.setState(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
renderScope.drawTexture(sprite, 0, 0, 0, 0, width, height, fgColor.value);
|
renderScope.drawTexture(sprite, 0, 0, 0, 0, width, height,
|
||||||
|
ctx.isHovering() ? Theme.ACCENT.value : Theme.PRIMARY.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.saturnclient.ui2.elements;
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
@@ -10,11 +10,9 @@ import org.saturnclient.ui2.resources.Fonts;
|
|||||||
import org.saturnclient.ui2.resources.Textures;
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
|
|
||||||
public class Notification extends Element {
|
public class Notification extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("Notification");
|
private static Property<Integer> error = Property.color(0xFFbf212f);
|
||||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0xFF000000));
|
private static Property<Integer> info = Property.color(0xFF264b96);
|
||||||
private static Property<Integer> error = theme.property("error", Property.color(0xFFbf212f));
|
private static Property<Integer> success = Property.color(0xFF27b376);
|
||||||
private static Property<Integer> info = theme.property("info", Property.color(0xFF264b96));
|
|
||||||
private static Property<Integer> success = theme.property("success", Property.color(0xFF27b376));
|
|
||||||
|
|
||||||
public static enum NotificationKind {
|
public static enum NotificationKind {
|
||||||
Error,
|
Error,
|
||||||
@@ -40,7 +38,7 @@ public class Notification extends Element {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, 10, bgColor.value);
|
renderScope.drawRoundedRectangle(0, 0, width, height, 10, Theme.PRIMARY.value);
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case Error:
|
case Error:
|
||||||
renderScope.drawTexture(Textures.CIRCLE_X, 9, 9, 0, 0, 15, 15, error.value);
|
renderScope.drawTexture(Textures.CIRCLE_X, 9, 9, 0, 0, 15, 15, error.value);
|
||||||
|
|||||||
@@ -4,21 +4,16 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
import org.saturnclient.ui2.components.ElementRenderer;
|
import org.saturnclient.ui2.components.ElementRenderer;
|
||||||
|
|
||||||
public class Scroll extends Element {
|
public class Scroll extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("Scroll");
|
private static Property<Integer> scrollBarRadius = Property.integer(10);
|
||||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0x90000000));
|
private static Property<Integer> scrollBarWidth = Property.integer(5);
|
||||||
private static Property<Integer> scrollBarColor = theme.property("scrollbar-color", Property.color(-7643914));
|
private static Property<Integer> scrollBarPadding = Property.integer(5);
|
||||||
|
|
||||||
private static Property<Integer> scrollBarRadius = theme.property("scrollbar-radius", Property.integer(10));
|
|
||||||
private static Property<Integer> scrollBarWidth = theme.property("scrollbar-width", Property.integer(5));
|
|
||||||
private static Property<Integer> scrollBarPadding = theme.property("scrollbar-padding", Property.integer(5));
|
|
||||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
|
||||||
|
|
||||||
int padding = 0;
|
int padding = 0;
|
||||||
|
|
||||||
@@ -30,18 +25,37 @@ public class Scroll extends Element {
|
|||||||
this.padding = padding;
|
this.padding = padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void draw(Element element) {
|
||||||
|
ElementRenderer.draw(children, element);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
calculateMaxScroll();
|
||||||
|
|
||||||
|
renderScope.drawRoundedRectangle(0, 0, width, height,
|
||||||
|
Theme.BG_RADIUS.value, Theme.BACKGROUND.value);
|
||||||
|
|
||||||
renderScope.enableScissor(padding, padding, width - padding, height - padding);
|
renderScope.enableScissor(padding, padding, width - padding, height - padding);
|
||||||
renderScope.matrices.push();
|
renderScope.matrices.push();
|
||||||
renderScope.matrices.translate(padding, (-scroll) + padding, 0);
|
renderScope.matrices.translate(padding, -scroll + padding, 0);
|
||||||
ElementRenderer.render(children, renderScope, ctx.mouseX - padding, ctx.mouseY - padding + scroll);
|
|
||||||
|
ElementRenderer.render(children, ctx.elapsed, renderScope,
|
||||||
|
ctx.mouseX - padding,
|
||||||
|
ctx.mouseY - padding + scroll);
|
||||||
|
|
||||||
renderScope.matrices.pop();
|
renderScope.matrices.pop();
|
||||||
renderScope.disableScissor();
|
renderScope.disableScissor();
|
||||||
|
|
||||||
renderScope.drawRoundedRectangle(width - scrollBarWidth.value - scrollBarPadding.value, calculateScrollBarY(), scrollBarWidth.value, calculateScrollBarHeight(), scrollBarRadius.value, scrollBarColor.value);
|
if (maxScroll > 0) {
|
||||||
|
renderScope.drawRoundedRectangle(
|
||||||
|
width - scrollBarWidth.value - scrollBarPadding.value,
|
||||||
|
calculateScrollBarY(),
|
||||||
|
scrollBarWidth.value,
|
||||||
|
calculateScrollBarHeight(),
|
||||||
|
scrollBarRadius.value,
|
||||||
|
Theme.SCROLL.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -54,36 +68,63 @@ public class Scroll extends Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(int mouseX, int mouseY) {
|
|
||||||
ElementRenderer.mouseClicked(children, mouseX - padding, mouseY - padding + scroll, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(Element element) {
|
|
||||||
children.add(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Element dimensions(int width, int height) {
|
public Element dimensions(int width, int height) {
|
||||||
|
maxScroll = 0;
|
||||||
|
|
||||||
for (Element element : children) {
|
for (Element element : children) {
|
||||||
maxScroll = Math.max(maxScroll, element.y + element.height - height);
|
maxScroll = Math.max(maxScroll, element.y + element.height - height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maxScroll = Math.max(0, maxScroll); // never negative
|
||||||
return super.dimensions(width, height);
|
return super.dimensions(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
int calculateScrollBarHeight() {
|
int calculateScrollBarHeight() {
|
||||||
if (maxScroll <= 0) return height - (scrollBarPadding.value * 2); // No scrolling needed
|
if (maxScroll <= 0)
|
||||||
return Math.max(20, (height * height) / (height + maxScroll)) - (scrollBarPadding.value * 2); // At least 20px tall
|
return height - (scrollBarPadding.value * 2);
|
||||||
|
return Math.max(20, (height * height) / (height + maxScroll + 10)) - (scrollBarPadding.value * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
int calculateScrollBarY() {
|
int calculateScrollBarY() {
|
||||||
int scrollBarHeight = calculateScrollBarHeight();
|
int scrollBarHeight = calculateScrollBarHeight();
|
||||||
if (maxScroll <= 0) return scrollBarPadding.value;
|
if (maxScroll <= 0)
|
||||||
|
return scrollBarPadding.value;
|
||||||
return (scroll * (height - scrollBarHeight)) / maxScroll + scrollBarPadding.value;
|
return (scroll * (height - scrollBarHeight)) / maxScroll + scrollBarPadding.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void calculateMaxScroll() {
|
||||||
|
maxScroll = 0;
|
||||||
|
|
||||||
|
for (Element element : children) {
|
||||||
|
int bottom = element.y + element.height;
|
||||||
|
maxScroll = Math.max(maxScroll, bottom - height + padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxScroll > 0) {
|
||||||
|
maxScroll = maxScroll + 10;
|
||||||
|
} else {
|
||||||
|
maxScroll = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||||
ElementRenderer.keyPressed(children, keyCode, scanCode, modifiers);
|
ElementRenderer.keyPressed(children, keyCode, scanCode, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(double mouseX, double mouseY, int button) {
|
||||||
|
ElementRenderer.mouseClicked(children, mouseX - padding, mouseY - padding + scroll, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
|
||||||
|
ElementRenderer.mouseDragged(children, mouseX - padding, mouseY - padding + scroll, button, deltaX, deltaY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(double mouseX, double mouseY, int button) {
|
||||||
|
ElementRenderer.mouseReleased(children, mouseX - padding, mouseY - padding + scroll, button);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.saturnclient.ui2.elements;
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
@@ -10,16 +9,6 @@ import org.saturnclient.ui2.Utils;
|
|||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
public class TabMenu extends Element {
|
public class TabMenu extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("TabMenu", "hovering", "selected");
|
|
||||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0x90000000));
|
|
||||||
private static Property<Integer> iconFg = theme.property("icon-fg", Property.color(0xFFFFFFFF));
|
|
||||||
private static Property<Integer> iconBg = theme.property("icon-bg", Property.color(0x00000000));
|
|
||||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
|
||||||
|
|
||||||
static {
|
|
||||||
theme.propertyStateDefault("hovering", "icon-bg", -7643914);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class TabMenuComponent {
|
public static class TabMenuComponent {
|
||||||
Runnable onClick;
|
Runnable onClick;
|
||||||
Identifier sprite;
|
Identifier sprite;
|
||||||
@@ -42,19 +31,21 @@ public class TabMenu extends Element {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value, Theme.PRIMARY.value);
|
||||||
|
|
||||||
int col = 0;
|
int col = 0;
|
||||||
for (TabMenuComponent component : components) {
|
for (TabMenuComponent component : components) {
|
||||||
int x = 25 * col + 5;
|
int x = 25 * col + 5;
|
||||||
if (ctx.isHovering(x, 5, 20, 20) || selectedScreen == col) {
|
|
||||||
theme.setState("hovering");
|
boolean hovering = ctx.isHovering(x, 5, 20, 20) || selectedScreen == col;
|
||||||
|
|
||||||
|
if (hovering) {
|
||||||
|
renderScope.drawRoundedRectangle(x, 5, 20, 20, Theme.WIDGET_RADIUS.value, Theme.ACCENT.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderScope.drawRoundedRectangle(x, 5, 20, 20, cornerRadius.value, iconBg.value);
|
renderScope.drawTexture(component.sprite, x + 5, 10, 0, 0, 10, 10,
|
||||||
renderScope.drawTexture(component.sprite, x + 5, 10, 0, 0, 10, 10, iconFg.value);
|
hovering ? Theme.ACCENT_FG.value : Theme.PRIMARY_FG.value);
|
||||||
|
|
||||||
theme.setState(null);
|
|
||||||
col++;
|
col++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,22 @@
|
|||||||
package org.saturnclient.ui2.elements;
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
import org.saturnclient.ui2.resources.Fonts;
|
import org.saturnclient.ui2.resources.Fonts;
|
||||||
|
|
||||||
public class Text extends Element {
|
public class Text extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("Text");
|
|
||||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
|
||||||
public static Property<Integer> font = theme.property("font", Property.font(1));
|
|
||||||
|
|
||||||
private String text;
|
private String text;
|
||||||
|
|
||||||
public Text(String text) {
|
public Text(String text) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
width = Fonts.getWidth(text, font.value);
|
width = Fonts.getWidth(text, Theme.FONT.value);
|
||||||
height = Fonts.getHeight();
|
height = Fonts.getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
renderScope.drawText(this.text, 0, 0, font.value, fgColor.value);
|
renderScope.drawText(this.text, 0, 0, Theme.FONT.value, Theme.FOREGROUND.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.saturnclient.ui2.elements;
|
package org.saturnclient.ui2.elements;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
|
||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
import org.saturnclient.ui2.ElementContext;
|
import org.saturnclient.ui2.ElementContext;
|
||||||
import org.saturnclient.ui2.RenderScope;
|
import org.saturnclient.ui2.RenderScope;
|
||||||
@@ -10,19 +9,9 @@ import net.minecraft.client.render.RenderLayer;
|
|||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
public class TextureButton extends Element {
|
public class TextureButton extends Element {
|
||||||
private static ThemeManager theme = new ThemeManager("TextureButton", "hovering");
|
|
||||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0xFF000000));
|
|
||||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
|
||||||
private static Property<Integer> padding = theme.property("padding", Property.integer(14));
|
|
||||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", Property.integer(10));
|
|
||||||
|
|
||||||
|
|
||||||
static {
|
|
||||||
theme.propertyStateDefault("hovering", "fg-color", 0xFF845eee);
|
|
||||||
}
|
|
||||||
|
|
||||||
Identifier sprite;
|
Identifier sprite;
|
||||||
private Runnable onClick;
|
private Runnable onClick;
|
||||||
|
static int padding = 14;
|
||||||
|
|
||||||
public TextureButton(Identifier sprite, Runnable onClick) {
|
public TextureButton(Identifier sprite, Runnable onClick) {
|
||||||
this.sprite = sprite;
|
this.sprite = sprite;
|
||||||
@@ -31,20 +20,16 @@ public class TextureButton extends Element {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||||
if (ctx.isHovering()) {
|
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value,
|
||||||
theme.setState("hovering");
|
ctx.isHovering() ? Theme.ACCENT.value : Theme.PRIMARY.value);
|
||||||
} else {
|
|
||||||
theme.setState(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
|
||||||
|
|
||||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||||
|
|
||||||
int texWidth = width - padding.value;
|
int texWidth = width - padding;
|
||||||
int texHeight = height - padding.value;
|
int texHeight = height - padding;
|
||||||
|
|
||||||
renderScope.drawTexture(sprite, padding.value / 2, padding.value / 2, 0, 0, texWidth, texHeight, fgColor.value);
|
renderScope.drawTexture(sprite, padding / 2, padding / 2, 0, 0, texWidth, texHeight,
|
||||||
|
ctx.isHovering() ? Theme.ACCENT_FG.value : Theme.PRIMARY_FG.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||||
import org.saturnclient.saturnclient.config.Property;
|
import org.saturnclient.saturnclient.config.Property;
|
||||||
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.ui2.SaturnScreen;
|
import org.saturnclient.ui2.SaturnScreen;
|
||||||
import org.saturnclient.ui2.components.Sidebar;
|
import org.saturnclient.ui2.components.Sidebar;
|
||||||
import org.saturnclient.ui2.components.inputs.FloatInput;
|
import org.saturnclient.ui2.components.inputs.FloatInput;
|
||||||
@@ -60,13 +61,12 @@ public class ConfigEditor extends SaturnScreen {
|
|||||||
if (prop.getType() == Property.PropertyType.NAMESPACE) {
|
if (prop.getType() == Property.PropertyType.NAMESPACE) {
|
||||||
configScroll.draw(
|
configScroll.draw(
|
||||||
new Text(
|
new Text(
|
||||||
propName
|
propName).position(Fonts.centerX(520, propName, Theme.FONT.value), modY + 1)
|
||||||
).position(Fonts.centerX(520, propName, Text.font.value), modY + 1).scale(0.7f));
|
.scale(0.7f));
|
||||||
} else {
|
} else {
|
||||||
configScroll.draw(
|
configScroll.draw(
|
||||||
new Text(
|
new Text(
|
||||||
propName
|
propName).position(modX, modY + 1).scale(0.7f));
|
||||||
).position(modX, modY + 1).scale(0.7f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (prop.getType()) {
|
switch (prop.getType()) {
|
||||||
@@ -78,7 +78,7 @@ public class ConfigEditor extends SaturnScreen {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case HEX:
|
case HEX:
|
||||||
configScroll.draw(new HexInput((Property<Integer>) prop, this).position(w / 2, modY));
|
configScroll.draw(new HexInput((Property<Integer>) prop).position(w / 2, modY));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package org.saturnclient.ui2.screens;
|
package org.saturnclient.ui2.screens;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
|
||||||
import org.saturnclient.saturnclient.client.ServiceClient;
|
import org.saturnclient.saturnclient.client.ServiceClient;
|
||||||
|
import org.saturnclient.saturnclient.config.SaturnClientConfig;
|
||||||
import org.saturnclient.saturnclient.cosmetics.Emotes;
|
import org.saturnclient.saturnclient.cosmetics.Emotes;
|
||||||
import org.saturnclient.ui2.SaturnScreen;
|
import org.saturnclient.ui2.SaturnScreen;
|
||||||
import org.saturnclient.ui2.Utils;
|
import org.saturnclient.ui2.Utils;
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ package org.saturnclient.ui2.screens;
|
|||||||
import org.saturnclient.modules.ModManager;
|
import org.saturnclient.modules.ModManager;
|
||||||
import org.saturnclient.modules.Module;
|
import org.saturnclient.modules.Module;
|
||||||
import org.saturnclient.ui2.SaturnScreen;
|
import org.saturnclient.ui2.SaturnScreen;
|
||||||
|
import org.saturnclient.ui2.anim.SlideFade;
|
||||||
import org.saturnclient.ui2.components.SaturnModule;
|
import org.saturnclient.ui2.components.SaturnModule;
|
||||||
import org.saturnclient.ui2.components.Sidebar;
|
import org.saturnclient.ui2.components.Sidebar;
|
||||||
|
import org.saturnclient.ui2.elements.AnimationStagger;
|
||||||
import org.saturnclient.ui2.elements.ImageTexture;
|
import org.saturnclient.ui2.elements.ImageTexture;
|
||||||
import org.saturnclient.ui2.elements.Scroll;
|
import org.saturnclient.ui2.elements.Scroll;
|
||||||
import org.saturnclient.ui2.resources.Textures;
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
@@ -24,8 +26,11 @@ public class ModMenu extends SaturnScreen {
|
|||||||
int row = 0;
|
int row = 0;
|
||||||
int col = 0;
|
int col = 0;
|
||||||
|
|
||||||
|
AnimationStagger moduleStagger = new AnimationStagger(80);
|
||||||
|
|
||||||
for (Module mod : ModManager.ALL_MODS) {
|
for (Module mod : ModManager.ALL_MODS) {
|
||||||
scroll.draw(new SaturnModule(mod).position((160 + g) * col, (50 + g) * row));
|
moduleStagger.draw(
|
||||||
|
new SaturnModule(mod).position((160 + g) * col, (50 + g) * row).animation(new SlideFade(600, -12)));
|
||||||
|
|
||||||
if (col == 2) {
|
if (col == 2) {
|
||||||
col = 0;
|
col = 0;
|
||||||
@@ -35,6 +40,8 @@ public class ModMenu extends SaturnScreen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scroll.draw(moduleStagger);
|
||||||
|
|
||||||
int scrollWidth = 480 + 10 + (g * 2) + (p * 2);
|
int scrollWidth = 480 + 10 + (g * 2) + (p * 2);
|
||||||
|
|
||||||
draw(scroll.dimensions(scrollWidth, 350).center(width, height));
|
draw(scroll.dimensions(scrollWidth, 350).center(width, height));
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package org.saturnclient.ui2.screens;
|
package org.saturnclient.ui2.screens;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
import org.saturnclient.saturnclient.config.SaturnClientConfig;
|
||||||
import org.saturnclient.saturnclient.menus.HudEditor;
|
import org.saturnclient.saturnclient.menus.HudEditor;
|
||||||
import org.saturnclient.ui2.resources.Textures;
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
import org.saturnclient.ui2.screens.cosmetics.CloakMenu;
|
import org.saturnclient.ui2.screens.cosmetics.CloakMenu;
|
||||||
import org.saturnclient.ui2.Element;
|
|
||||||
import org.saturnclient.ui2.SaturnScreen;
|
import org.saturnclient.ui2.SaturnScreen;
|
||||||
|
import org.saturnclient.ui2.elements.AnimationStagger;
|
||||||
import org.saturnclient.ui2.elements.Button;
|
import org.saturnclient.ui2.elements.Button;
|
||||||
import org.saturnclient.ui2.elements.ImageTexture;
|
import org.saturnclient.ui2.elements.ImageTexture;
|
||||||
import org.saturnclient.ui2.elements.TextureButton;
|
import org.saturnclient.ui2.elements.TextureButton;
|
||||||
@@ -20,21 +20,42 @@ public class ShiftMenu extends SaturnScreen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void ui() {
|
public void ui() {
|
||||||
draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(98, 10).centerOffset(width, height, 0, -36).animation(new Fade(700)));
|
// Logo animations (unchanged)
|
||||||
draw(new ImageTexture(SaturnClientConfig.getLogo()).dimensions(98, 98).centerOffset(width, height, 0, -80).animation(new SlideY(700, -20)));
|
draw(new ImageTexture(Textures.LOGO_TEXT)
|
||||||
|
.dimensions(98, 10)
|
||||||
|
.centerOffset(width, height, 0, -36)
|
||||||
|
.animation(new Fade(700)));
|
||||||
|
|
||||||
Element button = new Button("Settings", () -> {
|
draw(new ImageTexture(SaturnClientConfig.getLogo())
|
||||||
SaturnClient.client.setScreen(new ModMenu());
|
.dimensions(98, 98)
|
||||||
}).center(width, height);
|
.centerOffset(width, height, 0, -80)
|
||||||
|
.animation(new SlideY(700, -20)));
|
||||||
|
|
||||||
draw(button);
|
// Spacing and sizes
|
||||||
|
int btnWidth = 120;
|
||||||
|
int btnHeight = 40;
|
||||||
|
int spacing = 4;
|
||||||
|
|
||||||
draw(new TextureButton(Textures.COSMETICS, () -> {
|
// Create stagger
|
||||||
client.setScreen(new CloakMenu());
|
AnimationStagger stagger = new AnimationStagger(120);
|
||||||
}).dimensions(button.height, button.height).centerOffset(width, height, (button.width / 2) + (button.height / 2) + 4, 0));
|
|
||||||
|
|
||||||
draw(new TextureButton(Textures.HUD_ICON, () -> {
|
stagger.draw(new TextureButton(Textures.HUD_ICON, () -> {
|
||||||
client.setScreen(new HudEditor());
|
client.setScreen(new HudEditor());
|
||||||
}).dimensions(button.height, button.height).centerOffset(width, height, -((button.width / 2) + (button.height / 2) + 4), 0));
|
}).dimensions(btnHeight, btnHeight).position(0, 0)
|
||||||
|
.animation(new Fade(300)));
|
||||||
|
|
||||||
|
stagger.draw(new Button("Settings", () -> {
|
||||||
|
SaturnClient.client.setScreen(new ModMenu());
|
||||||
|
}).dimensions(btnWidth, btnHeight).position(btnHeight + spacing, 0)
|
||||||
|
.animation(new Fade(300)));
|
||||||
|
|
||||||
|
stagger.draw(new TextureButton(Textures.COSMETICS, () -> {
|
||||||
|
client.setScreen(new CloakMenu());
|
||||||
|
}).dimensions(btnHeight, btnHeight).position(btnWidth + btnHeight + (spacing * 2), 0)
|
||||||
|
.animation(new Fade(300)));
|
||||||
|
|
||||||
|
// Draw the stagger at the absolute center of the screen
|
||||||
|
draw(stagger.dimensions(btnWidth + (btnHeight * 2) + (spacing * 2), btnHeight).centerOffset(width, height, 0,
|
||||||
|
0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
package org.saturnclient.ui2.screens;
|
package org.saturnclient.ui2.screens;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
import org.saturnclient.saturnclient.config.SaturnClientConfig;
|
||||||
import org.saturnclient.saturnclient.menus.HudEditor;
|
import org.saturnclient.saturnclient.menus.HudEditor;
|
||||||
import org.saturnclient.ui2.resources.Textures;
|
import org.saturnclient.ui2.resources.Textures;
|
||||||
import org.saturnclient.ui2.screens.cosmetics.CloakMenu;
|
import org.saturnclient.ui2.screens.cosmetics.CloakMenu;
|
||||||
import org.saturnclient.ui2.SaturnScreen;
|
import org.saturnclient.ui2.SaturnScreen;
|
||||||
import org.saturnclient.ui2.anim.Fade;
|
import org.saturnclient.ui2.anim.Fade;
|
||||||
|
import org.saturnclient.ui2.anim.SlideFade;
|
||||||
import org.saturnclient.ui2.anim.SlideY;
|
import org.saturnclient.ui2.anim.SlideY;
|
||||||
|
import org.saturnclient.ui2.elements.AnimationStagger;
|
||||||
import org.saturnclient.ui2.elements.Button;
|
import org.saturnclient.ui2.elements.Button;
|
||||||
import org.saturnclient.ui2.elements.ImageTexture;
|
import org.saturnclient.ui2.elements.ImageTexture;
|
||||||
import org.saturnclient.ui2.elements.TextureButton;
|
import org.saturnclient.ui2.elements.TextureButton;
|
||||||
@@ -19,7 +21,7 @@ import net.minecraft.client.gui.screen.world.SelectWorldScreen;
|
|||||||
|
|
||||||
public class TitleMenu extends SaturnScreen {
|
public class TitleMenu extends SaturnScreen {
|
||||||
public TitleMenu() {
|
public TitleMenu() {
|
||||||
super("Tile Menu");
|
super("Title Menu");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -31,34 +33,42 @@ public class TitleMenu extends SaturnScreen {
|
|||||||
draw(new ImageTexture(SaturnClientConfig.getLogo()).dimensions(98, 98).centerOffset(width, height, 0, -82)
|
draw(new ImageTexture(SaturnClientConfig.getLogo()).dimensions(98, 98).centerOffset(width, height, 0, -82)
|
||||||
.animation(new SlideY(700, -20)));
|
.animation(new SlideY(700, -20)));
|
||||||
|
|
||||||
draw(new Button("SINGLEPLAYER", () -> {
|
AnimationStagger mainButtonStagger = new AnimationStagger(120);
|
||||||
|
|
||||||
|
mainButtonStagger.draw(new Button("SINGLEPLAYER", () -> {
|
||||||
client.setScreen(new SelectWorldScreen(new TitleMenu()));
|
client.setScreen(new SelectWorldScreen(new TitleMenu()));
|
||||||
}).scale(0.69f).dimensions(420, 52).centerOffset(width, height, 0, 0));
|
}).scale(0.69f).dimensions(420, 52).position(0, 0).animation(new SlideFade(1000, -10)));
|
||||||
|
|
||||||
draw(new Button("MULTIPLAYER", () -> {
|
mainButtonStagger.draw(new Button("MULTIPLAYER", () -> {
|
||||||
client.setScreen(new MultiplayerScreen(new TitleMenu()));
|
client.setScreen(new MultiplayerScreen(new TitleMenu()));
|
||||||
}).scale(0.69f).dimensions(420, 52).centerOffset(width, height, 0, 40));
|
}).scale(0.69f).dimensions(420, 52).position(0, 40).animation(new SlideFade(1000, -10)));
|
||||||
|
|
||||||
draw(new Button("OPTIONS", () -> {
|
mainButtonStagger.draw(new Button("OPTIONS", () -> {
|
||||||
client.setScreen(new OptionsScreen(new TitleMenu(), SaturnClient.client.options));
|
client.setScreen(new OptionsScreen(new TitleMenu(), SaturnClient.client.options));
|
||||||
}).scale(0.69f).dimensions(206, 52).centerOffset(width, height, -73, 80));
|
}).scale(0.69f).dimensions(206, 52).position(0, 80).animation(new SlideFade(1000, -10)));
|
||||||
|
|
||||||
draw(new Button("QUIT", () -> {
|
mainButtonStagger.draw(new Button("QUIT", () -> {
|
||||||
client.scheduleStop();
|
client.scheduleStop();
|
||||||
}).scale(0.69f).dimensions(206, 52).centerOffset(width, height, 73, 80));
|
}).scale(0.69f).dimensions(206, 52).position(146, 80).animation(new SlideFade(1000, -10)));
|
||||||
|
|
||||||
|
draw(mainButtonStagger.dimensions(289, 143).centerOffset(width, height, 0, 60));
|
||||||
|
|
||||||
int s = Fonts.getHeight() + 20;
|
int s = Fonts.getHeight() + 20;
|
||||||
|
|
||||||
draw(new TextureButton(Textures.HUD_ICON, () -> {
|
AnimationStagger saturnStagger = new AnimationStagger(180);
|
||||||
|
|
||||||
|
saturnStagger.draw(new TextureButton(Textures.HUD_ICON, () -> {
|
||||||
client.setScreen(new HudEditor());
|
client.setScreen(new HudEditor());
|
||||||
}).dimensions(s, s).centerHorizontal(width, height, -(s + 2), 8).animation(new SlideY(700, s + 8)));
|
}).dimensions(s, s).position(0, 0).animation(new SlideFade(1000, s + 8)));
|
||||||
|
|
||||||
draw(new TextureButton(Textures.SETTINGS, () -> {
|
saturnStagger.draw(new TextureButton(Textures.SETTINGS, () -> {
|
||||||
SaturnClient.client.setScreen(new ModMenu());
|
SaturnClient.client.setScreen(new ModMenu());
|
||||||
}).dimensions(s, s).centerHorizontal(width, height, 0, 8).animation(new SlideY(700, s + 8)));
|
}).dimensions(s, s).position(s + 2, 0).animation(new SlideFade(1000, s + 8)));
|
||||||
|
|
||||||
draw(new TextureButton(Textures.CLOAK, () -> {
|
saturnStagger.draw(new TextureButton(Textures.CLOAK, () -> {
|
||||||
client.setScreen(new CloakMenu());
|
client.setScreen(new CloakMenu());
|
||||||
}).dimensions(s, s).centerHorizontal(width, height, s + 2, 8).animation(new SlideY(700, s + 8)));
|
}).dimensions(s, s).position((s + 2) * 2, 0).animation(new SlideFade(1000, s + 8)));
|
||||||
|
|
||||||
|
draw(saturnStagger.dimensions(((s + 2) * 2) + s, s).centerHorizontal(width, height, 0, 8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.saturnclient.ui2.screens.store;
|
|||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import org.saturnclient.saturnclient.client.ServiceClient;
|
import org.saturnclient.saturnclient.client.ServiceClient;
|
||||||
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
|
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
|
||||||
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
||||||
import org.saturnclient.ui2.SaturnScreen;
|
import org.saturnclient.ui2.SaturnScreen;
|
||||||
import org.saturnclient.ui2.Utils;
|
import org.saturnclient.ui2.Utils;
|
||||||
@@ -75,10 +76,10 @@ public class CloakStore extends SaturnScreen {
|
|||||||
|
|
||||||
String t = "100";
|
String t = "100";
|
||||||
|
|
||||||
scroll.draw(new Text(t).position(x + Fonts.centerX(50, t, Text.font.value), y + 113).scale(0.5f));
|
scroll.draw(new Text(t).position(x + Fonts.centerX(50, t, Theme.FONT.value), y + 113).scale(0.5f));
|
||||||
|
|
||||||
scroll.draw(new ImageTexture(Textures.COINS).dimensions(16, 16)
|
scroll.draw(new ImageTexture(Textures.COINS).dimensions(16, 16)
|
||||||
.position(x + Fonts.getWidth(t, Text.font.value) - 1, y + 112).scale(0.5f));
|
.position(x + Fonts.getWidth(t, Theme.FONT.value) - 1, y + 112).scale(0.5f));
|
||||||
|
|
||||||
if (col == 8) {
|
if (col == 8) {
|
||||||
col = 0;
|
col = 0;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.saturnclient.ui2.screens.store;
|
|||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import org.saturnclient.saturnclient.client.ServiceClient;
|
import org.saturnclient.saturnclient.client.ServiceClient;
|
||||||
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
|
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
|
||||||
|
import org.saturnclient.saturnclient.config.Theme;
|
||||||
import org.saturnclient.saturnclient.cosmetics.Hats;
|
import org.saturnclient.saturnclient.cosmetics.Hats;
|
||||||
import org.saturnclient.ui2.SaturnScreen;
|
import org.saturnclient.ui2.SaturnScreen;
|
||||||
import org.saturnclient.ui2.Utils;
|
import org.saturnclient.ui2.Utils;
|
||||||
@@ -75,10 +76,10 @@ public class HatStore extends SaturnScreen {
|
|||||||
|
|
||||||
String t = "50";
|
String t = "50";
|
||||||
|
|
||||||
scroll.draw(new Text(t).position(x + Fonts.centerX(50, t, Text.font.value), y + 53).scale(0.5f));
|
scroll.draw(new Text(t).position(x + Fonts.centerX(50, t, Theme.FONT.value), y + 53).scale(0.5f));
|
||||||
|
|
||||||
scroll.draw(new ImageTexture(Textures.COINS).dimensions(16, 16)
|
scroll.draw(new ImageTexture(Textures.COINS).dimensions(16, 16)
|
||||||
.position(x + Fonts.getWidth(t, Text.font.value) + 4, y + 52).scale(0.5f));
|
.position(x + Fonts.getWidth(t, Theme.FONT.value) + 4, y + 52).scale(0.5f));
|
||||||
|
|
||||||
if (col == 8) {
|
if (col == 8) {
|
||||||
col = 0;
|
col = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user