Compare commits
83
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e3b6cf7f8 | ||
|
|
6fb38e4f9b | ||
|
|
997fbbe9a9 | ||
|
|
01a8ea15a0 | ||
|
|
08cee2172c | ||
|
|
2c64eed329 | ||
|
|
66d7d7eab9 | ||
|
|
21b1dcc997 | ||
|
|
c2470378e1 | ||
|
|
f57e773a44 | ||
|
|
6c0575a03f | ||
|
|
9f93ea923e | ||
|
|
ecf5987434 | ||
|
|
89a5b2437e | ||
|
|
c8d28133a0 | ||
|
|
0980e3a5d4 | ||
|
|
420ba82b44 | ||
|
|
2f3c125bba | ||
|
|
9e64b2332e | ||
|
|
089cf4778c | ||
|
|
b9984c35a2 | ||
|
|
b035381ba7 | ||
|
|
87b326ce9f | ||
|
|
786f9cf6f7 | ||
|
|
464d0b502b | ||
|
|
e38f4480a3 | ||
|
|
d178f1504b | ||
|
|
5b77ea7363 | ||
|
|
78097b1d8f | ||
|
|
51040900cf | ||
|
|
f06e2a0aaa | ||
|
|
70fcd64f25 | ||
|
|
b2c7e9f03e | ||
|
|
08155bd49a | ||
|
|
67a5b219f5 | ||
|
|
6c608409e0 | ||
|
|
4c72f8e39f | ||
|
|
3d9d01a28f | ||
|
|
7e39532d1d | ||
|
|
76c20d8733 | ||
|
|
a1c68609d9 | ||
|
|
d49afbb981 | ||
|
|
fd0bf75750 | ||
|
|
edbfd0306a | ||
|
|
324ffe0c8b | ||
|
|
21daf473b1 | ||
|
|
d1030bb235 | ||
|
|
05fcd3032b | ||
|
|
47cafad92b | ||
|
|
744698fd71 | ||
|
|
86b638afca | ||
|
|
a016fd72c6 | ||
|
|
8e8737afcd | ||
|
|
6eb3fc8092 | ||
|
|
f9baa0fe5f | ||
|
|
a6e762b0d8 | ||
|
|
d72b152a26 | ||
|
|
2a202c4160 | ||
|
|
930d002b81 | ||
|
|
35440180ea | ||
|
|
7fd0565f7f | ||
|
|
1421d94647 | ||
|
|
fbb1460872 | ||
|
|
e7ca5c0297 | ||
|
|
3a54739410 | ||
|
|
1c80803994 | ||
|
|
191e9eba4c | ||
|
|
3d654685d0 | ||
|
|
d9bd2c60c9 | ||
|
|
984132991d | ||
|
|
7d649efa22 | ||
|
|
1ffadc9b45 | ||
|
|
9a7b93ccbe | ||
|
|
d37d4e49f9 | ||
|
|
b491f246c8 | ||
|
|
cfe518380a | ||
|
|
fe2521bee2 | ||
|
|
ae4d9786b2 | ||
|
|
0f4af22346 | ||
|
|
5a8ae263e9 | ||
|
|
2458906e3b | ||
|
|
42611d4aed | ||
|
|
e5cc68ecad |
@@ -19,6 +19,10 @@ dependencies {
|
||||
|
||||
modApi "dev.felnull:special-model-loader:1.4.0+pre.1"
|
||||
include "dev.felnull:special-model-loader:1.4.0+pre.1"
|
||||
|
||||
include modImplementation("dev.kosmx.player-anim:player-animation-lib-fabric:${project.player_anim}")
|
||||
//You might want bendy-lib. playerAnimator will wrap it.
|
||||
// include modRuntimeOnly("io.github.kosmx.bendy-lib:bendy-lib-fabric:${project.bendylib_version}")
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +32,11 @@ repositories {
|
||||
name = "FelNull Maven"
|
||||
url = "https://maven.felnull.dev"
|
||||
}
|
||||
|
||||
maven {
|
||||
name "KosmX's maven"
|
||||
url 'https://maven.kosmx.dev/'
|
||||
}
|
||||
}
|
||||
|
||||
processResources {
|
||||
|
||||
+8
-12
@@ -1,17 +1,13 @@
|
||||
# Done to increase the memory available to gradle.
|
||||
org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://modmuss50.me/fabric.html
|
||||
minecraft_version=1.21.4
|
||||
yarn_mappings=1.21.4+build.7
|
||||
loader_version=0.16.10
|
||||
minecraft_version=1.21.4
|
||||
yarn_mappings=1.21.4+build.7
|
||||
loader_version=0.16.10
|
||||
fabric_version=0.114.0+1.21.4
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 0.0.1-alpha2
|
||||
maven_group = me.iipho3nix
|
||||
archives_base_name = saturnclient
|
||||
mod_version = 0.0.3-beta0
|
||||
maven_group = org.saturnclient
|
||||
archives_base_name = saturnclient
|
||||
|
||||
# Dependencies
|
||||
# check this on https://modmuss50.me/fabric.html
|
||||
fabric_version=0.114.0+1.21.4
|
||||
player_anim = 2.0.3+1.21.4
|
||||
@@ -1,11 +1,11 @@
|
||||
package org.saturnclient.modules;
|
||||
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
public interface HudMod {
|
||||
public ModDimensions getDimensions();
|
||||
|
||||
public void renderDummy(DrawContext context);
|
||||
public void renderDummy(RenderScope scope);
|
||||
|
||||
public void render(DrawContext context);
|
||||
public void renderHud(RenderScope scope);
|
||||
}
|
||||
|
||||
@@ -1,64 +1,54 @@
|
||||
package org.saturnclient.modules;
|
||||
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import java.util.Map;
|
||||
|
||||
import org.saturnclient.saturnclient.config.NamedProperty;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
|
||||
public class ModDimensions {
|
||||
public Property<Integer> x = new Property<>(0);
|
||||
public Property<Integer> y = new Property<>(0);
|
||||
public Property<Float> scale = new Property<>(1.0f);
|
||||
public Property<Integer> x = Property.integer(0);
|
||||
public Property<Integer> y = Property.integer(0);
|
||||
public Property<Float> scale = Property.floatProp(1.0f);
|
||||
public Property<Integer> bgColor = Property.color(0x00000000);
|
||||
public Property<Integer> fgColor = Property.color(0xFFffffff);
|
||||
public Property<Integer> radius = Property.integer(0);
|
||||
public Property<Integer> font = Property.font(0);
|
||||
public boolean renderBackground = true;
|
||||
|
||||
public int width = 0;
|
||||
public int height = 0;
|
||||
|
||||
private final ConfigManager dimensionsConfig;
|
||||
|
||||
public ModDimensions(ConfigManager configManager) {
|
||||
dimensionsConfig = new ConfigManager(configManager, "Dimensions");
|
||||
dimensionsConfig.property("x", this.x);
|
||||
dimensionsConfig.property("y", this.y);
|
||||
dimensionsConfig.property("scale", this.scale);
|
||||
public NamedProperty<Map<String, Property<?>>> prop() {
|
||||
return Property.namespace(Map.of(
|
||||
"X", x,
|
||||
"Y", y,
|
||||
"Scale", scale,
|
||||
"Background Color", bgColor,
|
||||
"Foreground Color", fgColor,
|
||||
"Corner Radius", radius,
|
||||
"Font", font
|
||||
)).named("In-Game Display");
|
||||
}
|
||||
|
||||
public ModDimensions(ConfigManager configManager, int x, int y) {
|
||||
dimensionsConfig = new ConfigManager(configManager, "Dimensions");
|
||||
this.x.value = x;
|
||||
this.y.value = y;
|
||||
dimensionsConfig.property("x", this.x);
|
||||
dimensionsConfig.property("y", this.y);
|
||||
dimensionsConfig.property("scale", this.scale);
|
||||
public ModDimensions() {}
|
||||
|
||||
public ModDimensions(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public ModDimensions(ConfigManager configManager, int x, int y, int width, int height) {
|
||||
dimensionsConfig = new ConfigManager(configManager, "Dimensions");
|
||||
public ModDimensions(int x, int y, int width, int height) {
|
||||
this.x.value = x;
|
||||
this.y.value = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
dimensionsConfig.property("x", this.x);
|
||||
dimensionsConfig.property("y", this.y);
|
||||
dimensionsConfig.property("scale", this.scale);
|
||||
}
|
||||
|
||||
public ModDimensions(ConfigManager configManager, int x, int y, float scale) {
|
||||
dimensionsConfig = new ConfigManager(configManager, "Dimensions");
|
||||
this.x.value = x;
|
||||
this.y.value = y;
|
||||
this.scale.value = scale;
|
||||
dimensionsConfig.property("x", this.x);
|
||||
dimensionsConfig.property("y", this.y);
|
||||
dimensionsConfig.property("scale", this.scale);
|
||||
}
|
||||
|
||||
public ModDimensions(ConfigManager configManager, int x, int y, int width, int height, float scale) {
|
||||
dimensionsConfig = new ConfigManager(configManager, "Dimensions");
|
||||
public ModDimensions(int x, int y, int width, int height, float scale) {
|
||||
this.x.value = x;
|
||||
this.y.value = y;
|
||||
this.scale.value = scale;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
dimensionsConfig.property("x", this.x);
|
||||
dimensionsConfig.property("y", this.y);
|
||||
dimensionsConfig.property("scale", this.scale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.saturnclient.modules;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
|
||||
import org.saturnclient.modules.mods.*;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
@@ -15,6 +15,12 @@ public class ModManager {
|
||||
public static Module[] MODS = {
|
||||
new Crosshair(),
|
||||
new AutoSprint(),
|
||||
new ArmorDisplay(),
|
||||
new Fps(),
|
||||
new PotionDisplay(),
|
||||
new Coordinates(),
|
||||
new Freelook(),
|
||||
new Keystrokes()
|
||||
};
|
||||
|
||||
public static void init() {
|
||||
@@ -38,16 +44,21 @@ public class ModManager {
|
||||
if (m instanceof HudMod && m.isEnabled()) {
|
||||
ModDimensions dim = ((HudMod) m).getDimensions();
|
||||
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
matrices.push();
|
||||
renderScope.matrices.push();
|
||||
|
||||
matrices.translate(dim.x.value, (float) dim.y.value, 0);
|
||||
renderScope.matrices.translate(dim.x.value, (float) dim.y.value, 0);
|
||||
|
||||
matrices.scale(dim.scale.value, dim.scale.value, 1.0f);
|
||||
renderScope.matrices.scale(dim.scale.value, dim.scale.value, 1.0f);
|
||||
|
||||
((HudMod) m).render(context);
|
||||
if (dim.renderBackground) {
|
||||
renderScope.drawRoundedRectangle(0, 0, dim.width, dim.height, dim.radius.value, dim.bgColor.value);
|
||||
}
|
||||
|
||||
matrices.pop();
|
||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||
|
||||
((HudMod) m).renderHud(renderScope);
|
||||
|
||||
renderScope.matrices.pop();
|
||||
} else {
|
||||
m.render(renderScope);
|
||||
}
|
||||
|
||||
@@ -2,34 +2,23 @@ package org.saturnclient.modules;
|
||||
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.NamedProperty;
|
||||
import org.saturnclient.ui.Textures;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public abstract class Module {
|
||||
private final String name;
|
||||
private final String namespace;
|
||||
private final ModuleDetails details;
|
||||
private final ConfigManager configManager;
|
||||
|
||||
public Module(String name, String namespace, NamedProperty<?>... props) {
|
||||
this.name = name;
|
||||
this.namespace = namespace;
|
||||
|
||||
configManager = new ConfigManager(name);
|
||||
|
||||
public Module(ModuleDetails details, NamedProperty<?>... props) {
|
||||
this.details = details;
|
||||
configManager = new ConfigManager(details.name);
|
||||
for (NamedProperty<?> prop : props) {
|
||||
configManager.property(prop.name, prop.prop);
|
||||
}
|
||||
}
|
||||
|
||||
public Module(ConfigManager config, String name, String namespace) {
|
||||
this.name = name;
|
||||
this.namespace = namespace;
|
||||
|
||||
configManager = config;
|
||||
}
|
||||
|
||||
public void render(RenderScope scope) {}
|
||||
public void tick() {}
|
||||
|
||||
@@ -38,14 +27,26 @@ public abstract class Module {
|
||||
public abstract void setEnabled(boolean e);
|
||||
|
||||
public final String getName() {
|
||||
return name;
|
||||
return details.name;
|
||||
}
|
||||
|
||||
public Identifier getIconTexture() {
|
||||
return Textures.getModIcon(namespace);
|
||||
return Textures.getModIcon(details.namespace);
|
||||
}
|
||||
|
||||
public ConfigManager getConfig() {
|
||||
return configManager;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return details.description;
|
||||
}
|
||||
|
||||
public String[] getTags() {
|
||||
return details.tags;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return details.version;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.saturnclient.modules;
|
||||
|
||||
public class ModuleDetails {
|
||||
public String name;
|
||||
public String namespace;
|
||||
public String description;
|
||||
public String version;
|
||||
public String[] tags = {};
|
||||
|
||||
public ModuleDetails(String name, String namespace) {
|
||||
this.name = name;
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
public ModuleDetails name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModuleDetails namespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModuleDetails description(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModuleDetails version(String version) {
|
||||
this.version = version;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModuleDetails tags(String... tags) {
|
||||
this.tags = tags;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
# Credits
|
||||
### Freelook
|
||||
- https://github.com/Celibistrial/freelook
|
||||
- https://modrinth.com/mod/freelook
|
||||
|
||||
**The other mods are coded by us, if you have a concern or we missed something feel free to submit a issue with the credits tag**
|
||||
@@ -0,0 +1,89 @@
|
||||
package org.saturnclient.modules.mods;
|
||||
|
||||
import org.saturnclient.modules.HudMod;
|
||||
import org.saturnclient.modules.ModDimensions;
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.modules.ModuleDetails;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
|
||||
public class ArmorDisplay extends Module implements HudMod {
|
||||
private static Property<Boolean> enabled = Property.bool(false);
|
||||
private static ModDimensions dimensions = new ModDimensions(40, 60);
|
||||
|
||||
public ArmorDisplay() {
|
||||
super(new ModuleDetails("Armor Display", "armor")
|
||||
.description("Displays armor durability")
|
||||
.version("v0.1.0")
|
||||
.tags("Utility"),
|
||||
enabled.named("Enabled"),
|
||||
dimensions.prop());
|
||||
}
|
||||
|
||||
public void renderArmor(RenderScope scope, ItemStack helmet, ItemStack chestplate, ItemStack leggings, ItemStack boots) {
|
||||
int row = 0;
|
||||
|
||||
if (!helmet.isEmpty()) {
|
||||
scope.drawItem(helmet, 0, 0);
|
||||
renderHealth(scope, row, helmet.getMaxDamage(), helmet.getDamage());
|
||||
row++;
|
||||
}
|
||||
|
||||
if (!chestplate.isEmpty()) {
|
||||
scope.drawItem(chestplate, 0, 15 * row);
|
||||
renderHealth(scope, row, chestplate.getMaxDamage(), chestplate.getDamage());
|
||||
row++;
|
||||
}
|
||||
if (!leggings.isEmpty()) {
|
||||
scope.drawItem(leggings, 0, 15 * row);
|
||||
renderHealth(scope, row, leggings.getMaxDamage(), leggings.getDamage());
|
||||
row++;
|
||||
}
|
||||
|
||||
if (!boots.isEmpty()) {
|
||||
scope.drawItem(boots, 0, 15 * row);
|
||||
renderHealth(scope, row, boots.getMaxDamage(), boots.getDamage());
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
public void renderHealth(RenderScope scope, int i, int max_damage, int damage) {
|
||||
if (max_damage > 0 ) {
|
||||
scope.drawText(0.5f, "" + (max_damage - damage), 17, (15 * i) + 3, dimensions.font.value, dimensions.fgColor.value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHud(RenderScope scope) {
|
||||
renderArmor(scope,
|
||||
SaturnClient.client.player.getEquippedStack(EquipmentSlot.HEAD),
|
||||
SaturnClient.client.player.getEquippedStack(EquipmentSlot.CHEST),
|
||||
SaturnClient.client.player.getEquippedStack(EquipmentSlot.LEGS),
|
||||
SaturnClient.client.player.getEquippedStack(EquipmentSlot.FEET));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderDummy(RenderScope scope) {
|
||||
renderArmor(scope, new ItemStack(Items.DIAMOND_HELMET), new ItemStack(Items.DIAMOND_CHESTPLATE), new ItemStack(Items.DIAMOND_LEGGINGS), new ItemStack(Items.DIAMOND_BOOTS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModDimensions getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,20 @@ package org.saturnclient.modules.mods;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.modules.ModuleDetails;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
|
||||
public class AutoSprint extends Module {
|
||||
private static Property<Boolean> enabled = new Property<>(true);
|
||||
private static Property<Boolean> enabled = Property.bool(false);
|
||||
|
||||
public AutoSprint() {
|
||||
super("Auto Sprint", "sprint", enabled.named("Enabled"));
|
||||
super(
|
||||
new ModuleDetails("Auto Sprint", "sprint")
|
||||
.description("Makes the player always sprint")
|
||||
.tags("Movement")
|
||||
.version("v0.1.0"),
|
||||
enabled.named("Enabled"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.saturnclient.modules.mods;
|
||||
|
||||
import org.saturnclient.modules.HudMod;
|
||||
import org.saturnclient.modules.ModDimensions;
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.modules.ModuleDetails;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class Coordinates extends Module implements HudMod {
|
||||
private static Property<Boolean> enabled = Property.bool(false);
|
||||
private static Property<Integer> displayMethod = Property.select(0, "Flat", "Flat annotated", "Newline", "Newline annotated");
|
||||
private static ModDimensions dimensions = new ModDimensions(40, 18);
|
||||
|
||||
public Coordinates() {
|
||||
super(new ModuleDetails("Coordinates", "coords")
|
||||
.description("Displays your current coordinates")
|
||||
.version("v0.1.0")
|
||||
.tags("Utility"),
|
||||
enabled.named("Enabled"),
|
||||
displayMethod.named("Display Method"),
|
||||
dimensions.prop()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderDummy(RenderScope scope) {
|
||||
renderCoords(532, 69, 253, scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHud(RenderScope scope) {
|
||||
Vec3d pos = SaturnClient.client.player.getPos();
|
||||
renderCoords((int) pos.x, (int) pos.y, (int) pos.z, scope);
|
||||
}
|
||||
|
||||
public void renderCoords(int x, int y, int z, RenderScope scope) {
|
||||
String f = "%d %d %d"; // Flat
|
||||
switch (displayMethod.value) {
|
||||
case 1: // Flat annotated
|
||||
f = "X: %d Y: %d Z: %d";
|
||||
break;
|
||||
case 2: // Newline
|
||||
f = "%d\n%d\n%d";
|
||||
break;
|
||||
case 3: // Newline annotated
|
||||
f = "X: %d\nY: %d\nZ: %d";
|
||||
break;
|
||||
}
|
||||
String text = String.format(f, x, y, z);
|
||||
scope.drawText(text,
|
||||
0, 0, dimensions.font.value, dimensions.fgColor.value);
|
||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
||||
dimensions.height = 18 * text.split("\n").length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModDimensions getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.saturnclient.modules.mods;
|
||||
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.modules.ModuleDetails;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
@@ -9,17 +10,20 @@ import org.saturnclient.ui2.resources.Textures;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
|
||||
public class Crosshair extends Module {
|
||||
public static Property<Boolean> enabled = new Property<>(false);
|
||||
public static Property<Boolean> range_indicator = new Property<>(false);
|
||||
public static Property<Boolean> enabled = Property.bool(false);
|
||||
|
||||
public Crosshair() {
|
||||
super("Crosshair", "crosshair", enabled.named("Enabled"), range_indicator.named("Range Indicator"));
|
||||
super(
|
||||
new ModuleDetails("Crosshair", "crosshair")
|
||||
.description("Changes the crosshair if you're aiming at a entity")
|
||||
.tags("Visuals", "Utility")
|
||||
.version("v0.1.0"),
|
||||
enabled.named("Enabled"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope scope) {
|
||||
if (enabled.value
|
||||
&& range_indicator.value
|
||||
&& SaturnClient.client.targetedEntity != null
|
||||
&& SaturnClient.client.targetedEntity.isAlive()) {
|
||||
int scaledWidth = 15;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.saturnclient.modules.mods;
|
||||
|
||||
import org.saturnclient.modules.HudMod;
|
||||
import org.saturnclient.modules.ModDimensions;
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.modules.ModuleDetails;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
public class Fps extends Module implements HudMod {
|
||||
private static Property<Boolean> enabled = Property.bool(false);
|
||||
private static ModDimensions dimensions = new ModDimensions(60, Fonts.getHeight());
|
||||
|
||||
public Fps() {
|
||||
super(new ModuleDetails("FPS Display", "fps")
|
||||
.description("Displays current FPS")
|
||||
.version("v0.1.0")
|
||||
.tags("Utility"),
|
||||
enabled.named("Enabled"),
|
||||
dimensions.prop());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHud(RenderScope scope) {
|
||||
String text = String.valueOf(SaturnClient.client.getCurrentFps()) + " FPS";
|
||||
scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value);
|
||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderDummy(RenderScope scope) {
|
||||
String text = "369 FPS";
|
||||
scope.drawText(text, 0, 0, dimensions.font.value, dimensions.fgColor.value);
|
||||
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModDimensions getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package org.saturnclient.modules.mods;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.modules.ModuleDetails;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
|
||||
import net.minecraft.client.option.Perspective;
|
||||
|
||||
public class Freelook extends Module {
|
||||
private static Property<Boolean> enabled = Property.bool(false);
|
||||
private static Property<Boolean> toggle = Property.bool(true);
|
||||
public static Property<Integer> freelookKey = Property.keybinding(GLFW.GLFW_KEY_H);
|
||||
public static boolean isFreeLooking = false;
|
||||
private static boolean was1stPerson = false;
|
||||
|
||||
public Freelook() {
|
||||
super(
|
||||
new ModuleDetails("Freelook", "freelook")
|
||||
.description("Allows you to look around freely without moving your character")
|
||||
.tags("Movement", "Camera")
|
||||
.version("0.1.0"),
|
||||
enabled.named("Enabled"),
|
||||
toggle.named("Toggle freelook"),
|
||||
freelookKey.named("Freelook Keybinding")
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (toggle.value) {
|
||||
if (freelookKey.wasKeyPressed()) {
|
||||
if (isFreeLooking) {
|
||||
stopFreelook();
|
||||
} else {
|
||||
startFreelook();
|
||||
}
|
||||
}
|
||||
} else if (freelookKey.isKeyPressed()) {
|
||||
if (!isFreeLooking) {
|
||||
startFreelook();
|
||||
}
|
||||
} else if (isFreeLooking) {
|
||||
stopFreelook();
|
||||
}
|
||||
}
|
||||
|
||||
private void startFreelook() {
|
||||
isFreeLooking = true;
|
||||
was1stPerson = SaturnClient.client.options.getPerspective() == Perspective.FIRST_PERSON;
|
||||
SaturnClient.client.options.setPerspective(Perspective.THIRD_PERSON_BACK);
|
||||
}
|
||||
|
||||
private void stopFreelook() {
|
||||
if (was1stPerson) {
|
||||
SaturnClient.client.options.setPerspective(Perspective.FIRST_PERSON);
|
||||
}
|
||||
isFreeLooking = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package org.saturnclient.modules.mods;
|
||||
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.modules.HudMod;
|
||||
import org.saturnclient.modules.ModDimensions;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.modules.ModuleDetails;
|
||||
|
||||
public class Keystrokes extends Module implements HudMod {
|
||||
public static Property<Boolean> enabled = Property.bool(false);
|
||||
public static Property<Boolean> showMouse = Property.bool(true);
|
||||
public static Property<Boolean> showSpace = Property.bool(false);
|
||||
public static ModDimensions dimensions = new ModDimensions(78, 46);
|
||||
private boolean w = false;
|
||||
private boolean a = false;
|
||||
private boolean s = false;
|
||||
private boolean d = false;
|
||||
private boolean lmb = false;
|
||||
private boolean rmb = false;
|
||||
private boolean space = false;
|
||||
|
||||
private static Property<Integer> clickBg = Property.color(0xFFCCCCCC);
|
||||
private static Property<Integer> clickFg = Property.color(0xFFFFFFFF);
|
||||
|
||||
public Keystrokes() {
|
||||
super(new ModuleDetails("Keystrokes", "keystrokes")
|
||||
.description("Displays the keystrokes for movement")
|
||||
.version("v0.1.0")
|
||||
.tags("Utility"),
|
||||
|
||||
enabled.named("Enabled"),
|
||||
showMouse.named("Show mouse clicks"),
|
||||
showSpace.named("Show space clicks"),
|
||||
dimensions.prop(),
|
||||
clickFg.named("Clicked fg"),
|
||||
clickBg.named("Clicked bg"));
|
||||
|
||||
dimensions.renderBackground = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
w = SaturnClient.client.options.forwardKey.isPressed();
|
||||
a = SaturnClient.client.options.leftKey.isPressed();
|
||||
s = SaturnClient.client.options.backKey.isPressed();
|
||||
d = SaturnClient.client.options.rightKey.isPressed();
|
||||
lmb = SaturnClient.client.options.attackKey.isPressed();
|
||||
rmb = SaturnClient.client.options.useKey.isPressed();
|
||||
space = SaturnClient.client.options.jumpKey.isPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderDummy(RenderScope scope) {
|
||||
dimensions.height = 54; // base height with padding considered
|
||||
|
||||
// WASD keys (3px padding between each key)
|
||||
renderKey(scope, true, 'W', 27, 0); // Top center
|
||||
renderKey(scope, false, 'A', 0, 27); // Bottom left
|
||||
renderKey(scope, false, 'S', 27, 27); // Bottom center
|
||||
renderKey(scope, false, 'D', 54, 27); // Bottom right
|
||||
|
||||
if (showMouse.value) {
|
||||
renderKeyM(scope, true, "LMB", 0, 54); // Below A/S/D
|
||||
renderKeyM(scope, false, "RMB", 40, 54); // With 3px between
|
||||
dimensions.height += 27;
|
||||
}
|
||||
|
||||
if (showSpace.value) {
|
||||
renderKeySpace(scope, false, 0, dimensions.height);
|
||||
dimensions.height += 22;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHud(RenderScope scope) {
|
||||
dimensions.height = 54; // base height with padding considered
|
||||
|
||||
// WASD keys (3px padding between each key)
|
||||
renderKey(scope, w, 'W', 27, 0); // Top center
|
||||
renderKey(scope, a, 'A', 0, 27); // Bottom left
|
||||
renderKey(scope, s, 'S', 27, 27); // Bottom center
|
||||
renderKey(scope, d, 'D', 54, 27); // Bottom right
|
||||
|
||||
if (showMouse.value) {
|
||||
renderKeyM(scope, lmb, "LMB", 0, 54); // Below A/S/D
|
||||
renderKeyM(scope, rmb, "RMB", 40, 54); // With 3px between
|
||||
dimensions.height += 27;
|
||||
}
|
||||
|
||||
if (showSpace.value) {
|
||||
renderKeySpace(scope, space, 0, dimensions.height);
|
||||
dimensions.height += 22;
|
||||
}
|
||||
}
|
||||
|
||||
// Consistent 3px padding applied below:
|
||||
|
||||
private void renderKeySpace(RenderScope scope, boolean isPressed, int x, int y) {
|
||||
int height = 19;
|
||||
scope.drawRoundedRectangle(x, y, dimensions.width, height, dimensions.radius.value, isPressed ? clickBg.value : dimensions.bgColor.value);
|
||||
|
||||
// A 30-pixel line centered vertically with 3px top padding
|
||||
int lineY = y + (height - 1) / 2;
|
||||
scope.drawRect(x + (dimensions.width - 30) / 2, lineY, 30, 1, isPressed ? clickFg.value : dimensions.fgColor.value);
|
||||
}
|
||||
|
||||
private void renderKeyM(RenderScope scope, boolean isPressed, String c, int x, int y) {
|
||||
int width = 38, height = 24;
|
||||
scope.drawRoundedRectangle(x, y, width, height, dimensions.radius.value, isPressed ? clickBg.value : dimensions.bgColor.value);
|
||||
|
||||
// Apply padding: 3px top and left -> add slight offset to x/y
|
||||
scope.drawText(0.6f, c, x + 9, y + 7, dimensions.font.value, isPressed ? clickFg.value : dimensions.fgColor.value);
|
||||
}
|
||||
|
||||
private void renderKey(RenderScope scope, boolean isPressed, char c, int x, int y) {
|
||||
int size = 24;
|
||||
scope.drawRoundedRectangle(x, y, size, size, dimensions.radius.value, isPressed ? clickBg.value : dimensions.bgColor.value);
|
||||
|
||||
// Center the character with 3px top padding
|
||||
scope.drawText(0.6f, String.valueOf(c), x + 9, y + 7, dimensions.font.value, isPressed ? clickFg.value : dimensions.fgColor.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModDimensions getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package org.saturnclient.modules.mods;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.saturnclient.modules.HudMod;
|
||||
import org.saturnclient.modules.ModDimensions;
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.modules.ModuleDetails;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.texture.StatusEffectSpriteManager;
|
||||
import net.minecraft.entity.effect.StatusEffect;
|
||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.entry.RegistryEntry;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class PotionDisplay extends Module implements HudMod {
|
||||
public static Property<Boolean> enabled = Property.bool(false);
|
||||
private static ModDimensions dimensions = new ModDimensions(60, 0);
|
||||
|
||||
private final StatusEffectInstance[] dummyEffects = {
|
||||
new StatusEffectInstance(Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("speed")).get(), 12000, 2),
|
||||
new StatusEffectInstance(Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("strength")).get(), 12000, 2),
|
||||
new StatusEffectInstance(Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("fire_resistance")).get(), 12000, 2),
|
||||
};
|
||||
|
||||
public PotionDisplay() {
|
||||
super(new ModuleDetails("Potion Display", "potion")
|
||||
.description("Displays potion effects")
|
||||
.version("v0.1.0")
|
||||
.tags("Utility"),
|
||||
|
||||
enabled.named("Enabled"),
|
||||
dimensions.prop());
|
||||
}
|
||||
|
||||
private void renderEffects(RenderScope scope, Iterable<StatusEffectInstance> effects) {
|
||||
int row = 0;
|
||||
|
||||
StatusEffectSpriteManager statusEffectSpriteManager = SaturnClient.client.getStatusEffectSpriteManager();
|
||||
|
||||
for (StatusEffectInstance effect : effects) {
|
||||
if (effect.shouldShowIcon()) {
|
||||
RegistryEntry<StatusEffect> registryEntry = effect.getEffectType();
|
||||
Sprite sprite = statusEffectSpriteManager.getSprite(registryEntry);
|
||||
scope.drawSpriteStretched(sprite, 0, 18 * row, 16, 16);
|
||||
scope.drawText(0.5f, getDurationAsString(effect), 18, 18 * row + 3, dimensions.font.value, -1);
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
dimensions.height = 18 * row;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHud(RenderScope scope) {
|
||||
renderEffects(scope, SaturnClient.client.player.getStatusEffects());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderDummy(RenderScope scope) {
|
||||
renderEffects(scope, Arrays.asList(dummyEffects));
|
||||
}
|
||||
|
||||
// This code was from: https://github.com/magicus/statuseffecttimer/blob/master/src/main/java/se/icus/mag/statuseffecttimer/mixin/StatusEffectTimerMixin.java
|
||||
private String getDurationAsString(StatusEffectInstance statusEffectInstance) {
|
||||
if (statusEffectInstance.isInfinite()) {
|
||||
return I18n.translate("effect.duration.infinite");
|
||||
}
|
||||
|
||||
int ticks = MathHelper.floor((float) statusEffectInstance.getDuration());
|
||||
int totalSeconds = ticks / 20;
|
||||
|
||||
if (totalSeconds >= 3600) {
|
||||
return totalSeconds / 3600 + "h";
|
||||
} else if (totalSeconds >= 60) {
|
||||
int minutes = totalSeconds / 60;
|
||||
int seconds = totalSeconds % 60;
|
||||
return String.format("%d:%02d", minutes, seconds);
|
||||
} else {
|
||||
return String.valueOf(totalSeconds) + "s";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModDimensions getDimensions() {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.saturnclient.modules.mods.mixins;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
import org.saturnclient.modules.mods.Freelook;
|
||||
import org.saturnclient.modules.mods.utils.CameraOverriddenEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(Camera.class)
|
||||
public abstract class CameraMixin {
|
||||
@Unique
|
||||
boolean firstTime = true;
|
||||
|
||||
@Shadow
|
||||
protected abstract void setRotation(float yaw, float pitch);
|
||||
|
||||
@Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER))
|
||||
public void lockRotation(BlockView focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing, float tickDelta, CallbackInfo ci) {
|
||||
if (Freelook.isFreeLooking && cameraEntity instanceof ClientPlayerEntity) {
|
||||
CameraOverriddenEntity cameraOverriddenEntity = (CameraOverriddenEntity) cameraEntity;
|
||||
|
||||
if (firstTime && MinecraftClient.getInstance().player != null) {
|
||||
cameraOverriddenEntity.freelook$setCameraPitch(MinecraftClient.getInstance().player.getPitch());
|
||||
cameraOverriddenEntity.freelook$setCameraYaw(MinecraftClient.getInstance().player.getYaw());
|
||||
firstTime = false;
|
||||
}
|
||||
this.setRotation(cameraOverriddenEntity.freelook$getCameraYaw(), cameraOverriddenEntity.freelook$getCameraPitch());
|
||||
|
||||
}
|
||||
if (!Freelook.isFreeLooking && cameraEntity instanceof ClientPlayerEntity) {
|
||||
firstTime = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.saturnclient.modules.mods.mixins;
|
||||
|
||||
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import org.saturnclient.modules.mods.Freelook;
|
||||
import org.saturnclient.modules.mods.utils.CameraOverriddenEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(Entity.class)
|
||||
public class EntityMixin implements CameraOverriddenEntity {
|
||||
@Unique
|
||||
private float cameraPitch;
|
||||
|
||||
@Unique
|
||||
private float cameraYaw;
|
||||
|
||||
@Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true)
|
||||
public void changeCameraLookDirection(double xDelta, double yDelta, CallbackInfo ci) {
|
||||
//noinspection ConstantValue// IntelliJ is incorrect here, this code block is reachable
|
||||
if (Freelook.isFreeLooking && (Object) this instanceof ClientPlayerEntity) {
|
||||
double pitchDelta = (yDelta * 0.15);
|
||||
double yawDelta = (xDelta * 0.15);
|
||||
|
||||
this.cameraPitch = MathHelper.clamp(this.cameraPitch + (float) pitchDelta, -90.0f, 90.0f);
|
||||
this.cameraYaw += (float) yawDelta;
|
||||
|
||||
ci.cancel();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Unique
|
||||
public float freelook$getCameraPitch() {
|
||||
return this.cameraPitch;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Unique
|
||||
public float freelook$getCameraYaw() {
|
||||
return this.cameraYaw;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Unique
|
||||
public void freelook$setCameraPitch(float pitch) {
|
||||
this.cameraPitch = pitch;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Unique
|
||||
public void freelook$setCameraYaw(float yaw) {
|
||||
this.cameraYaw = yaw;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.saturnclient.modules.mods.utils;
|
||||
|
||||
public interface CameraOverriddenEntity {
|
||||
float freelook$getCameraPitch();
|
||||
float freelook$getCameraYaw();
|
||||
|
||||
void freelook$setCameraPitch(float pitch);
|
||||
void freelook$setCameraYaw(float yaw);
|
||||
}
|
||||
@@ -4,15 +4,20 @@ import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.TitleScreen;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import org.saturnclient.modules.ModManager;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.saturnclient.cosmetics.Emotes;
|
||||
import org.saturnclient.saturnclient.cosmetics.Hats;
|
||||
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
||||
import org.saturnclient.saturnclient.event.KeyInputHandler;
|
||||
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.elements.ImageTexture;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
import org.saturnclient.ui2.screens.TitleMenu;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -32,24 +37,43 @@ public class SaturnClient implements ModInitializer {
|
||||
public void onInitialize() {
|
||||
LOGGER.info("Initializing " + MOD_ID);
|
||||
client = MinecraftClient.getInstance();
|
||||
ModManager.init();
|
||||
SaturnClientConfig.init();
|
||||
ThemeManager.load();
|
||||
ConfigManager.load();
|
||||
ModManager.init();
|
||||
|
||||
ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save());
|
||||
ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
|
||||
if (SaturnClientConfig.saturnTitleScreen.value && screen instanceof TitleScreen
|
||||
&& !(screen instanceof TitleMenu)) {
|
||||
client.setScreen(new TitleMenu());
|
||||
}
|
||||
});
|
||||
|
||||
SpecialModelLoaderEvents.LOAD_SCOPE.register(() -> {
|
||||
return (resourceManager, location) -> MOD_ID.equals(location.getNamespace());
|
||||
});
|
||||
|
||||
ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
|
||||
if (screen != null && !(screen instanceof TitleMenu)) {
|
||||
if (screen instanceof SaturnScreen) {
|
||||
((SaturnScreen) screen).draw(new ImageTexture(Textures.LOGO_TEXT_BIG).dimensions(180, 18).position(screen.width - 180 - 20, screen.height - 18 - 20));
|
||||
} else {
|
||||
ScreenEvents.afterRender(screen).register((screen1, context, mouseX, mouseY, tickDelta) -> {
|
||||
RenderScope renderScope = new RenderScope(context.getMatrices(),
|
||||
((DrawContextAccessor) context).getVertexConsumers());
|
||||
|
||||
int width = context.getScaledWindowWidth();
|
||||
int height = context.getScaledWindowHeight();
|
||||
|
||||
float scaleX = (float) screen1.width / width;
|
||||
float scaleY = (float) screen1.height / height;
|
||||
|
||||
MatrixStack matrixStack = context.getMatrices();
|
||||
matrixStack.push();
|
||||
matrixStack.translate(width - 95, height - 14, 0);
|
||||
matrixStack.scale(0.5f / scaleX, 0.5f / scaleY, 1.0f);
|
||||
renderScope.drawTexture(Textures.LOGO_TEXT_BIG, 0, 0, 0, 0, 180, 18);
|
||||
matrixStack.pop();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
KeyInputHandler.register();
|
||||
Emotes.initialize();
|
||||
if (Auth.authenticate()) {
|
||||
Cloaks.initialize();
|
||||
Hats.initialize();
|
||||
|
||||
@@ -1,48 +1,20 @@
|
||||
package org.saturnclient.saturnclient;
|
||||
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.ui.SaturnAnimation;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.Textures;
|
||||
import org.saturnclient.ui.animations.FadeIn;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.ColorHelper;
|
||||
|
||||
public class SaturnClientConfig {
|
||||
public static ConfigManager config;
|
||||
|
||||
public static Property<Integer> color =
|
||||
new Property<>(
|
||||
ColorHelper.getArgb(255, 251, 60, 79),
|
||||
Property.PropertyType.HEX);
|
||||
public static Property<Boolean> realisticLogo = Property.bool(false);
|
||||
|
||||
public static Property<Integer> normal =
|
||||
new Property<>(
|
||||
ColorHelper.getArgb(255, 182, 182, 182),
|
||||
Property.PropertyType.HEX);
|
||||
|
||||
public static Property<Boolean> realisticLogo =
|
||||
new Property<>(false);
|
||||
|
||||
public static Property<Boolean> saturnTitleScreen =
|
||||
new Property<>(true);
|
||||
|
||||
public static int WHITE = ColorHelper.getArgb(255, 255, 255, 255);
|
||||
|
||||
public static int getWhite(float alpha) {
|
||||
return ((int) (alpha * 255) << 24) | (normal.value & 0x00FFFFFF);
|
||||
}
|
||||
|
||||
public static int getColor(boolean hovering, float alpha) {
|
||||
return SaturnUi.getAlpha(hovering ? color.value : normal.value, alpha);
|
||||
}
|
||||
|
||||
public static SaturnAnimation[] getAnimations() {
|
||||
return new SaturnAnimation[] { new FadeIn(1) };
|
||||
}
|
||||
public static Property<Boolean> saturnTitleScreen = Property.bool(true);
|
||||
public static Property<Integer> openEmoteWheel = Property.keybinding(GLFW.GLFW_KEY_B);
|
||||
|
||||
public static Identifier getLogo() {
|
||||
return realisticLogo.value ? Textures.REALISTIC_LOGO : Textures.LOGO;
|
||||
@@ -71,10 +43,8 @@ public class SaturnClientConfig {
|
||||
|
||||
public static void init() {
|
||||
config = new ConfigManager("Saturn Client");
|
||||
|
||||
config.property("Primary color", color);
|
||||
config.property("Default color", normal);
|
||||
config.property("Realistic logo", realisticLogo);
|
||||
config.property("Saturn client title screen", saturnTitleScreen);
|
||||
config.property("Open Emote Wheel", openEmoteWheel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,22 @@ package org.saturnclient.saturnclient.auth;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import net.minecraft.client.network.AbstractClientPlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import org.saturnclient.saturnclient.cosmetics.Hats;
|
||||
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.elements.Notification;
|
||||
import org.saturnclient.ui2.elements.Notification.NotificationKind;
|
||||
|
||||
import dev.kosmx.playerAnim.api.layered.AnimationStack;
|
||||
import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationAccess;
|
||||
import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationRegistry;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
|
||||
public class Auth {
|
||||
@@ -96,9 +109,72 @@ public class Auth {
|
||||
}
|
||||
break;
|
||||
|
||||
case "successful_transaction":
|
||||
String cloak = parser.getStringOrNull("cloak");
|
||||
String hat = parser.getStringOrNull("hat");
|
||||
if (cloak != null) {
|
||||
Cloaks.availableCloaks.add(cloak);
|
||||
|
||||
}
|
||||
if (hat != null) {
|
||||
Hats.availableHats.add(hat);
|
||||
}
|
||||
|
||||
case "update_cloak":
|
||||
String targetUuid = parser.getStringOrNull("uuid");
|
||||
String targetCloak = parser.getStringOrNull("cloak");
|
||||
if (targetUuid != null && targetCloak != null) {
|
||||
SaturnPlayer player = players.get(targetUuid);
|
||||
if (player != null) {
|
||||
player.cloak = targetCloak;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "update_hat":
|
||||
targetUuid = parser.getStringOrNull("uuid");
|
||||
String targetHat = parser.getStringOrNull("hat");
|
||||
if (targetUuid != null && targetHat != null) {
|
||||
SaturnPlayer player = players.get(targetUuid);
|
||||
if (player != null) {
|
||||
player.hat = targetHat;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "emote":
|
||||
targetUuid = parser.getStringOrNull("uuid");
|
||||
String emote = parser.getStringOrNull("name");
|
||||
|
||||
for (AbstractClientPlayerEntity player : SaturnClient.client.world.getPlayers()) {
|
||||
if (player.getUuidAsString().replace("-", "").equals(targetUuid)) {
|
||||
AnimationStack animationStack = PlayerAnimationAccess.getPlayerAnimLayer(player);
|
||||
if (emote != null && !emote.isEmpty()) {
|
||||
if (animationStack.isActive() && animationStack.getPriority() == 1000) {
|
||||
animationStack.removeLayer(1000);
|
||||
}
|
||||
animationStack.addAnimLayer(1000,
|
||||
PlayerAnimationRegistry
|
||||
.getAnimation(Identifier.of("saturnclient", emote))
|
||||
.playAnimation());
|
||||
} else {
|
||||
animationStack.removeLayer(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (parser.error != null) {
|
||||
SaturnClient.LOGGER.error("Error from the server: " + parser.error);
|
||||
|
||||
if (SaturnClient.client.currentScreen instanceof SaturnScreen) {
|
||||
String[] a = parser.error.replace("!", "").split(": ");
|
||||
((SaturnScreen) SaturnClient.client.currentScreen)
|
||||
.draw(new Notification(SaturnClient.client.currentScreen.width,
|
||||
SaturnClient.client.currentScreen.height, NotificationKind.Error,
|
||||
a[0], a[1]));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -161,7 +237,7 @@ public class Auth {
|
||||
|
||||
public static void setCloak(String cloakName) {
|
||||
try {
|
||||
Network.write("set_cloak@cloak=" + cloakName);
|
||||
Network.write("set_cloak@cloak=" + cloakName + "@notify=" + stringifyPlayers());
|
||||
} catch (Exception e) {
|
||||
SaturnClient.LOGGER.error("Request failed", e);
|
||||
}
|
||||
@@ -169,12 +245,26 @@ public class Auth {
|
||||
|
||||
public static void setHat(String hatName) {
|
||||
try {
|
||||
Network.write("set_hat@hat=" + hatName);
|
||||
Network.write("set_hat@hat=" + hatName + "@notify=" + stringifyPlayers());
|
||||
} catch (Exception e) {
|
||||
SaturnClient.LOGGER.error("Request failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void emote(String name) {
|
||||
try {
|
||||
Network.write("emote@name=" + name + "@notify=" + stringifyPlayers());
|
||||
} catch (Exception e) {
|
||||
SaturnClient.LOGGER.error("Request failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String stringifyPlayers() {
|
||||
return players.keySet().stream()
|
||||
.filter(key -> key != uuid)
|
||||
.collect(Collectors.joining("$"));
|
||||
}
|
||||
|
||||
public static void player(String name, String uuid) {
|
||||
try {
|
||||
playerNames.put(name, uuid.replaceAll("-", ""));
|
||||
@@ -184,14 +274,19 @@ public class Auth {
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendReload() {
|
||||
for (Map.Entry<String, String> player : playerNames.entrySet()) {
|
||||
if (players.containsKey(player.getValue()) && !player.getValue().equals(uuid)) {
|
||||
SaturnClient.client.player.networkHandler
|
||||
.sendChatCommand("msg " + player.getKey() + " "
|
||||
+ "$SATURN_RELOAD if you are seeing this as a player, please report this to https://github.com/saturnclientmc/saturnclient/issues");
|
||||
;
|
||||
}
|
||||
public static void buyCloak(String name) {
|
||||
try {
|
||||
Network.write("buy_cloak@cloak=" + name);
|
||||
} catch (Exception e) {
|
||||
SaturnClient.LOGGER.error("Request failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void buyHat(String name) {
|
||||
try {
|
||||
Network.write("buy_hat@hat=" + name);
|
||||
} catch (Exception e) {
|
||||
SaturnClient.LOGGER.error("Request failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,11 @@ public class SaturnParser {
|
||||
}
|
||||
}
|
||||
|
||||
public String getStringOrNull(String i) throws IOException {
|
||||
String val = params.get(i);
|
||||
return val;
|
||||
}
|
||||
|
||||
public boolean getBool(String i) throws IOException {
|
||||
String val = params.get(i);
|
||||
if (val != null) {
|
||||
|
||||
@@ -15,13 +15,14 @@ import java.util.Map;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
|
||||
public class ConfigManager {
|
||||
|
||||
private static File configFile = new File(
|
||||
SaturnClient.client.runDirectory,
|
||||
"saturn.json");
|
||||
private static Map<String, Map<String, Property<?>>> properties = new HashMap<>();
|
||||
private static JsonObject cachedThemeJson = null;
|
||||
|
||||
private Map<String, Property<?>> currentMap;
|
||||
private String namespace;
|
||||
|
||||
public ConfigManager(String namespace) {
|
||||
currentMap = new LinkedHashMap<>();
|
||||
@@ -31,21 +32,60 @@ public class ConfigManager {
|
||||
|
||||
public ConfigManager(ConfigManager config, String namespace) {
|
||||
currentMap = new LinkedHashMap<>();
|
||||
Property<Map<String, Property<?>>> namespaceProperty = new Property<>(currentMap,
|
||||
Property.PropertyType.NAMESPACE);
|
||||
Property<Map<String, Property<?>>> namespaceProperty = Property.namespace(currentMap);
|
||||
config.property(namespace, namespaceProperty);
|
||||
// Update the parent's state
|
||||
config.currentMap.put(namespace, namespaceProperty);
|
||||
System.out.println("Created sub-namespace: " + namespace);
|
||||
}
|
||||
|
||||
public void sub(String namespace) {
|
||||
Property<Map<String, Property<?>>> namespaceProperty = Property.namespace(currentMap);
|
||||
property(namespace, namespaceProperty);
|
||||
}
|
||||
|
||||
// Generic method to store any type of property
|
||||
public <T> Property<T> property(String name, Property<T> value) {
|
||||
System.out.println("Adding property: " + name);
|
||||
currentMap.put(name, value);
|
||||
loadProp(name, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> void loadProp(String name, Property<T> prop) {
|
||||
if (cachedThemeJson != null) {
|
||||
JsonElement element = cachedThemeJson.get(namespace);
|
||||
if (element != null && element.isJsonObject()) {
|
||||
JsonObject theme = element.getAsJsonObject();
|
||||
JsonElement value = theme.get(name);
|
||||
if (value != null && prop.matchesJson(value)) {
|
||||
switch (prop.getType()) {
|
||||
case BOOLEAN:
|
||||
((Property<Boolean>) prop).setValue(value.getAsBoolean());
|
||||
break;
|
||||
case INTEGER:
|
||||
((Property<Integer>) prop).setValue(value.getAsInt());
|
||||
break;
|
||||
case FLOAT:
|
||||
((Property<Float>) prop).setValue(value.getAsFloat());
|
||||
break;
|
||||
case STRING:
|
||||
((Property<String>) prop).setValue(value.getAsString());
|
||||
break;
|
||||
case HEX:
|
||||
((Property<Integer>) prop).setValue(value.getAsInt());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
load();
|
||||
}
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
try {
|
||||
SaturnClient.LOGGER.info("Starting to load config...");
|
||||
@@ -97,25 +137,17 @@ public class ConfigManager {
|
||||
Map<String, Property<?>> nestedProperties = p.getNamespaceValue();
|
||||
loadProperties(nestedConfig, nestedProperties);
|
||||
} else {
|
||||
// Handle regular properties
|
||||
switch (p.getType()) {
|
||||
case BOOLEAN:
|
||||
((Property<Boolean>) p).value = c.getAsBoolean();
|
||||
break;
|
||||
case INTEGER:
|
||||
((Property<Integer>) p).value = c.getAsInt();
|
||||
break;
|
||||
case FLOAT:
|
||||
((Property<Float>) p).value = c.getAsFloat();
|
||||
break;
|
||||
case STRING:
|
||||
((Property<String>) p).value = c.getAsString();
|
||||
break;
|
||||
case HEX:
|
||||
((Property<Integer>) p).value = c.getAsInt();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (p.value instanceof Integer) {
|
||||
((Property<Integer>) p).value = c.getAsInt();
|
||||
} else if (p.value instanceof String) {
|
||||
((Property<String>) p).value = c.getAsString();
|
||||
} else if (p.value instanceof Float) {
|
||||
((Property<Float>) p).value = c.getAsFloat();
|
||||
} else if (p.value instanceof Boolean) {
|
||||
((Property<Boolean>) p).value = c.getAsBoolean();
|
||||
} else {
|
||||
SaturnClient.LOGGER.warn(
|
||||
"Unknown property type for: " + propertyName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -161,36 +193,29 @@ public class ConfigManager {
|
||||
for (String propertyName : propertyMap.keySet()) {
|
||||
Property<?> property = propertyMap.get(propertyName);
|
||||
JsonElement propertyValue = null;
|
||||
|
||||
if (property.getType() == Property.PropertyType.NAMESPACE) {
|
||||
// Handle nested namespace
|
||||
JsonObject nestedConfig = new JsonObject();
|
||||
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) property.value;
|
||||
saveProperties(nestedConfig, nestedProperties);
|
||||
propertyValue = nestedConfig;
|
||||
} else {
|
||||
// Convert the property value based on its type
|
||||
switch (property.getType()) {
|
||||
case BOOLEAN:
|
||||
propertyValue = new JsonPrimitive((Boolean) property.value);
|
||||
break;
|
||||
case INTEGER:
|
||||
// Convert the property value based on its type
|
||||
switch (property.getType()) {
|
||||
case NAMESPACE:
|
||||
// Handle nested namespace
|
||||
JsonObject nestedConfig = new JsonObject();
|
||||
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) property.value;
|
||||
saveProperties(nestedConfig, nestedProperties);
|
||||
propertyValue = nestedConfig;
|
||||
break;
|
||||
default:
|
||||
if (property.value instanceof Integer) {
|
||||
propertyValue = new JsonPrimitive((Integer) property.value);
|
||||
break;
|
||||
case FLOAT:
|
||||
propertyValue = new JsonPrimitive((Float) property.value);
|
||||
break;
|
||||
case STRING:
|
||||
} else if (property.value instanceof String) {
|
||||
propertyValue = new JsonPrimitive((String) property.value);
|
||||
break;
|
||||
case HEX:
|
||||
propertyValue = new JsonPrimitive((Integer) property.value);
|
||||
break;
|
||||
default:
|
||||
} else if (property.value instanceof Float) {
|
||||
propertyValue = new JsonPrimitive((Float) property.value);
|
||||
} else if (property.value instanceof Boolean) {
|
||||
propertyValue = new JsonPrimitive((Boolean) property.value);
|
||||
} else {
|
||||
SaturnClient.LOGGER.warn(
|
||||
"Unknown property type for: " + propertyName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (propertyValue != null) {
|
||||
|
||||
@@ -2,6 +2,9 @@ package org.saturnclient.saturnclient.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
@@ -13,62 +16,100 @@ public class Property<T> {
|
||||
FLOAT,
|
||||
STRING,
|
||||
HEX,
|
||||
NAMESPACE
|
||||
NAMESPACE,
|
||||
SELECT,
|
||||
KEYBINDING,
|
||||
}
|
||||
|
||||
public T value;
|
||||
public boolean isReset = false;
|
||||
private T defaultValue;
|
||||
private String[] availableValues;
|
||||
private PropertyType type;
|
||||
private boolean wasPressedLastTick = false;
|
||||
|
||||
public Property(T value) {
|
||||
this.value = value;
|
||||
this.defaultValue = value;
|
||||
if (value instanceof Boolean) {
|
||||
type = PropertyType.BOOLEAN;
|
||||
} else if (value instanceof Integer) {
|
||||
type = PropertyType.INTEGER;
|
||||
} else if (value instanceof Float) {
|
||||
type = PropertyType.FLOAT;
|
||||
} else if (value instanceof String) {
|
||||
type = PropertyType.STRING;
|
||||
} else if (valueIsNamespace(value)) {
|
||||
type = PropertyType.NAMESPACE;
|
||||
}
|
||||
}
|
||||
|
||||
public Property(T value, PropertyType type) {
|
||||
private Property(T value, PropertyType type) {
|
||||
this.value = value;
|
||||
this.defaultValue = value;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public boolean getBool() {
|
||||
public static <T> Property<T> from(T value) {
|
||||
if (value instanceof Boolean) {
|
||||
return (boolean) value;
|
||||
return new Property<>(value, PropertyType.BOOLEAN);
|
||||
} else if (value instanceof Integer) {
|
||||
return new Property<>(value, PropertyType.INTEGER);
|
||||
} else if (value instanceof Float) {
|
||||
return new Property<>(value, PropertyType.FLOAT);
|
||||
} else if (value instanceof String) {
|
||||
return new Property<>(value, PropertyType.STRING);
|
||||
} else if (valueIsNamespace(value)) {
|
||||
return new Property<>(value, PropertyType.NAMESPACE);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
throw new IllegalStateException("Property does not contain a boolean");
|
||||
}
|
||||
|
||||
public int getInt() {
|
||||
if (value instanceof Integer) {
|
||||
return (int) value;
|
||||
}
|
||||
throw new IllegalStateException("Property does not contain an int");
|
||||
public static Property<Integer> font(int value) {
|
||||
return select(value, "Default", "Inter", "Inter bold");
|
||||
}
|
||||
|
||||
public float getFloat() {
|
||||
if (value instanceof Float) {
|
||||
return (float) value;
|
||||
}
|
||||
throw new IllegalStateException("Property does not contain a float");
|
||||
public static Property<Integer> select(Integer value, String... availableValues) {
|
||||
Property<Integer> property = new Property<>(value, PropertyType.SELECT);
|
||||
property.availableValues = availableValues;
|
||||
return property;
|
||||
}
|
||||
|
||||
public String getString() {
|
||||
if (value instanceof String) {
|
||||
return (String) value;
|
||||
public static Property<Map<String, Property<?>>> namespace(Map<String, Property<?>> value) {
|
||||
return new Property<>(value, PropertyType.NAMESPACE);
|
||||
}
|
||||
|
||||
public static Property<Boolean> bool(boolean value) {
|
||||
return new Property<>(value, PropertyType.BOOLEAN);
|
||||
}
|
||||
|
||||
public static Property<Integer> integer(int value) {
|
||||
return new Property<>(value, PropertyType.INTEGER);
|
||||
}
|
||||
|
||||
public static Property<Float> floatProp(float value) {
|
||||
return new Property<>(value, PropertyType.FLOAT);
|
||||
}
|
||||
|
||||
public static Property<String> string(String value) {
|
||||
return new Property<>(value, PropertyType.STRING);
|
||||
}
|
||||
|
||||
public static Property<Integer> color(int value) {
|
||||
return new Property<>(value, PropertyType.HEX);
|
||||
}
|
||||
|
||||
public static Property<Integer> keybinding(int value) {
|
||||
return new Property<>(value, PropertyType.KEYBINDING);
|
||||
}
|
||||
|
||||
public void next() {
|
||||
if ((Integer) value < availableValues.length-1) setValue((Integer)value+1);
|
||||
else setValue(0);
|
||||
}
|
||||
|
||||
public void prev() {
|
||||
if ((Integer) value > 0) setValue((Integer)value-1);
|
||||
else setValue(availableValues.length - 1);
|
||||
}
|
||||
|
||||
public void setSelection(int selection) {
|
||||
if (selection >= 0 && selection < availableValues.length && type == PropertyType.SELECT) {
|
||||
setValue(selection);
|
||||
}
|
||||
}
|
||||
|
||||
public String getSelection() {
|
||||
if (type == PropertyType.SELECT) {
|
||||
return availableValues[(Integer) value];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
throw new IllegalStateException("Property does not contain a string");
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
@@ -154,4 +195,20 @@ public class Property<T> {
|
||||
public NamedProperty<T> named(String name) {
|
||||
return new NamedProperty<>(name, this);
|
||||
}
|
||||
|
||||
public boolean isKeyPressed() {
|
||||
return (Integer) value == -1 ? false : GLFW.glfwGetKey(SaturnClient.client.getWindow().getHandle(), (Integer) (Object) value) == GLFW.GLFW_PRESS;
|
||||
}
|
||||
|
||||
public boolean wasKeyPressed() {
|
||||
long window = SaturnClient.client.getWindow().getHandle();
|
||||
int key = (Integer) value;
|
||||
|
||||
boolean isPressed = key != -1 && GLFW.glfwGetKey(window, key) == GLFW.GLFW_PRESS;
|
||||
|
||||
boolean wasJustPressed = isPressed && !wasPressedLastTick;
|
||||
wasPressedLastTick = isPressed;
|
||||
|
||||
return wasJustPressed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ public class ThemeManager {
|
||||
SaturnClient.client.runDirectory,
|
||||
"saturn.theme.json");
|
||||
private static Map<String, Map<String, Property<?>>> properties = new HashMap<>();
|
||||
private static JsonObject cachedThemeJson = null;
|
||||
|
||||
// private Map<String, Map<String, Property<?>>> states;
|
||||
private Map<String, Property<?>> currentStyling;
|
||||
@@ -43,33 +44,86 @@ public class ThemeManager {
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
this.state = state;
|
||||
if (this.state != null) {
|
||||
for (Map.Entry<String, Property<?>> tProp : properties.get(namespace+"@"+state).entrySet()) {
|
||||
currentStyling.get(tProp.getKey()).setValue(tProp.getValue().value);
|
||||
}
|
||||
} else {
|
||||
for (Map.Entry<String, Property<?>> tProp : properties.get(namespace).entrySet()) {
|
||||
Property<?> p = currentStyling.get(tProp.getKey());
|
||||
if (p != null) p.setValue(tProp.getValue().value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state != null) {
|
||||
for (Map.Entry<String, Property<?>> tProp : properties.get(namespace+"@"+state).entrySet()) {
|
||||
currentStyling.get(tProp.getKey()).setValue(tProp.getValue().value);
|
||||
}
|
||||
} else {
|
||||
for (Map.Entry<String, Property<?>> tProp : properties.get(namespace).entrySet()) {
|
||||
currentStyling.get(tProp.getKey()).setValue(tProp.getValue().value);
|
||||
public void applyState(String state) {
|
||||
if (this.state != null) {
|
||||
for (Map.Entry<String, Property<?>> tProp : properties.get(namespace+"@"+state).entrySet()) {
|
||||
Property<?> p = currentStyling.get(tProp.getKey());
|
||||
Property<?> currProp = properties.get(namespace).get(tProp.getKey());
|
||||
if (currProp != null && p.value.equals(currProp.value)) {
|
||||
p.setValue(tProp.getValue().value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setState(state);
|
||||
}
|
||||
}
|
||||
|
||||
// Generic method to store any type of property
|
||||
public <T> Property<T> property(String name, Property<T> prop) {
|
||||
for (String state : states) {
|
||||
properties.get(namespace+"@"+state).put(name, new Property<T>(prop.value));
|
||||
Property<?> property = Property.from(prop.value);
|
||||
properties.get(namespace+"@"+state).put(name, property);
|
||||
loadProp(state, name, property);
|
||||
}
|
||||
|
||||
properties.get(namespace).put(name, new Property<T>(prop.value));
|
||||
loadProp(null, name, prop);
|
||||
properties.get(namespace).put(name, Property.from(prop.value));
|
||||
currentStyling.put(name, prop);
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
public <T> void propertyStateDefault(String state, String name, T value) {
|
||||
properties.get(namespace+"@"+state).get(name).setValue(value, value); // sets the current and default value
|
||||
Property<?> prop = properties.get(namespace+"@"+state).get(name);
|
||||
prop.setValue(value, value); // sets the current and default value
|
||||
loadProp(state, name, prop);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> void loadProp(String state, String name, Property<T> prop) {
|
||||
if (cachedThemeJson == null) {
|
||||
load();
|
||||
}
|
||||
|
||||
JsonElement element = cachedThemeJson.get(state != null ? namespace+"@"+state : namespace);
|
||||
if (element != null && element.isJsonObject()) {
|
||||
JsonObject theme = element.getAsJsonObject();
|
||||
JsonElement value = theme.get(name);
|
||||
if (value != null && prop.matchesJson(value)) {
|
||||
switch (prop.getType()) {
|
||||
case BOOLEAN:
|
||||
((Property<Boolean>) prop).setValue(value.getAsBoolean());
|
||||
break;
|
||||
case INTEGER:
|
||||
((Property<Integer>) prop).setValue(value.getAsInt());
|
||||
break;
|
||||
case FLOAT:
|
||||
((Property<Float>) prop).setValue(value.getAsFloat());
|
||||
break;
|
||||
case STRING:
|
||||
((Property<String>) prop).setValue(value.getAsString());
|
||||
break;
|
||||
case HEX:
|
||||
((Property<Integer>) prop).setValue(value.getAsInt());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
@@ -80,74 +134,15 @@ public class ThemeManager {
|
||||
Files.write(themeFile.toPath(), "{}".getBytes());
|
||||
}
|
||||
|
||||
JsonObject jsonObject = JsonParser.parseString(
|
||||
new String(Files.readAllBytes(themeFile.toPath()))).getAsJsonObject();
|
||||
cachedThemeJson = JsonParser.parseString(
|
||||
new String(Files.readAllBytes(themeFile.toPath()))).getAsJsonObject();
|
||||
|
||||
for (String namespace : properties.keySet()) {
|
||||
JsonElement themeElement = jsonObject.get(namespace);
|
||||
|
||||
if (themeElement == null)
|
||||
continue;
|
||||
|
||||
JsonObject theme = jsonObject.get(namespace).getAsJsonObject();
|
||||
|
||||
if (theme == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<String, Property<?>> propertyMap = properties.get(namespace);
|
||||
loadProperties(theme, propertyMap);
|
||||
}
|
||||
SaturnClient.LOGGER.info("Theme loaded");
|
||||
} catch (IOException e) {
|
||||
SaturnClient.LOGGER.error("Error reading the theme file", e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void loadProperties(JsonObject theme, Map<String, Property<?>> propertyMap) {
|
||||
for (String propertyName : propertyMap.keySet()) {
|
||||
JsonElement c = theme.get(propertyName);
|
||||
|
||||
if (c == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Property<?> p = propertyMap.get(propertyName);
|
||||
if (p.matchesJson(c)) {
|
||||
if (p.getType() == Property.PropertyType.NAMESPACE) {
|
||||
// Handle nested namespace
|
||||
JsonObject nestedTheme = c.getAsJsonObject();
|
||||
Map<String, Property<?>> nestedProperties = p.getNamespaceValue();
|
||||
loadProperties(nestedTheme, nestedProperties);
|
||||
} else {
|
||||
// Handle regular properties
|
||||
switch (p.getType()) {
|
||||
case BOOLEAN:
|
||||
((Property<Boolean>) p).value = c.getAsBoolean();
|
||||
break;
|
||||
case INTEGER:
|
||||
((Property<Integer>) p).value = c.getAsInt();
|
||||
break;
|
||||
case FLOAT:
|
||||
((Property<Float>) p).value = c.getAsFloat();
|
||||
break;
|
||||
case STRING:
|
||||
((Property<String>) p).value = c.getAsString();
|
||||
break;
|
||||
case HEX:
|
||||
((Property<Integer>) p).value = c.getAsInt();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SaturnClient.LOGGER.warn(
|
||||
"Property does not match JSON: " + propertyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void save() {
|
||||
try {
|
||||
SaturnClient.LOGGER.info("Starting to save theme...");
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.saturnclient.saturnclient.cosmetics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Emotes {
|
||||
public static List<String> availableEmotes = new ArrayList<>();
|
||||
|
||||
public static void initialize() {
|
||||
availableEmotes.add("tpose");
|
||||
availableEmotes.add("back_flip");
|
||||
availableEmotes.add("facepalm");
|
||||
availableEmotes.add("cry");
|
||||
availableEmotes.add("giga_chad");
|
||||
availableEmotes.add("front_flip");
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ public class HatFeatureRenderer extends FeatureRenderer<PlayerEntityRenderState,
|
||||
PlayerEntityRenderState state, float limbAngle, float limbDistance) {
|
||||
ItemStack headItem = state.equippedHeadStack;
|
||||
String uuid = Auth.playerNames.get(state.name);
|
||||
if (headItem.isEmpty() && uuid != null) {
|
||||
if (headItem.isEmpty() && uuid != null && !state.invisible) {
|
||||
SaturnPlayer player = Auth.players.get(uuid);
|
||||
if (player == null || player.hat == null || player.hat.isEmpty()) {
|
||||
return;
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.saturnclient.saturnclient.auth.SaturnPlayer;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
|
||||
public class Hats {
|
||||
public static final String[] ALL_HATS = { "horns_black", "horns_white", "halo", "halo_black" };
|
||||
public static List<String> availableHats = new ArrayList<>();
|
||||
|
||||
public static void initialize() {
|
||||
@@ -15,7 +16,6 @@ public class Hats {
|
||||
public static void setHat(String uuid, String hatName) {
|
||||
setHatSilent(uuid, hatName);
|
||||
Auth.setHat(hatName);
|
||||
Auth.sendReload();
|
||||
}
|
||||
|
||||
public static void setHatSilent(String uuid, String hatName) {
|
||||
|
||||
@@ -20,7 +20,8 @@ import org.saturnclient.saturnclient.SaturnClient;
|
||||
* Originally created by IIpho3nix and modified for Saturn Client by leo.
|
||||
*/
|
||||
public class Cloaks {
|
||||
private static final String[] ANIMATED_CLOAKS = { "glitch" };
|
||||
public static final String[] ALL_CLOAKS = { "glitch", "mercedes_flow", "crimson_mark", };
|
||||
private static final String[] ANIMATED_CLOAKS = { "glitch", "mercedes_flow" };
|
||||
|
||||
private static final String CLOAKS_RESOURCE_PATH = "assets/saturnclient/textures/cloaks/";
|
||||
public static final List<String> availableCloaks = new ArrayList<>();
|
||||
@@ -44,10 +45,20 @@ public class Cloaks {
|
||||
public static void setCloak(String uuid, String cloakName) {
|
||||
Auth.setCloak(cloakName);
|
||||
setCloakSilent(uuid, cloakName);
|
||||
Auth.sendReload();
|
||||
SaturnClient.LOGGER.info("Cloak set to " + cloakName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets cloak of the current player
|
||||
*
|
||||
* @param cloakName Name of the cloak file to load
|
||||
*/
|
||||
public static void setCloak(String cloakName) {
|
||||
if (availableCloaks.contains(cloakName)) {
|
||||
setCloak(Auth.uuid, cloakName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles loading and caching of a new cloak texture, without connecting to the
|
||||
* server.
|
||||
@@ -101,20 +112,25 @@ public class Cloaks {
|
||||
List<AnimatedCloakData> animatedFrames = new ArrayList<>();
|
||||
for (int i = 0; i < frameCount; i++) {
|
||||
String frameId = fileName.replace(".gif", "") + "_frame_" + i;
|
||||
Identifier frameIdentifier = Identifier.of(SaturnClient.MOD_ID, "cloaks_" + frameId);
|
||||
IdentifierUtils.registerBufferedImageTexture(frameIdentifier, frames.get(i));
|
||||
Identifier frameIdentifier = Identifier.of(SaturnClient.MOD_ID,
|
||||
"cloaks_" + frameId);
|
||||
IdentifierUtils.registerBufferedImageTexture(frameIdentifier,
|
||||
frames.get(i));
|
||||
animatedFrames.add(new AnimatedCloakData(frameIdentifier, delays.get(i)));
|
||||
}
|
||||
animatedCloaks.put(uuid, animatedFrames);
|
||||
lastFrameTime.put(uuid, System.currentTimeMillis());
|
||||
SaturnClient.LOGGER.info("Loaded " + frames.size() + " frames for animated cloak: " + fileName);
|
||||
SaturnClient.LOGGER.info(
|
||||
"Loaded " + frames.size() + " frames for animated cloak: " + fileName);
|
||||
} catch (Exception e) {
|
||||
SaturnClient.LOGGER.error("Failed to register animated cloak textures: " + fileName, e);
|
||||
SaturnClient.LOGGER
|
||||
.error("Failed to register animated cloak textures: " + fileName, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (IOException e) {
|
||||
SaturnClient.LOGGER.error("Failed to load animated cloak from resources: " + player.cloak + ".gif", e);
|
||||
SaturnClient.LOGGER
|
||||
.error("Failed to load animated cloak from resources: " + player.cloak + ".gif", e);
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
|
||||
@@ -3,12 +3,17 @@ package org.saturnclient.saturnclient.event;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
// import net.minecraft.client.option.Perspective;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
|
||||
// import org.saturnclient.modules.mods.FreeLook;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
import org.saturnclient.ui2.screens.EmoteWheel;
|
||||
import org.saturnclient.ui2.screens.ShiftMenu;
|
||||
// import org.saturnclient.saturnclient.menus.SaturnMenu;
|
||||
|
||||
import dev.kosmx.playerAnim.api.layered.AnimationStack;
|
||||
import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationAccess;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
/**
|
||||
@@ -21,55 +26,30 @@ public class KeyInputHandler {
|
||||
private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT;
|
||||
private static KeyBinding mainMenuKeyBinding;
|
||||
|
||||
// private static final String FREELOOK_KEY_ID = "key.saturnclient.freelook";
|
||||
// private static final int FREELOOK_KEY = GLFW.GLFW_KEY_M;
|
||||
// private static KeyBinding freelookKeyBinding;
|
||||
|
||||
/**
|
||||
* Registers all keybindings and their associated event handlers.
|
||||
* Should be called during mod initialization.
|
||||
*/
|
||||
public static void register() {
|
||||
// Register the main menu key binding
|
||||
mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding(
|
||||
MAIN_MENU_KEY_ID,
|
||||
InputUtil.Type.KEYSYM,
|
||||
DEFAULT_MENU_KEY,
|
||||
KEY_CATEGORY));
|
||||
|
||||
// freelookKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding(
|
||||
// FREELOOK_KEY_ID,
|
||||
// InputUtil.Type.KEYSYM,
|
||||
// FREELOOK_KEY,
|
||||
// KEY_CATEGORY));
|
||||
|
||||
// Register the event handler for the main menu key
|
||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||
if (mainMenuKeyBinding.wasPressed()) {
|
||||
client.setScreen(new ShiftMenu());
|
||||
}
|
||||
// else if (freelookKeyBinding.wasPressed() && FreeLook.enabled.value && FreeLook.toggle.value) {
|
||||
// FreeLook.isFreeLooking = !FreeLook.isFreeLooking;
|
||||
// if (FreeLook.isFreeLooking) {
|
||||
// FreeLook.lastPerspective = client.options.getPerspective();
|
||||
// client.options.setPerspective(Perspective.THIRD_PERSON_BACK);
|
||||
// } else if (FreeLook.lastPerspective != null) {
|
||||
// client.options.setPerspective(FreeLook.lastPerspective);
|
||||
// FreeLook.lastPerspective = null;
|
||||
// }
|
||||
// } else if (FreeLook.enabled.value && !FreeLook.toggle.value) {
|
||||
// if (freelookKeyBinding.isPressed()) {
|
||||
// if (!FreeLook.isFreeLooking) {
|
||||
// FreeLook.lastPerspective = client.options.getPerspective();
|
||||
// client.options.setPerspective(Perspective.THIRD_PERSON_BACK);
|
||||
// FreeLook.isFreeLooking = true;
|
||||
// }
|
||||
// } else if (FreeLook.isFreeLooking && FreeLook.lastPerspective != null) {
|
||||
// client.options.setPerspective(FreeLook.lastPerspective);
|
||||
// FreeLook.isFreeLooking = false;
|
||||
// FreeLook.lastPerspective = null;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (SaturnClientConfig.openEmoteWheel.wasKeyPressed()) {
|
||||
client.setScreen(new EmoteWheel());
|
||||
}
|
||||
|
||||
if (SaturnClient.client.player != null && SaturnClient.client.player.isSneaking()) {
|
||||
AnimationStack animationStack = PlayerAnimationAccess.getPlayerAnimLayer(SaturnClient.client.player);
|
||||
if (animationStack.isActive() && animationStack.getPriority() == 1000) {
|
||||
animationStack.removeLayer(1000);
|
||||
Auth.emote("");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
package org.saturnclient.saturnclient.menus;
|
||||
|
||||
import net.minecraft.text.Text;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.Textures;
|
||||
import org.saturnclient.ui.components.SkinPreview;
|
||||
import org.saturnclient.ui.widgets.SaturnClickableImage;
|
||||
import org.saturnclient.ui.widgets.SaturnClickableSprite;
|
||||
import org.saturnclient.ui.widgets.SaturnImage;
|
||||
import org.saturnclient.ui.widgets.SaturnInputBox;
|
||||
import org.saturnclient.ui.widgets.SaturnScroll;
|
||||
import org.saturnclient.ui.widgets.SaturnSprite;
|
||||
|
||||
public class CloaksMenu extends SaturnUi {
|
||||
|
||||
private SaturnScroll scroll;
|
||||
private Property<String> search = new Property<>("");
|
||||
|
||||
public CloaksMenu() {
|
||||
super(Text.of("Cloaks Menu"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
int rectWidth = 330;
|
||||
int rectHeight = 228;
|
||||
int rectX = (width - rectWidth) / 2;
|
||||
int rectY = (height - rectHeight + 15) / 2;
|
||||
|
||||
draw(
|
||||
new SaturnSprite(Textures.SETTINGS_BG)
|
||||
.setX(rectX)
|
||||
.setY(rectY)
|
||||
.setWidth(rectWidth)
|
||||
.setHeight(rectHeight)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
int tabsX = (width - 43) / 2;
|
||||
int tabsY = rectY - 17;
|
||||
|
||||
draw(
|
||||
new SaturnSprite(Textures.RECT)
|
||||
.setX(tabsX)
|
||||
.setY(tabsY)
|
||||
.setWidth(43)
|
||||
.setHeight(15)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
draw(
|
||||
new SaturnInputBox(search, rectX + rectWidth - 72, tabsY, 70).onUpdate(() -> {
|
||||
scroll.clear();
|
||||
drawItems(rectX, rectY, rectWidth, rectHeight);
|
||||
})
|
||||
.setHeight(15)
|
||||
.setWidth(72)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
int tabSize = 9;
|
||||
tabsX = (width - tabSize) / 2;
|
||||
draw(
|
||||
new SaturnClickableImage(Textures.HAT, () -> {
|
||||
client.setScreen(new HatsMenu());
|
||||
})
|
||||
.setX(tabsX)
|
||||
.setY(tabsY + 4)
|
||||
.setWidth(tabSize)
|
||||
.setHeight(7)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
draw(
|
||||
new SaturnClickableImage(Textures.CLOAK, () -> {
|
||||
})
|
||||
.setSelected(true)
|
||||
.setX(tabsX - 12)
|
||||
.setY(tabsY + 3)
|
||||
.setWidth(tabSize)
|
||||
.setHeight(tabSize)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
draw(
|
||||
new SaturnClickableImage(Textures.SEARCH, () -> {
|
||||
System.out.println("Pressed");
|
||||
})
|
||||
.setX(tabsX + 12)
|
||||
.setY(tabsY + 3)
|
||||
.setWidth(tabSize)
|
||||
.setHeight(tabSize)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
scroll = new SaturnScroll();
|
||||
|
||||
drawItems(rectX, rectY, rectWidth, rectHeight);
|
||||
|
||||
draw(scroll
|
||||
.setX(rectX + 17)
|
||||
.setY(rectY + 10)
|
||||
.setWidth(rectWidth - 17)
|
||||
.setHeight(rectHeight - 10)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
draw(new SkinPreview()
|
||||
.setScale(3.0f)
|
||||
.setX((rectX + rectWidth) - 180)
|
||||
.setY(rectY + 8)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
super.init();
|
||||
}
|
||||
|
||||
private void drawItems(int rectX, int rectY, int rectWidth, int rectHeight) {
|
||||
int cloakWidth = 28;
|
||||
int cloakHeight = 61;
|
||||
|
||||
int modX = 0;
|
||||
int modY = 0;
|
||||
int col = 0;
|
||||
|
||||
String[] searchTokens = search.value.toLowerCase().split("\\ ");
|
||||
|
||||
outer: for (String cloak : Cloaks.availableCloaks) {
|
||||
for (String searchToken : searchTokens) {
|
||||
if (!cloak.contains(searchToken)) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
scroll.draw(
|
||||
new SaturnClickableSprite(Textures.BUTTON_BORDER, () -> {
|
||||
Cloaks.setCloak(Auth.uuid, cloak);
|
||||
})
|
||||
.setX(modX)
|
||||
.setY(modY)
|
||||
.setWidth(cloakWidth + 6)
|
||||
.setHeight(cloakHeight + 6));
|
||||
|
||||
scroll.draw(
|
||||
new SaturnImage(Textures.getCloakPreview(cloak))
|
||||
.setX(modX + 3)
|
||||
.setY(modY + 3)
|
||||
.setWidth(cloakWidth)
|
||||
.setHeight(cloakHeight));
|
||||
|
||||
col++;
|
||||
|
||||
if (col < 4) {
|
||||
modX += cloakWidth + 21;
|
||||
} else {
|
||||
modX = 0;
|
||||
modY += cloakHeight + 20;
|
||||
col = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
package org.saturnclient.saturnclient.menus;
|
||||
|
||||
import java.util.Map;
|
||||
import net.minecraft.text.Text;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
import org.saturnclient.ui.Textures;
|
||||
import org.saturnclient.ui.components.SaturnFloat;
|
||||
import org.saturnclient.ui.components.SaturnHex;
|
||||
import org.saturnclient.ui.components.SaturnInteger;
|
||||
import org.saturnclient.ui.components.SaturnString;
|
||||
import org.saturnclient.ui.components.SaturnToggle;
|
||||
import org.saturnclient.ui.widgets.SaturnImageButton;
|
||||
import org.saturnclient.ui.widgets.SaturnScroll;
|
||||
import org.saturnclient.ui.widgets.SaturnSprite;
|
||||
import org.saturnclient.ui.widgets.SaturnText;
|
||||
|
||||
public class ConfigEditor extends SaturnUi {
|
||||
|
||||
private ConfigManager config;
|
||||
|
||||
public ConfigEditor(ConfigManager config) {
|
||||
super(Text.of("Config editor"));
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
int rectWidth = 330;
|
||||
int rectHeight = 228;
|
||||
int rectX = (width - rectWidth) / 2;
|
||||
int rectY = (height - rectHeight + 15) / 2;
|
||||
|
||||
draw(
|
||||
new SaturnSprite(Textures.SETTINGS_BG)
|
||||
.setX(rectX)
|
||||
.setY(rectY)
|
||||
.setWidth(rectWidth)
|
||||
.setHeight(rectHeight)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
draw(
|
||||
new SaturnImageButton(Textures.CLOSE, 9, 9, () -> {
|
||||
this.close();
|
||||
})
|
||||
.setX(rectX)
|
||||
.setY(rectY - 15)
|
||||
.setWidth(13)
|
||||
.setHeight(13)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
SaturnScroll configScroll = new SaturnScroll();
|
||||
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
|
||||
drawProperties(configScroll, config.getProperties(), rectWidth, row, col);
|
||||
|
||||
draw(
|
||||
configScroll
|
||||
.setX(rectX + 17)
|
||||
.setY(rectY + 10)
|
||||
.setWidth(rectWidth - 17)
|
||||
.setHeight(rectHeight - 10)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
super.init();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private int drawProperties(SaturnScroll configScroll, Map<String, Property<?>> properties, int rectWidth,
|
||||
int row, int col) {
|
||||
int totalRows = row;
|
||||
for (Map.Entry<String, Property<?>> propEntry : properties.entrySet()) {
|
||||
Property<?> prop = propEntry.getValue();
|
||||
String propName = propEntry.getKey();
|
||||
|
||||
boolean full = isFull(prop);
|
||||
|
||||
if (full && col > 0) {
|
||||
col = 0;
|
||||
totalRows++;
|
||||
}
|
||||
|
||||
int modX = ((rectWidth / 2) - 17) * col;
|
||||
int modY = 14 * totalRows;
|
||||
|
||||
switch (prop.getType()) {
|
||||
case BOOLEAN:
|
||||
configScroll.draw(
|
||||
new SaturnToggle((Property<Boolean>) prop)
|
||||
.setX(modX)
|
||||
.setY(modY));
|
||||
configScroll.draw(
|
||||
new SaturnText(
|
||||
propName.substring(0, 1).toUpperCase() +
|
||||
propName.substring(1))
|
||||
.setX(modX + 18)
|
||||
.setY(modY)
|
||||
.setScale(0.8f));
|
||||
break;
|
||||
case INTEGER:
|
||||
configScroll.draw(
|
||||
new SaturnText(
|
||||
propName.substring(0, 1).toUpperCase() +
|
||||
propName.substring(1))
|
||||
.setX(modX)
|
||||
.setY(modY)
|
||||
.setScale(0.8f));
|
||||
|
||||
configScroll.draw(
|
||||
new SaturnInteger(
|
||||
(Property<Integer>) prop,
|
||||
(rectWidth / 2) - 17,
|
||||
modY,
|
||||
70));
|
||||
|
||||
configScroll.draw(resetButton(prop, modX, modY));
|
||||
break;
|
||||
case FLOAT:
|
||||
configScroll.draw(
|
||||
new SaturnText(
|
||||
propName.substring(0, 1).toUpperCase() +
|
||||
propName.substring(1))
|
||||
.setX(modX)
|
||||
.setY(modY)
|
||||
.setScale(0.8f));
|
||||
|
||||
configScroll.draw(
|
||||
new SaturnFloat(
|
||||
(Property<Float>) prop,
|
||||
(rectWidth / 2) - 17,
|
||||
modY,
|
||||
70));
|
||||
|
||||
configScroll.draw(resetButton(prop, modX, modY));
|
||||
break;
|
||||
case STRING:
|
||||
configScroll.draw(
|
||||
new SaturnText(
|
||||
propName.substring(0, 1).toUpperCase() +
|
||||
propName.substring(1))
|
||||
.setX(modX)
|
||||
.setY(modY)
|
||||
.setScale(0.8f));
|
||||
|
||||
configScroll.draw(
|
||||
new SaturnString(
|
||||
(Property<String>) prop,
|
||||
(rectWidth / 2) - 17,
|
||||
modY,
|
||||
70));
|
||||
|
||||
configScroll.draw(resetButton(prop, modX, modY));
|
||||
break;
|
||||
case HEX:
|
||||
configScroll.draw(
|
||||
new SaturnText(
|
||||
propName.substring(0, 1).toUpperCase() +
|
||||
propName.substring(1))
|
||||
.setX(modX)
|
||||
.setY(modY)
|
||||
.setScale(0.8f));
|
||||
|
||||
configScroll.draw(
|
||||
new SaturnHex(
|
||||
(Property<Integer>) prop,
|
||||
(rectWidth / 2) - 17,
|
||||
modY,
|
||||
70));
|
||||
|
||||
configScroll.draw(resetButton(prop, modX, modY));
|
||||
break;
|
||||
case NAMESPACE:
|
||||
configScroll.draw(
|
||||
new SaturnText(
|
||||
propName.substring(0, 1).toUpperCase() +
|
||||
propName.substring(1))
|
||||
.setX(modX)
|
||||
.setY(modY)
|
||||
.setScale(0.8f));
|
||||
|
||||
// Recursively draw nested properties and update total rows
|
||||
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) prop.value;
|
||||
totalRows = drawProperties(configScroll, nestedProperties, rectWidth,
|
||||
totalRows + 1, 0);
|
||||
}
|
||||
|
||||
if (full) {
|
||||
totalRows++;
|
||||
} else {
|
||||
col++;
|
||||
if (col > 1) {
|
||||
col = 0;
|
||||
totalRows++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return totalRows;
|
||||
}
|
||||
|
||||
public static boolean isFull(Property<?> prop) {
|
||||
switch (prop.getType()) {
|
||||
case BOOLEAN:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
ConfigManager.save();
|
||||
super.close();
|
||||
}
|
||||
|
||||
public SaturnWidget resetButton(Property<?> prop, int modX, int modY) {
|
||||
int size = textRenderer.fontHeight - 1;
|
||||
return new SaturnImageButton(
|
||||
Textures.RESET,
|
||||
size,
|
||||
size,
|
||||
() -> {
|
||||
prop.reset();
|
||||
})
|
||||
.setX(modX + 209)
|
||||
.setY(modY)
|
||||
.setWidth(size + 3)
|
||||
.setHeight(size + 3);
|
||||
}
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
package org.saturnclient.saturnclient.menus;
|
||||
|
||||
import net.minecraft.text.Text;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
import org.saturnclient.saturnclient.cosmetics.Hats;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.Textures;
|
||||
import org.saturnclient.ui.components.SkinPreview;
|
||||
import org.saturnclient.ui.widgets.SaturnClickableImage;
|
||||
import org.saturnclient.ui.widgets.SaturnClickableSprite;
|
||||
import org.saturnclient.ui.widgets.SaturnImage;
|
||||
import org.saturnclient.ui.widgets.SaturnScroll;
|
||||
import org.saturnclient.ui.widgets.SaturnSprite;
|
||||
|
||||
public class HatsMenu extends SaturnUi {
|
||||
|
||||
public HatsMenu() {
|
||||
super(Text.of("Hats Menu"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
int rectWidth = 330;
|
||||
int rectHeight = 228;
|
||||
int rectX = (width - rectWidth) / 2;
|
||||
int rectY = (height - rectHeight + 15) / 2;
|
||||
|
||||
draw(
|
||||
new SaturnSprite(Textures.SETTINGS_BG)
|
||||
.setX(rectX)
|
||||
.setY(rectY)
|
||||
.setWidth(rectWidth)
|
||||
.setHeight(rectHeight)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
int tabsX = (width - 43) / 2;
|
||||
int tabsY = rectY - 17;
|
||||
|
||||
draw(
|
||||
new SaturnSprite(Textures.RECT)
|
||||
.setX(tabsX)
|
||||
.setY(tabsY)
|
||||
.setWidth(43)
|
||||
.setHeight(15)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
int tabSize = 9;
|
||||
tabsX = (width - tabSize) / 2;
|
||||
draw(
|
||||
new SaturnClickableImage(Textures.HAT, () -> {
|
||||
client.setScreen(new HatsMenu());
|
||||
})
|
||||
.setSelected(true)
|
||||
.setX(tabsX)
|
||||
.setY(tabsY + 4)
|
||||
.setWidth(tabSize)
|
||||
.setHeight(7)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
draw(
|
||||
new SaturnClickableImage(Textures.CLOAK, () -> {
|
||||
client.setScreen(new CloaksMenu());
|
||||
})
|
||||
.setX(tabsX - 12)
|
||||
.setY(tabsY + 3)
|
||||
.setWidth(tabSize)
|
||||
.setHeight(tabSize)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
draw(
|
||||
new SaturnClickableImage(Textures.SEARCH, () -> {
|
||||
System.out.println("Pressed");
|
||||
})
|
||||
.setX(tabsX + 12)
|
||||
.setY(tabsY + 3)
|
||||
.setWidth(tabSize)
|
||||
.setHeight(tabSize)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
int hatSize = 28;
|
||||
|
||||
int modX = 0;
|
||||
int modY = 0;
|
||||
int col = 0;
|
||||
|
||||
SaturnScroll modsScroll = new SaturnScroll();
|
||||
|
||||
for (String hat : Hats.availableHats) {
|
||||
modsScroll.draw(
|
||||
new SaturnClickableSprite(Textures.BUTTON_BORDER, () -> {
|
||||
Hats.setHat(Auth.uuid, hat);
|
||||
})
|
||||
.setX(modX)
|
||||
.setY(modY)
|
||||
.setWidth(hatSize + 6)
|
||||
.setHeight(hatSize + 6));
|
||||
|
||||
modsScroll.draw(
|
||||
new SaturnImage(Textures.getHatPreview(hat))
|
||||
.setX(modX + 3)
|
||||
.setY(modY + 3)
|
||||
.setWidth(hatSize)
|
||||
.setHeight(hatSize));
|
||||
|
||||
col++;
|
||||
|
||||
if (col < 4) {
|
||||
modX += hatSize + 21;
|
||||
} else {
|
||||
modX = 0;
|
||||
modY += hatSize + 20;
|
||||
col = 0;
|
||||
}
|
||||
}
|
||||
|
||||
draw(
|
||||
modsScroll
|
||||
.setX(rectX + 17)
|
||||
.setY(rectY + 10)
|
||||
.setWidth(rectWidth - 17)
|
||||
.setHeight(rectHeight - 10)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
draw(new SkinPreview()
|
||||
.setScale(3.0f)
|
||||
.setX((rectX + rectWidth) - 180)
|
||||
.setY(rectY + 8)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
super.init();
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,9 @@ import org.saturnclient.modules.ModDimensions;
|
||||
import org.saturnclient.modules.ModManager;
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -90,9 +92,11 @@ public class HudEditor extends Screen {
|
||||
@Override
|
||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
if (client.world == null && client.getCurrentServerEntry() == null) {
|
||||
SaturnUi.ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, 1.0F, delta);
|
||||
SaturnScreen.ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, 1.0F, delta);
|
||||
}
|
||||
|
||||
RenderScope scope = new RenderScope(context.getMatrices(), ((DrawContextAccessor) context).getVertexConsumers());
|
||||
|
||||
for (HudMod mod : hudMods) {
|
||||
ModDimensions dim = mod.getDimensions();
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
@@ -102,7 +106,7 @@ public class HudEditor extends Screen {
|
||||
matrices.scale(dim.scale.value, dim.scale.value, 1.0f);
|
||||
|
||||
// Render the mod
|
||||
mod.renderDummy(context);
|
||||
mod.renderDummy(scope);
|
||||
|
||||
matrices.pop();
|
||||
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
package org.saturnclient.saturnclient.menus;
|
||||
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import org.saturnclient.modules.ModManager;
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.Textures;
|
||||
import org.saturnclient.ui.components.SaturnModComp;
|
||||
import org.saturnclient.ui.widgets.SaturnClickableImage;
|
||||
import org.saturnclient.ui.widgets.SaturnInputBox;
|
||||
import org.saturnclient.ui.widgets.SaturnScroll;
|
||||
import org.saturnclient.ui.widgets.SaturnSprite;
|
||||
|
||||
public class ModMenu extends SaturnUi {
|
||||
|
||||
private SaturnScroll scroll;
|
||||
private Property<String> search = new Property<>("");
|
||||
|
||||
public ModMenu() {
|
||||
super(Text.literal("Mods"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
int rectWidth = 330;
|
||||
int rectHeight = 228;
|
||||
int rectX = (width - rectWidth) / 2;
|
||||
int rectY = (height - rectHeight + 15) / 2;
|
||||
|
||||
draw(
|
||||
new SaturnSprite(Textures.SETTINGS_BG)
|
||||
.setX(rectX)
|
||||
.setY(rectY)
|
||||
.setWidth(rectWidth)
|
||||
.setHeight(rectHeight)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
int tabsX = (width - 43) / 2;
|
||||
int tabsY = rectY - 17;
|
||||
|
||||
draw(
|
||||
new SaturnSprite(Textures.RECT)
|
||||
.setX(tabsX)
|
||||
.setY(tabsY)
|
||||
.setWidth(43)
|
||||
.setHeight(15)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
draw(
|
||||
new SaturnInputBox(search, rectX + rectWidth - 72, tabsY, 70).onUpdate(() -> {
|
||||
scroll.clear();
|
||||
drawItems(rectX, rectY, rectWidth, rectHeight);
|
||||
})
|
||||
.setHeight(15)
|
||||
.setWidth(72)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
int tabSize = 9;
|
||||
tabsX = (width - tabSize) / 2;
|
||||
draw(
|
||||
new SaturnClickableImage(Textures.SETTINGS, () -> {
|
||||
client.setScreen(new SaturnConfigEditor());
|
||||
})
|
||||
.setX(tabsX)
|
||||
.setY(tabsY + 3)
|
||||
.setWidth(tabSize)
|
||||
.setHeight(tabSize)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
draw(
|
||||
new SaturnClickableImage(Textures.MODS_TAB, () -> {
|
||||
})
|
||||
.setSelected(true)
|
||||
.setX(tabsX - 12)
|
||||
.setY(tabsY + 3)
|
||||
.setWidth(tabSize)
|
||||
.setHeight(tabSize)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
draw(
|
||||
new SaturnClickableImage(Textures.SEARCH, () -> {
|
||||
System.out.println("Pressed");
|
||||
})
|
||||
.setX(tabsX + 12)
|
||||
.setY(tabsY + 3)
|
||||
.setWidth(tabSize)
|
||||
.setHeight(tabSize)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
scroll = new SaturnScroll();
|
||||
|
||||
drawItems(rectX, rectY, rectWidth, rectHeight);
|
||||
|
||||
draw(scroll
|
||||
.setX(rectX + 17)
|
||||
.setY(rectY + 10)
|
||||
.setWidth(rectWidth - 17)
|
||||
.setHeight(rectHeight - 20)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
super.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
ConfigManager.save();
|
||||
super.close();
|
||||
}
|
||||
|
||||
private void drawItems(int rectX, int rectY, int rectWidth, int rectHeight) {
|
||||
int modX = 0;
|
||||
int modY = 0;
|
||||
int col = 0;
|
||||
|
||||
String[] searchTokens = search.value.toLowerCase().split("\\ ");
|
||||
|
||||
outer: for (Module mod : ModManager.MODS) {
|
||||
String modName = mod.getName().toLowerCase();
|
||||
for (String searchToken : searchTokens) {
|
||||
if (!modName.contains(searchToken)) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
scroll.draw(
|
||||
new SaturnModComp(mod)
|
||||
.setX(modX)
|
||||
.setY(modY)
|
||||
.setWidth(86)
|
||||
.setHeight(20));
|
||||
|
||||
col++;
|
||||
|
||||
if (col < 3) {
|
||||
modX += 86 + 18;
|
||||
} else {
|
||||
modX = 0;
|
||||
modY += 20 + 20;
|
||||
col = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package org.saturnclient.saturnclient.menus;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.ui.Textures;
|
||||
import org.saturnclient.ui.widgets.SaturnClickableImage;
|
||||
import org.saturnclient.ui.widgets.SaturnSprite;
|
||||
|
||||
public class SaturnConfigEditor extends ConfigEditor {
|
||||
|
||||
public SaturnConfigEditor() {
|
||||
super(SaturnClientConfig.config);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
int rectHeight = 228;
|
||||
int rectY = (height - rectHeight + 15) / 2;
|
||||
|
||||
int tabsX = (width - 43) / 2;
|
||||
int tabsY = rectY - 17;
|
||||
|
||||
draw(
|
||||
new SaturnSprite(Textures.RECT)
|
||||
.setX(tabsX)
|
||||
.setY(tabsY)
|
||||
.setWidth(43)
|
||||
.setHeight(15)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
int tabSize = 9;
|
||||
tabsX = (width - tabSize) / 2;
|
||||
draw(
|
||||
new SaturnClickableImage(Textures.SETTINGS, () -> {
|
||||
})
|
||||
.setSelected(true)
|
||||
.setX(tabsX)
|
||||
.setY(tabsY + 3)
|
||||
.setWidth(tabSize)
|
||||
.setHeight(tabSize)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
draw(
|
||||
new SaturnClickableImage(Textures.MODS_TAB, () -> {
|
||||
client.setScreen(new ModMenu());
|
||||
})
|
||||
.setX(tabsX - 12)
|
||||
.setY(tabsY + 3)
|
||||
.setWidth(tabSize)
|
||||
.setHeight(tabSize)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
draw(
|
||||
new SaturnClickableImage(Textures.SEARCH, () -> {
|
||||
System.out.println("Pressed");
|
||||
})
|
||||
.setX(tabsX + 12)
|
||||
.setY(tabsY + 3)
|
||||
.setWidth(tabSize)
|
||||
.setHeight(tabSize)
|
||||
.setAnimations(SaturnClientConfig.getAnimations()));
|
||||
|
||||
super.init();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.saturnclient.saturnclient.menus;
|
||||
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
|
||||
public class SaturnMenu extends SaturnScreen {
|
||||
public SaturnMenu() {
|
||||
super("Saturn Client");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ui() {
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package org.saturnclient.saturnclient.menus;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.Textures;
|
||||
import org.saturnclient.ui.animations.FadeIn;
|
||||
import org.saturnclient.ui.animations.Slide;
|
||||
import org.saturnclient.ui.widgets.SaturnButton;
|
||||
import org.saturnclient.ui.widgets.SaturnImage;
|
||||
import org.saturnclient.ui2.screens.ShiftMenu;
|
||||
|
||||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
|
||||
import net.minecraft.client.gui.screen.option.OptionsScreen;
|
||||
import net.minecraft.client.gui.screen.world.SelectWorldScreen;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public class SaturnTitleScreen extends SaturnUi {
|
||||
public SaturnTitleScreen() {
|
||||
super(Text.literal("Title Screen"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
blur = false;
|
||||
|
||||
int logoSize = 49;
|
||||
int bX = (width - 150) / 2;
|
||||
int bY = height / 2 - logoSize - 27;
|
||||
|
||||
draw(
|
||||
new SaturnImage(SaturnClientConfig.getLogo())
|
||||
.setX((width - logoSize) / 2)
|
||||
.setY(bY)
|
||||
.setWidth(logoSize)
|
||||
.setHeight(logoSize)
|
||||
.setAnimations(new Slide(3, 14)));
|
||||
|
||||
bY += 44;
|
||||
|
||||
draw(
|
||||
new SaturnImage(Textures.LOGO_TEXT)
|
||||
.setX((width - logoSize) / 2)
|
||||
.setY(bY)
|
||||
.setWidth(logoSize)
|
||||
.setHeight(8)
|
||||
.setAnimations(new FadeIn(3)));
|
||||
|
||||
bY += 15;
|
||||
|
||||
draw(new SaturnButton("SINGLEPLAYER", () -> {
|
||||
client.setScreen(new SelectWorldScreen(new SaturnTitleScreen()));
|
||||
}).setBold(true).setWidth(210).setHeight(26).setX(bX).setY(bY).setScale(0.69f));
|
||||
|
||||
bY += 20;
|
||||
|
||||
draw(new SaturnButton("MULTIPLAYER", () -> {
|
||||
client.setScreen(new MultiplayerScreen(new SaturnTitleScreen()));
|
||||
}).setBold(true).setWidth(210).setHeight(26).setX(bX).setY(bY).setScale(0.69f));
|
||||
|
||||
bY += 20;
|
||||
|
||||
draw(new SaturnButton("OPTIONS", () -> {
|
||||
client.setScreen(new OptionsScreen(new SaturnTitleScreen(), this.client.options));
|
||||
}).setBold(true).setWidth(103).setHeight(26).setX(bX).setY(bY).setScale(0.69f));
|
||||
|
||||
draw(new SaturnButton("QUIT", () -> {
|
||||
client.scheduleStop();
|
||||
}).setBold(true).setWidth(103).setHeight(26).setX(bX + 74).setY(bY).setScale(0.69f));
|
||||
|
||||
bY += 20;
|
||||
|
||||
draw(new SaturnButton("SATURN OPTIONS", () -> {
|
||||
client.setScreen(new ShiftMenu());
|
||||
}).setBold(true).setWidth(210).setHeight(26).setX(bX).setY(bY).setScale(0.69f));
|
||||
|
||||
super.init();
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package org.saturnclient.saturnclient.mixin;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.gui.hud.ChatHud;
|
||||
import net.minecraft.client.gui.hud.MessageIndicator;
|
||||
import net.minecraft.network.message.MessageSignatureData;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
@Mixin(ChatHud.class)
|
||||
public class SaturnReload {
|
||||
@Inject(method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;Lnet/minecraft/client/gui/hud/MessageIndicator;)V", at = @At("HEAD"), cancellable = true)
|
||||
public void onAddMessage(Text message, @Nullable MessageSignatureData signatureData,
|
||||
@Nullable MessageIndicator indicator, CallbackInfo ci) {
|
||||
String msg = message.toString();
|
||||
if (msg.contains("$SATURN_RELOAD")) {
|
||||
for (Map.Entry<String, String> player : Auth.playerNames.entrySet()) {
|
||||
String name = player.getKey();
|
||||
if (msg.contains(name)) {
|
||||
Auth.player(name, player.getValue());
|
||||
}
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.saturnclient.saturnclient.mixin;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.ui2.screens.TitleMenu;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.gui.screen.TitleScreen;
|
||||
|
||||
@Mixin(TitleScreen.class)
|
||||
public class TitleScreenMixin {
|
||||
@Inject(method = "init", at = @At("HEAD"), cancellable = true)
|
||||
private void onInit(CallbackInfo ci) {
|
||||
if (SaturnClientConfig.saturnTitleScreen.value) {
|
||||
SaturnClient.client.setScreen(new TitleMenu());
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.saturnclient.ui;
|
||||
|
||||
public class SaturnAnimation {
|
||||
|
||||
public int delay = 0;
|
||||
public int lastTick = 0;
|
||||
|
||||
public void init(SaturnWidget widget) {}
|
||||
|
||||
public boolean run(SaturnWidget widget, int tick) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,322 +0,0 @@
|
||||
package org.saturnclient.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gl.PostEffectProcessor;
|
||||
import net.minecraft.client.gui.CubeMapRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.RotatingCubeMapRenderer;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.render.DefaultFramebufferSet;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.util.Pool;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.MutableText;
|
||||
import net.minecraft.text.Style;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
public class SaturnUi extends Screen {
|
||||
|
||||
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
private final Pool pool = new Pool(3);
|
||||
private float f = 0.0f;
|
||||
public boolean blur = true;
|
||||
public boolean titleBackground = false;
|
||||
public List<SaturnWidget> widgets = new ArrayList<>();
|
||||
private int tick = 0;
|
||||
|
||||
protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer(
|
||||
Identifier.of("saturnclient", "textures/gui/title/background/panorama"));
|
||||
|
||||
public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER;
|
||||
|
||||
static {
|
||||
ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER);
|
||||
}
|
||||
|
||||
public static MutableText text(String text) {
|
||||
return Text.literal(text).setStyle(
|
||||
Style.EMPTY.withFont(Identifier.of("saturnclient:panton")));
|
||||
}
|
||||
|
||||
public static MutableText textBold(String text) {
|
||||
return Text.literal(text).setStyle(
|
||||
Style.EMPTY.withFont(Identifier.of("saturnclient:panton_bold")));
|
||||
}
|
||||
|
||||
public static void drawHighResTexture(DrawContext context, Identifier t, int x, int y, int w, int h) {
|
||||
MatrixStack matricies = context.getMatrices();
|
||||
matricies.push();
|
||||
matricies.translate(x, y, 0);
|
||||
matricies.scale(.25f, .25f, 1.0f);
|
||||
|
||||
context.drawTexture(RenderLayer::getGuiTextured, t, 0, 0, 0, 0,
|
||||
w * 4, h * 4, w * 4, h * 4);
|
||||
|
||||
matricies.pop();
|
||||
}
|
||||
|
||||
public static void drawHighResTexture(DrawContext context, Identifier t, int x, int y, int w, int h, int c) {
|
||||
MatrixStack matricies = context.getMatrices();
|
||||
matricies.push();
|
||||
matricies.translate(x, y, 0);
|
||||
matricies.scale(.25f, .25f, 1.0f);
|
||||
|
||||
context.drawTexture(RenderLayer::getGuiTextured, t, 0, 0, 0, 0,
|
||||
w * 4, h * 4, w * 4, h * 4, c);
|
||||
|
||||
matricies.pop();
|
||||
}
|
||||
|
||||
public static void drawHighResGuiTexture(DrawContext context, Identifier t, int x, int y, int w, int h, int c) {
|
||||
MatrixStack matricies = context.getMatrices();
|
||||
matricies.push();
|
||||
matricies.translate(x, y, 0);
|
||||
matricies.scale(.25f, .25f, 1.0f);
|
||||
|
||||
context.drawGuiTexture(
|
||||
RenderLayer::getGuiTextured,
|
||||
t,
|
||||
0,
|
||||
0,
|
||||
w * 4,
|
||||
h * 4,
|
||||
c);
|
||||
|
||||
matricies.pop();
|
||||
}
|
||||
|
||||
public static int getAlpha(int color, float alpha) {
|
||||
return ((int) (alpha * 255) << 24) |
|
||||
(color & 0x00FFFFFF);
|
||||
}
|
||||
|
||||
public SaturnUi(Text title) {
|
||||
super(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
scheduler.scheduleAtFixedRate(
|
||||
this::saturnTick,
|
||||
0,
|
||||
7,
|
||||
TimeUnit.MILLISECONDS);
|
||||
super.init();
|
||||
}
|
||||
|
||||
public void draw(SaturnWidget widget) {
|
||||
synchronized (widgets) {
|
||||
widget.init();
|
||||
widgets.add(widget);
|
||||
}
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
synchronized (widgets) {
|
||||
widgets.clear();
|
||||
|
||||
f = 0.0f;
|
||||
tick = 0;
|
||||
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
int mouseX,
|
||||
int mouseY,
|
||||
float delta) {
|
||||
|
||||
if (client.world == null && client.getCurrentServerEntry() == null) {
|
||||
ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, 1.0F, delta);
|
||||
}
|
||||
|
||||
// Blur
|
||||
if (!(f < 1.0F) && blur) {
|
||||
PostEffectProcessor postEffectProcessor = this.client.getShaderLoader().loadPostEffect(
|
||||
Identifier.ofVanilla("blur"),
|
||||
DefaultFramebufferSet.MAIN_ONLY);
|
||||
if (postEffectProcessor != null) {
|
||||
postEffectProcessor.setUniforms("Radius", f);
|
||||
postEffectProcessor.render(this.client.getFramebuffer(), this.pool);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (SaturnWidget widget : new ArrayList<>(widgets)) {
|
||||
if (!widget.visible)
|
||||
continue;
|
||||
|
||||
double adjustedMouseX = mouseX - widget.x;
|
||||
double adjustedMouseY = mouseY - widget.y;
|
||||
boolean isMouseInside = adjustedMouseX >= 0 &&
|
||||
adjustedMouseX <= (widget.width * widget.scale) &&
|
||||
adjustedMouseY >= 0 &&
|
||||
adjustedMouseY <= (widget.height * widget.scale);
|
||||
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
matrices.push();
|
||||
matrices.translate(widget.x, widget.y, 0);
|
||||
matrices.scale(widget.scale, widget.scale, 1.0f);
|
||||
widget.render(
|
||||
context,
|
||||
isMouseInside,
|
||||
(int) (adjustedMouseX / widget.scale),
|
||||
(int) (adjustedMouseY / widget.scale));
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (button == 0) {
|
||||
for (SaturnWidget widget : new ArrayList<>(widgets)) {
|
||||
widget.focused = false;
|
||||
if (!widget.visible)
|
||||
continue;
|
||||
|
||||
double adjustedMouseX = mouseX - widget.x;
|
||||
double adjustedMouseY = mouseY - widget.y;
|
||||
boolean isMouseInside = adjustedMouseX >= 0 &&
|
||||
adjustedMouseX <= (widget.width * widget.scale) &&
|
||||
adjustedMouseY >= 0 &&
|
||||
adjustedMouseY <= (widget.height * widget.scale);
|
||||
|
||||
if (isMouseInside) {
|
||||
widget.focused = true;
|
||||
widget.click(
|
||||
(int) (adjustedMouseX / widget.scale),
|
||||
(int) (adjustedMouseY / widget.scale));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
for (SaturnWidget widget : new ArrayList<>(widgets)) {
|
||||
if (!widget.visible && !widget.focused)
|
||||
continue;
|
||||
|
||||
widget.keyPressed(keyCode, scanCode, modifiers);
|
||||
|
||||
char typedChar = getCharFromKey(keyCode, modifiers);
|
||||
if (typedChar != '\0') {
|
||||
widget.charTyped(typedChar);
|
||||
}
|
||||
}
|
||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(
|
||||
double mouseX,
|
||||
double mouseY,
|
||||
double horizontalAmount,
|
||||
double verticalAmount) {
|
||||
for (SaturnWidget widget : new ArrayList<>(widgets)) {
|
||||
double adjustedMouseX = mouseX - widget.x;
|
||||
double adjustedMouseY = mouseY - widget.y;
|
||||
boolean isMouseInside = adjustedMouseX >= 0 &&
|
||||
adjustedMouseX <= (widget.width * widget.scale) &&
|
||||
adjustedMouseY >= 0 &&
|
||||
adjustedMouseY <= (widget.height * widget.scale);
|
||||
|
||||
if (isMouseInside) {
|
||||
widget.mouseScrolled(
|
||||
(int) (adjustedMouseX / widget.scale),
|
||||
(int) (adjustedMouseY / widget.scale),
|
||||
horizontalAmount,
|
||||
verticalAmount);
|
||||
}
|
||||
}
|
||||
|
||||
return super.mouseScrolled(
|
||||
mouseX,
|
||||
mouseY,
|
||||
horizontalAmount,
|
||||
verticalAmount);
|
||||
}
|
||||
|
||||
private char getCharFromKey(int keyCode, int modifiers) {
|
||||
boolean shift = (modifiers & GLFW.GLFW_MOD_SHIFT) != 0;
|
||||
|
||||
// A-Z
|
||||
if (keyCode >= GLFW.GLFW_KEY_A && keyCode <= GLFW.GLFW_KEY_Z) {
|
||||
return (char) (shift
|
||||
? 'A' + (keyCode - GLFW.GLFW_KEY_A)
|
||||
: 'a' + (keyCode - GLFW.GLFW_KEY_A));
|
||||
}
|
||||
|
||||
// 0-9
|
||||
if (keyCode >= GLFW.GLFW_KEY_0 && keyCode <= GLFW.GLFW_KEY_9) {
|
||||
return shift
|
||||
? ")!@#$%^&*(".charAt(keyCode - GLFW.GLFW_KEY_0)
|
||||
: (char) ('0' + (keyCode - GLFW.GLFW_KEY_0));
|
||||
}
|
||||
|
||||
// Special characters
|
||||
return switch (keyCode) {
|
||||
case GLFW.GLFW_KEY_SPACE -> ' ';
|
||||
case GLFW.GLFW_KEY_PERIOD -> shift ? '>' : '.';
|
||||
case GLFW.GLFW_KEY_COMMA -> shift ? '<' : ',';
|
||||
case GLFW.GLFW_KEY_MINUS -> shift ? '_' : '-';
|
||||
case GLFW.GLFW_KEY_EQUAL -> shift ? '+' : '=';
|
||||
case GLFW.GLFW_KEY_SEMICOLON -> shift ? ':' : ';';
|
||||
case GLFW.GLFW_KEY_APOSTROPHE -> shift ? '"' : '\'';
|
||||
case GLFW.GLFW_KEY_SLASH -> shift ? '?' : '/';
|
||||
case GLFW.GLFW_KEY_BACKSLASH -> shift ? '|' : '\\';
|
||||
case GLFW.GLFW_KEY_LEFT_BRACKET -> shift ? '{' : '[';
|
||||
case GLFW.GLFW_KEY_RIGHT_BRACKET -> shift ? '}' : ']';
|
||||
case GLFW.GLFW_KEY_GRAVE_ACCENT -> shift ? '~' : '`';
|
||||
default -> '\0';
|
||||
};
|
||||
}
|
||||
|
||||
public void saturnTick() {
|
||||
synchronized (scheduler) {
|
||||
if (f < 15.0f) {
|
||||
f += 0.25f;
|
||||
}
|
||||
}
|
||||
synchronized (widgets) {
|
||||
for (SaturnWidget widget : widgets) {
|
||||
if (widget.visible && widget.animations != null) {
|
||||
for (SaturnAnimation animation : widget.animations) {
|
||||
if (animation != null &&
|
||||
tick - animation.lastTick == animation.delay) {
|
||||
if (animation.run(widget, tick)) {
|
||||
animation = null;
|
||||
} else {
|
||||
animation.lastTick = tick;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
widget.tick();
|
||||
}
|
||||
tick++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(MinecraftClient client, int width, int height) {
|
||||
super.resize(client, width, height);
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package org.saturnclient.ui;
|
||||
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
|
||||
public class SaturnWidget {
|
||||
|
||||
public int x = 0;
|
||||
public int y = 0;
|
||||
public int width = 0;
|
||||
public int height = 0;
|
||||
public float alpha = 1.0f;
|
||||
public float scale = 1.0f;
|
||||
public SaturnAnimation[] animations = null;
|
||||
public boolean visible = true;
|
||||
public boolean focused = false;
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
}
|
||||
|
||||
public void click(int mouseX, int mouseY) {
|
||||
}
|
||||
|
||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
}
|
||||
|
||||
public void charTyped(char typedChar) {
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
}
|
||||
|
||||
public void mouseScrolled(
|
||||
int mouseX,
|
||||
int mouseY,
|
||||
double horizontalAmount,
|
||||
double verticalAmount) {
|
||||
}
|
||||
|
||||
public SaturnWidget setX(int x) {
|
||||
this.x = x;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SaturnWidget setY(int y) {
|
||||
this.y = y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SaturnWidget setWidth(int width) {
|
||||
this.width = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SaturnWidget setHeight(int height) {
|
||||
this.height = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SaturnWidget setAlpha(float alpha) {
|
||||
this.alpha = alpha;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SaturnWidget setAnimations(SaturnAnimation... animations) {
|
||||
this.animations = animations;
|
||||
for (SaturnAnimation anim : this.animations) {
|
||||
anim.init(this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SaturnWidget setVisible(boolean visible) {
|
||||
this.visible = visible;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SaturnWidget setScale(float scale) {
|
||||
this.scale = scale;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package org.saturnclient.ui;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class Textures {
|
||||
public static final Identifier COSMETICS = Identifier.of("saturnclient", "textures/gui/components/cosmetics.png");
|
||||
public static final Identifier HUD_ICON = Identifier.of("saturnclient", "textures/gui/components/hud.png");
|
||||
public static final Identifier SEARCH = Identifier.of("saturnclient", "textures/gui/components/search.png");
|
||||
public static final Identifier CLOSE = Identifier.of("saturnclient", "textures/gui/components/close.png");
|
||||
public static final Identifier MODS_TAB = Identifier.of("saturnclient", "textures/gui/components/mods_tab.png");
|
||||
public static final Identifier SETTINGS = Identifier.of("saturnclient", "textures/gui/components/settings.png");
|
||||
public static final Identifier CLOAK = Identifier.of("saturnclient", "textures/gui/components/cloak.png");
|
||||
public static final Identifier HAT = Identifier.of("saturnclient", "textures/gui/components/hat.png");
|
||||
public static final Identifier RESET = Identifier.of("saturnclient", "textures/gui/components/reset.png");
|
||||
public static final Identifier TOGGLE_INDICATOR = Identifier.of("saturnclient",
|
||||
"textures/gui/components/toggle_indicator.png");
|
||||
public static final Identifier TOGGLE_BG = Identifier.of("saturnclient", "textures/gui/components/toggle_bg.png");
|
||||
|
||||
public static final Identifier LOGO = Identifier.of("saturnclient", "textures/logo/logo.png");
|
||||
public static final Identifier REALISTIC_LOGO = Identifier.of("saturnclient", "textures/logo/realistic.png");
|
||||
public static final Identifier LOGO_TEXT = Identifier.of("saturnclient", "textures/logo/text.png");
|
||||
|
||||
// Widgets
|
||||
public static final Identifier BUTTON_BORDER = Identifier.of("saturnclient", "button_border");
|
||||
public static final Identifier BUTTON = Identifier.of("saturnclient", "button");
|
||||
public static final Identifier BUTTON_OP = Identifier.of("saturnclient", "button_op");
|
||||
public static final Identifier SETTINGS_BG = Identifier.of("saturnclient", "settings_bg");
|
||||
public static final Identifier RECT = Identifier.of("saturnclient", "rect");
|
||||
public static final Identifier RECT_BORDER = Identifier.of("saturnclient", "rect_border");
|
||||
public static final Identifier MOD = Identifier.of("saturnclient", "textures/gui/components/mod.png");
|
||||
public static final Identifier MOD_BG = Identifier.of("saturnclient", "textures/gui/components/mod_bg.png");
|
||||
|
||||
public static Identifier getCloakPreview(String cloak) {
|
||||
return Identifier.of("saturnclient", "textures/gui/cloak/" + (cloak.isEmpty() ? "none" : cloak) + ".png");
|
||||
}
|
||||
|
||||
public static Identifier getHatPreview(String hat) {
|
||||
return Identifier.of("saturnclient", "textures/gui/hat/" + (hat.isEmpty() ? "none" : hat) + ".png");
|
||||
}
|
||||
|
||||
public static Identifier getModIcon(String modId) {
|
||||
return Identifier.of("saturnclient", "textures/gui/mod/" + modId + ".png");
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package org.saturnclient.ui.animations;
|
||||
|
||||
import org.saturnclient.ui.SaturnAnimation;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
|
||||
public class FadeIn extends SaturnAnimation {
|
||||
public FadeIn(int delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
public void init(SaturnWidget widget) {
|
||||
widget.alpha = 0.0f;
|
||||
}
|
||||
|
||||
public boolean run(SaturnWidget widget, int tick) {
|
||||
widget.alpha += 0.05f;
|
||||
|
||||
return widget.alpha > 0.9f;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package org.saturnclient.ui.animations;
|
||||
|
||||
import org.saturnclient.ui.SaturnAnimation;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
|
||||
public class Slide extends SaturnAnimation {
|
||||
private int offset;
|
||||
|
||||
public Slide(int delay, int offset) {
|
||||
this.delay = delay;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public void init(SaturnWidget widget) {
|
||||
widget.y += offset;
|
||||
}
|
||||
|
||||
public boolean run(SaturnWidget widget, int tick) {
|
||||
widget.y--;
|
||||
offset--;
|
||||
|
||||
return offset == 0;
|
||||
}
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
package org.saturnclient.ui.components;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
public class SaturnFloat extends SaturnWidget {
|
||||
|
||||
String text = "";
|
||||
public Property<Float> prop;
|
||||
public int cursorPosition = 0;
|
||||
private TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
||||
|
||||
public SaturnFloat(Property<Float> prop, int x, int y, int width) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.prop = prop;
|
||||
this.text = String.valueOf(prop.value);
|
||||
this.height = textRenderer.fontHeight + 4;
|
||||
this.scale = 0.8f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
int scrollOffset = getScrollOffset();
|
||||
String visibleText = text.substring(scrollOffset);
|
||||
|
||||
int newCursorPos = scrollOffset;
|
||||
int textWidth = 0;
|
||||
|
||||
for (int i = 0; i < visibleText.length(); i++) {
|
||||
textWidth = textRenderer.getWidth(visibleText.substring(0, i + 1));
|
||||
|
||||
if (textWidth > mouseX) {
|
||||
break;
|
||||
}
|
||||
|
||||
newCursorPos++;
|
||||
}
|
||||
|
||||
cursorPosition = newCursorPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void charTyped(char chr) {
|
||||
if ((Character.isDigit(chr) || chr == '.') && text.length() < 10) {
|
||||
if (text.equals("0") && cursorPosition == 1) {
|
||||
text = "" + chr;
|
||||
} else {
|
||||
text = text.substring(0, cursorPosition) +
|
||||
chr +
|
||||
text.substring(cursorPosition);
|
||||
|
||||
prop.value = text.isEmpty() ? 0 : Float.parseFloat(text);
|
||||
ConfigManager.save();
|
||||
|
||||
cursorPosition++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
|
||||
if (cursorPosition > 0) {
|
||||
text = text.substring(0, cursorPosition - 1) +
|
||||
text.substring(cursorPosition);
|
||||
cursorPosition--;
|
||||
if (text.length() == 0) {
|
||||
text = "0";
|
||||
cursorPosition = 1;
|
||||
}
|
||||
prop.value = Float.parseFloat(text);
|
||||
ConfigManager.save();
|
||||
}
|
||||
} else if (keyCode == GLFW.GLFW_KEY_LEFT) {
|
||||
if (cursorPosition > 0) {
|
||||
cursorPosition--;
|
||||
}
|
||||
} else if (keyCode == GLFW.GLFW_KEY_RIGHT) {
|
||||
if (cursorPosition < text.length()) {
|
||||
cursorPosition++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
if (prop.isReset) {
|
||||
this.text = String.valueOf(prop.value);
|
||||
this.cursorPosition = 0;
|
||||
prop.isReset = false;
|
||||
}
|
||||
SaturnUi.drawHighResGuiTexture(
|
||||
context,
|
||||
Textures.BUTTON_BORDER,
|
||||
0,
|
||||
0,
|
||||
this.width,
|
||||
this.height,
|
||||
focused
|
||||
? SaturnClientConfig.color.value
|
||||
: SaturnClientConfig.getWhite(this.alpha));
|
||||
|
||||
int scrollOffset = getScrollOffset();
|
||||
String visibleText = getVisibleText(scrollOffset);
|
||||
|
||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||
context.drawText(
|
||||
textRenderer,
|
||||
SaturnUi.text(visibleText),
|
||||
2,
|
||||
2,
|
||||
textColor,
|
||||
false);
|
||||
|
||||
if (focused) {
|
||||
int cursorX = 2 +
|
||||
textRenderer.getWidth(
|
||||
SaturnUi.text(
|
||||
visibleText.substring(0, cursorPosition - scrollOffset)));
|
||||
context.fill(
|
||||
cursorX,
|
||||
2,
|
||||
cursorX + 1,
|
||||
textRenderer.fontHeight + 4,
|
||||
0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearText() {
|
||||
text = "0";
|
||||
cursorPosition = 1;
|
||||
prop.value = 0.0f;
|
||||
}
|
||||
|
||||
private int getScrollOffset() {
|
||||
if (text.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
int maxWidth = width - 4; // Available width for text
|
||||
while (offset < cursorPosition) { // Ensure cursor remains visible
|
||||
String visibleText = text.substring(offset, cursorPosition);
|
||||
if (textRenderer.getWidth(SaturnUi.text(visibleText)) > maxWidth) {
|
||||
offset++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
private String getVisibleText(int scrollOffset) {
|
||||
String visibleText = text.substring(scrollOffset);
|
||||
|
||||
// Ensure text does not overflow past the available width
|
||||
for (int i = 1; i <= visibleText.length(); i++) {
|
||||
if (textRenderer.getWidth(
|
||||
SaturnUi.text(visibleText.substring(0, i))) > width - 4) {
|
||||
return visibleText.substring(0, i - 1); // Trim overflow
|
||||
}
|
||||
}
|
||||
return visibleText;
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
package org.saturnclient.ui.components;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
public class SaturnHex extends SaturnWidget {
|
||||
|
||||
private String text = "#"; // Always starts with '#'
|
||||
public Property<Integer> prop;
|
||||
public int cursorPosition = 1; // After '#'
|
||||
private final TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
||||
|
||||
public SaturnHex(Property<Integer> prop, int x, int y, int width) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.prop = prop;
|
||||
this.text = intToHex(prop.value);
|
||||
this.height = textRenderer.fontHeight + 4;
|
||||
this.scale = 0.8f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
cursorPosition = Math.min(7, text.length()); // Keep cursor inside hex length
|
||||
}
|
||||
|
||||
@Override
|
||||
public void charTyped(char chr) {
|
||||
if (isHexChar(chr) && text.length() < 7) { // Limit to 6 hex digits + '#'
|
||||
text = text.substring(0, cursorPosition) +
|
||||
chr +
|
||||
text.substring(cursorPosition);
|
||||
cursorPosition++;
|
||||
|
||||
if (text.length() == 7) { // Only update value when full hex is entered
|
||||
prop.value = hexToInt(text);
|
||||
ConfigManager.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (keyCode == GLFW.GLFW_KEY_BACKSPACE && cursorPosition > 1) { // Prevent deleting '#'
|
||||
text = text.substring(0, cursorPosition - 1) +
|
||||
text.substring(cursorPosition);
|
||||
cursorPosition--;
|
||||
} else if (keyCode == GLFW.GLFW_KEY_LEFT && cursorPosition > 1) {
|
||||
cursorPosition--;
|
||||
} else if (keyCode == GLFW.GLFW_KEY_RIGHT && cursorPosition < text.length()) {
|
||||
cursorPosition++;
|
||||
}
|
||||
|
||||
if (text.length() == 1) { // Reset if empty (keep '#')
|
||||
text = "#";
|
||||
cursorPosition = 1;
|
||||
}
|
||||
|
||||
if (text.length() == 7) { // Update only when valid hex
|
||||
prop.value = hexToInt(text);
|
||||
ConfigManager.save();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
if (prop.isReset) {
|
||||
this.text = intToHex(prop.value);
|
||||
this.cursorPosition = 0;
|
||||
prop.isReset = false;
|
||||
}
|
||||
SaturnUi.drawHighResGuiTexture(
|
||||
context,
|
||||
Textures.BUTTON_BORDER,
|
||||
0,
|
||||
0,
|
||||
this.width,
|
||||
this.height,
|
||||
focused
|
||||
? SaturnClientConfig.color.value
|
||||
: SaturnClientConfig.getWhite(this.alpha));
|
||||
|
||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||
context.drawText(
|
||||
textRenderer,
|
||||
SaturnUi.text(text),
|
||||
2,
|
||||
2,
|
||||
textColor,
|
||||
false);
|
||||
|
||||
if (focused) {
|
||||
int cursorX = 2 +
|
||||
textRenderer.getWidth(
|
||||
SaturnUi.text(text.substring(0, cursorPosition)));
|
||||
context.fill(
|
||||
cursorX,
|
||||
2,
|
||||
cursorX + 1,
|
||||
textRenderer.fontHeight + 4,
|
||||
0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearText() {
|
||||
text = "#";
|
||||
cursorPosition = 1;
|
||||
prop.value = 0xFFFFFFFF; // Default white
|
||||
}
|
||||
|
||||
private boolean isHexChar(char chr) {
|
||||
return ((chr >= '0' && chr <= '9') ||
|
||||
(chr >= 'A' && chr <= 'F') ||
|
||||
(chr >= 'a' && chr <= 'f'));
|
||||
}
|
||||
|
||||
public static int hexToInt(String hex) {
|
||||
hex = hex.replace("#", "");
|
||||
int rgb = Integer.parseInt(hex, 16);
|
||||
return (0xFF << 24) | rgb;
|
||||
}
|
||||
|
||||
public static String intToHex(int color) {
|
||||
int rgb = color & 0xFFFFFF;
|
||||
return String.format("#%06X", rgb).toLowerCase();
|
||||
}
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
package org.saturnclient.ui.components;
|
||||
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
public class SaturnInteger extends SaturnWidget {
|
||||
|
||||
String text = "";
|
||||
public Property<Integer> prop;
|
||||
public int cursorPosition = 0;
|
||||
|
||||
public SaturnInteger(Property<Integer> prop, int x, int y, int width) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.prop = prop;
|
||||
this.text = String.valueOf(prop.value);
|
||||
this.height = SaturnClient.client.textRenderer.fontHeight + 4;
|
||||
this.scale = 0.8f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
int scrollOffset = getScrollOffset();
|
||||
String visibleText = text.substring(scrollOffset);
|
||||
|
||||
int newCursorPos = scrollOffset;
|
||||
int textWidth = 0;
|
||||
|
||||
for (int i = 0; i < visibleText.length(); i++) {
|
||||
textWidth = SaturnClient.client.textRenderer.getWidth(visibleText.substring(0, i + 1));
|
||||
|
||||
if (textWidth > mouseX) {
|
||||
break;
|
||||
}
|
||||
|
||||
newCursorPos++;
|
||||
}
|
||||
|
||||
cursorPosition = newCursorPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void charTyped(char chr) {
|
||||
if (Character.isDigit(chr) && text.length() < 10) {
|
||||
if (text.equals("0") && cursorPosition == 1) {
|
||||
text = "" + chr;
|
||||
} else {
|
||||
text = text.substring(0, cursorPosition) +
|
||||
chr +
|
||||
text.substring(cursorPosition);
|
||||
|
||||
prop.value = text.isEmpty() ? 0 : Integer.parseInt(text);
|
||||
ConfigManager.save();
|
||||
|
||||
cursorPosition++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
|
||||
if (cursorPosition > 0) {
|
||||
text = text.substring(0, cursorPosition - 1) +
|
||||
text.substring(cursorPosition);
|
||||
cursorPosition--;
|
||||
if (text.length() == 0) {
|
||||
text = "0";
|
||||
cursorPosition = 1;
|
||||
}
|
||||
prop.value = Integer.parseInt(text);
|
||||
ConfigManager.save();
|
||||
}
|
||||
} else if (keyCode == GLFW.GLFW_KEY_LEFT) {
|
||||
if (cursorPosition > 0) {
|
||||
cursorPosition--;
|
||||
}
|
||||
} else if (keyCode == GLFW.GLFW_KEY_RIGHT) {
|
||||
if (cursorPosition < text.length()) {
|
||||
cursorPosition++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
if (prop.isReset) {
|
||||
this.text = String.valueOf(prop.value);
|
||||
this.cursorPosition = 0;
|
||||
prop.isReset = false;
|
||||
}
|
||||
SaturnUi.drawHighResGuiTexture(
|
||||
context,
|
||||
Textures.BUTTON_BORDER,
|
||||
0,
|
||||
0,
|
||||
this.width,
|
||||
this.height,
|
||||
focused
|
||||
? SaturnClientConfig.color.value
|
||||
: SaturnClientConfig.getWhite(this.alpha));
|
||||
|
||||
int scrollOffset = getScrollOffset();
|
||||
String visibleText = getVisibleText(scrollOffset);
|
||||
|
||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||
context.drawText(
|
||||
SaturnClient.client.textRenderer,
|
||||
SaturnUi.text(visibleText),
|
||||
2,
|
||||
2,
|
||||
textColor,
|
||||
false);
|
||||
|
||||
if (focused) {
|
||||
int cursorX = 2 +
|
||||
SaturnClient.client.textRenderer.getWidth(
|
||||
SaturnUi.text(
|
||||
visibleText.substring(0, cursorPosition - scrollOffset)));
|
||||
context.fill(
|
||||
cursorX,
|
||||
2,
|
||||
cursorX + 1,
|
||||
SaturnClient.client.textRenderer.fontHeight + 4,
|
||||
0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearText() {
|
||||
text = "0";
|
||||
cursorPosition = 1;
|
||||
prop.value = 0;
|
||||
}
|
||||
|
||||
private int getScrollOffset() {
|
||||
if (text.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
int maxWidth = width - 4; // Available width for text
|
||||
while (offset < cursorPosition) { // Ensure cursor remains visible
|
||||
String visibleText = text.substring(offset, cursorPosition);
|
||||
if (SaturnClient.client.textRenderer.getWidth(SaturnUi.text(visibleText)) > maxWidth) {
|
||||
offset++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
private String getVisibleText(int scrollOffset) {
|
||||
String visibleText = text.substring(scrollOffset);
|
||||
|
||||
// Ensure text does not overflow past the available width
|
||||
for (int i = 1; i <= visibleText.length(); i++) {
|
||||
if (SaturnClient.client.textRenderer.getWidth(
|
||||
SaturnUi.text(visibleText.substring(0, i))) > width - 4) {
|
||||
return visibleText.substring(0, i - 1); // Trim overflow
|
||||
}
|
||||
}
|
||||
return visibleText;
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
package org.saturnclient.ui.components;
|
||||
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.menus.ConfigEditor;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
public class SaturnModComp extends SaturnWidget {
|
||||
|
||||
Module mod;
|
||||
|
||||
public SaturnModComp(Module mod) {
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
boolean enabled = mod.isEnabled();
|
||||
|
||||
boolean hovering_settings = settingsHovering(mouseX, mouseY);
|
||||
|
||||
int color = !hovering_settings && (enabled || hovering)
|
||||
? SaturnClientConfig.color.value
|
||||
: SaturnClientConfig.getWhite(alpha);
|
||||
|
||||
int size = 12;
|
||||
|
||||
if (enabled) {
|
||||
SaturnUi.drawHighResTexture(
|
||||
context,
|
||||
Textures.MOD_BG,
|
||||
0,
|
||||
0,
|
||||
86,
|
||||
20,
|
||||
SaturnClientConfig.color.value);
|
||||
}
|
||||
|
||||
SaturnUi.drawHighResTexture(
|
||||
context,
|
||||
Textures.MOD,
|
||||
0,
|
||||
0,
|
||||
86,
|
||||
20,
|
||||
color);
|
||||
|
||||
SaturnUi.drawHighResTexture(
|
||||
context,
|
||||
mod.getIconTexture(),
|
||||
4,
|
||||
4,
|
||||
size,
|
||||
size,
|
||||
color);
|
||||
|
||||
context.drawText(
|
||||
SaturnClient.client.textRenderer,
|
||||
SaturnUi.text(mod.getName()),
|
||||
20,
|
||||
(21 - SaturnClient.client.textRenderer.fontHeight) / 2,
|
||||
color,
|
||||
false);
|
||||
|
||||
SaturnUi.drawHighResTexture(
|
||||
context,
|
||||
Textures.SETTINGS,
|
||||
77,
|
||||
11,
|
||||
7,
|
||||
7,
|
||||
hovering_settings
|
||||
? SaturnClientConfig.color.value
|
||||
: SaturnClientConfig.getWhite(alpha));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
if (settingsHovering(mouseX, mouseY)) {
|
||||
SaturnClient.client
|
||||
.setScreen(new ConfigEditor(mod.getConfig()));
|
||||
} else {
|
||||
mod.setEnabled(!mod.isEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean settingsHovering(int mouseX, int mouseY) {
|
||||
int sX = 77;
|
||||
int sY = 11;
|
||||
int size = 7;
|
||||
|
||||
return (sX < mouseX &&
|
||||
sX + size > mouseX &&
|
||||
sY < mouseY &&
|
||||
sY + size > mouseY);
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
package org.saturnclient.ui.components;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
public class SaturnString extends SaturnWidget {
|
||||
|
||||
public Property<String> prop;
|
||||
public int cursorPosition = 0;
|
||||
private TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
||||
|
||||
public SaturnString(Property<String> prop, int x, int y, int width) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.prop = prop;
|
||||
this.height = textRenderer.fontHeight + 4;
|
||||
this.scale = 0.8f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
int scrollOffset = getScrollOffset();
|
||||
String visibleText = prop.value.substring(scrollOffset);
|
||||
|
||||
int newCursorPos = scrollOffset;
|
||||
int textWidth = 0;
|
||||
|
||||
for (int i = 0; i < visibleText.length(); i++) {
|
||||
textWidth = textRenderer.getWidth(visibleText.substring(0, i + 1));
|
||||
|
||||
if (textWidth > mouseX) {
|
||||
break;
|
||||
}
|
||||
|
||||
newCursorPos++;
|
||||
}
|
||||
|
||||
cursorPosition = newCursorPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void charTyped(char chr) {
|
||||
prop.value = prop.value.substring(0, cursorPosition) +
|
||||
chr +
|
||||
prop.value.substring(cursorPosition);
|
||||
|
||||
cursorPosition++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
|
||||
if (cursorPosition > 0) {
|
||||
prop.value = prop.value.substring(0, cursorPosition - 1) +
|
||||
prop.value.substring(cursorPosition);
|
||||
cursorPosition--;
|
||||
}
|
||||
} else if (keyCode == GLFW.GLFW_KEY_LEFT) {
|
||||
if (cursorPosition > 0) {
|
||||
cursorPosition--;
|
||||
}
|
||||
} else if (keyCode == GLFW.GLFW_KEY_RIGHT) {
|
||||
if (cursorPosition < prop.value.length()) {
|
||||
cursorPosition++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
SaturnUi.drawHighResGuiTexture(
|
||||
context,
|
||||
Textures.BUTTON_BORDER,
|
||||
0,
|
||||
0,
|
||||
this.width,
|
||||
this.height,
|
||||
focused
|
||||
? SaturnClientConfig.color.value
|
||||
: SaturnClientConfig.getWhite(this.alpha));
|
||||
|
||||
int scrollOffset = getScrollOffset();
|
||||
String visibleText = getVisibleText(scrollOffset);
|
||||
|
||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||
context.drawText(
|
||||
textRenderer,
|
||||
SaturnUi.text(visibleText),
|
||||
2,
|
||||
2,
|
||||
textColor,
|
||||
false);
|
||||
|
||||
if (focused) {
|
||||
int cursorX = 2 +
|
||||
textRenderer.getWidth(
|
||||
SaturnUi.text(
|
||||
visibleText.substring(0, cursorPosition - scrollOffset)));
|
||||
context.fill(
|
||||
cursorX,
|
||||
2,
|
||||
cursorX + 1,
|
||||
textRenderer.fontHeight + 3,
|
||||
0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearText() {
|
||||
prop.value = "";
|
||||
cursorPosition = 1;
|
||||
}
|
||||
|
||||
private int getScrollOffset() {
|
||||
if (prop.value.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
int maxWidth = width - 4; // Available width for prop.value
|
||||
while (offset < cursorPosition) { // Ensure cursor remains visible
|
||||
String visibleText = prop.value.substring(offset, cursorPosition);
|
||||
if (textRenderer.getWidth(SaturnUi.text(visibleText)) > maxWidth) {
|
||||
offset++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
private String getVisibleText(int scrollOffset) {
|
||||
String visibleText = prop.value.substring(scrollOffset);
|
||||
|
||||
// Ensure prop.value does not overflow past the available width
|
||||
for (int i = 1; i <= visibleText.length(); i++) {
|
||||
if (textRenderer.getWidth(
|
||||
SaturnUi.text(visibleText.substring(0, i))) > width - 4) {
|
||||
return visibleText.substring(0, i - 1); // Trim overflow
|
||||
}
|
||||
}
|
||||
return visibleText;
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package org.saturnclient.ui.components;
|
||||
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
public class SaturnToggle extends SaturnWidget {
|
||||
|
||||
Property<Boolean> prop;
|
||||
|
||||
public SaturnToggle(Property<Boolean> prop) {
|
||||
this.prop = prop;
|
||||
width = 16;
|
||||
height = 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
int color = prop.value
|
||||
? SaturnClientConfig.color.value
|
||||
: SaturnClientConfig.getWhite(alpha);
|
||||
int w = 13;
|
||||
int h = 6;
|
||||
int s = 8;
|
||||
|
||||
context.drawTexture(
|
||||
RenderLayer::getGuiTextured,
|
||||
Textures.TOGGLE_BG,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
w,
|
||||
h,
|
||||
w,
|
||||
h,
|
||||
color);
|
||||
|
||||
context.drawTexture(
|
||||
RenderLayer::getGuiTextured,
|
||||
Textures.TOGGLE_INDICATOR,
|
||||
prop.value ? 5 : 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
s,
|
||||
s,
|
||||
s,
|
||||
s,
|
||||
color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
prop.value = !prop.value;
|
||||
ConfigManager.save();
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
package org.saturnclient.ui.widgets;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.util.function.Consumer;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
import org.saturnclient.ui.Textures;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
||||
|
||||
public class SaturnButton extends SaturnWidget {
|
||||
|
||||
public boolean active = true;
|
||||
public String text;
|
||||
public Consumer<SaturnButton> onPress;
|
||||
public boolean background = true;
|
||||
public boolean bold = false;
|
||||
private float hoverAlpha = 0.0f;
|
||||
|
||||
public SaturnButton(String text, Consumer<SaturnButton> onPress) {
|
||||
this.text = text;
|
||||
this.onPress = onPress;
|
||||
}
|
||||
|
||||
public SaturnButton(String text, Runnable onPress) {
|
||||
this(text, b -> {
|
||||
onPress.run();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
MinecraftClient minecraftClient = SaturnClient.client;
|
||||
|
||||
if (background) {
|
||||
RenderSystem.setShaderTexture(0, Textures.BUTTON);
|
||||
|
||||
SaturnUi.drawHighResGuiTexture(
|
||||
context,
|
||||
Textures.BUTTON,
|
||||
0,
|
||||
0,
|
||||
this.width,
|
||||
this.height,
|
||||
SaturnClientConfig.getColor(hovering, alpha));
|
||||
|
||||
if (hovering) {
|
||||
if (hoverAlpha == 0.0f)
|
||||
hoverAlpha = 0.1f;
|
||||
|
||||
SaturnUi.drawHighResGuiTexture(
|
||||
context,
|
||||
Textures.BUTTON_BORDER,
|
||||
0,
|
||||
0,
|
||||
this.width,
|
||||
this.height,
|
||||
SaturnClientConfig.getColor(hovering, alpha));
|
||||
} else {
|
||||
hoverAlpha = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (alpha != 0.0f) {
|
||||
Text t = bold ? SaturnUi.textBold(text) : SaturnUi.text(text);
|
||||
context.drawText(
|
||||
minecraftClient.textRenderer,
|
||||
t,
|
||||
((this.width -
|
||||
minecraftClient.textRenderer.getWidth(t))
|
||||
/
|
||||
2),
|
||||
((this.height - minecraftClient.textRenderer.fontHeight + 1) /
|
||||
2),
|
||||
SaturnClientConfig.getColor(hovering, alpha),
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
this.onPress.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (hoverAlpha > 0.0f && hoverAlpha < 0.9f)
|
||||
hoverAlpha += 0.03f;
|
||||
else if (hoverAlpha > 0.9f && hoverAlpha < 1.0f)
|
||||
hoverAlpha = 1.0f;
|
||||
}
|
||||
|
||||
public SaturnWidget setBold(boolean bold) {
|
||||
this.bold = bold;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package org.saturnclient.ui.widgets;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
|
||||
public class SaturnClickableImage extends SaturnWidget {
|
||||
|
||||
public Identifier texture;
|
||||
public boolean selected = false;
|
||||
public Consumer<SaturnClickableImage> onPress;
|
||||
private float hoverAlpha = 0.0f;
|
||||
|
||||
public SaturnClickableImage(
|
||||
Identifier texture,
|
||||
Consumer<SaturnClickableImage> onPress) {
|
||||
this.texture = texture;
|
||||
this.onPress = onPress;
|
||||
}
|
||||
|
||||
public SaturnClickableImage(Identifier texture, Runnable onPress) {
|
||||
this(texture, _o -> {
|
||||
onPress.run();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
if (hovering) {
|
||||
if (hoverAlpha == 0.0f)
|
||||
hoverAlpha = 0.1f;
|
||||
}
|
||||
|
||||
SaturnUi.drawHighResTexture(
|
||||
context,
|
||||
texture,
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
SaturnClientConfig.getColor(hovering || selected, alpha));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
this.onPress.accept(this);
|
||||
}
|
||||
|
||||
public SaturnClickableImage setSelected(boolean selected) {
|
||||
this.selected = selected;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (hoverAlpha > 0.0f && hoverAlpha < 0.9f)
|
||||
hoverAlpha += 0.03f;
|
||||
else if (hoverAlpha > 0.9f && hoverAlpha < 1.0f)
|
||||
hoverAlpha = 1.0f;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package org.saturnclient.ui.widgets;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
|
||||
public class SaturnClickableSprite extends SaturnWidget {
|
||||
|
||||
public Identifier sprite;
|
||||
public boolean selected = false;
|
||||
public Consumer<SaturnClickableSprite> onPress;
|
||||
|
||||
public SaturnClickableSprite(
|
||||
Identifier sprite,
|
||||
Consumer<SaturnClickableSprite> onPress) {
|
||||
this.sprite = sprite;
|
||||
this.onPress = onPress;
|
||||
}
|
||||
|
||||
public SaturnClickableSprite(Identifier sprite, Runnable onPress) {
|
||||
this(sprite, _o -> {
|
||||
onPress.run();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
SaturnUi.drawHighResGuiTexture(
|
||||
context,
|
||||
sprite,
|
||||
0,
|
||||
0,
|
||||
this.width,
|
||||
this.height,
|
||||
SaturnClientConfig.getColor(hovering, alpha));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
this.onPress.accept(this);
|
||||
}
|
||||
|
||||
public SaturnClickableSprite setSelected(boolean selected) {
|
||||
this.selected = selected;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package org.saturnclient.ui.widgets;
|
||||
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.ColorHelper;
|
||||
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
|
||||
public class SaturnImage extends SaturnWidget {
|
||||
|
||||
private final Identifier sprite;
|
||||
|
||||
public SaturnImage(Identifier sprite) {
|
||||
this.sprite = sprite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
SaturnUi.drawHighResTexture(
|
||||
context,
|
||||
sprite,
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
ColorHelper.getWhite(alpha));
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package org.saturnclient.ui.widgets;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
public class SaturnImageButton extends SaturnWidget {
|
||||
|
||||
public Identifier sprite;
|
||||
public int imageWidth;
|
||||
public int imageHeight;
|
||||
public Consumer<SaturnImageButton> onPress;
|
||||
private float hoverAlpha = 0.0f;
|
||||
|
||||
public SaturnImageButton(
|
||||
Identifier sprite,
|
||||
int imageWidth,
|
||||
int imageHeight,
|
||||
Consumer<SaturnImageButton> onPress) {
|
||||
this.sprite = sprite;
|
||||
this.imageWidth = imageWidth;
|
||||
this.imageHeight = imageHeight;
|
||||
this.onPress = onPress;
|
||||
}
|
||||
|
||||
public SaturnImageButton(
|
||||
Identifier sprite,
|
||||
int imageWidth,
|
||||
int imageHeight,
|
||||
Runnable onPress) {
|
||||
this(sprite, imageWidth, imageHeight, _o -> {
|
||||
onPress.run();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
if (hovering) {
|
||||
if (hoverAlpha == 0.0f)
|
||||
hoverAlpha = 0.1f;
|
||||
}
|
||||
RenderSystem.setShaderTexture(0, Textures.BUTTON);
|
||||
|
||||
SaturnUi.drawHighResGuiTexture(
|
||||
context,
|
||||
Textures.BUTTON,
|
||||
0,
|
||||
0,
|
||||
this.width,
|
||||
this.height,
|
||||
SaturnClientConfig.getColor(hovering, alpha));
|
||||
|
||||
if (hovering) {
|
||||
SaturnUi.drawHighResGuiTexture(
|
||||
context,
|
||||
Textures.BUTTON_BORDER,
|
||||
0,
|
||||
0,
|
||||
this.width,
|
||||
this.height,
|
||||
SaturnClientConfig.getColor(hovering, alpha));
|
||||
}
|
||||
|
||||
context.drawTexture(
|
||||
RenderLayer::getGuiTextured,
|
||||
sprite,
|
||||
((width - imageWidth) / 2),
|
||||
((height - imageHeight) / 2),
|
||||
0,
|
||||
0,
|
||||
imageWidth,
|
||||
imageHeight,
|
||||
imageWidth,
|
||||
imageHeight,
|
||||
SaturnClientConfig.getColor(hovering, alpha));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
this.onPress.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (hoverAlpha > 0.0f && hoverAlpha < 0.9f)
|
||||
hoverAlpha += 0.03f;
|
||||
else if (hoverAlpha > 0.9f && hoverAlpha < 1.0f)
|
||||
hoverAlpha = 1.0f;
|
||||
}
|
||||
}
|
||||
@@ -1,230 +0,0 @@
|
||||
package org.saturnclient.ui.widgets;
|
||||
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.Textures;
|
||||
|
||||
public class SaturnInputBox extends SaturnWidget {
|
||||
|
||||
private TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
||||
private int tick = 0;
|
||||
private boolean cursorVisible = true;
|
||||
|
||||
public Property<String> prop;
|
||||
public int cursorPosition = 0;
|
||||
public Runnable onUpdate;
|
||||
|
||||
public SaturnInputBox(Property<String> prop, int x, int y, int width) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.prop = prop;
|
||||
this.height = textRenderer.fontHeight + 4;
|
||||
this.scale = 1.0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
int scrollOffset = getScrollOffset();
|
||||
String visibleText = prop.value.substring(scrollOffset);
|
||||
|
||||
int newCursorPos = scrollOffset;
|
||||
int textWidth = 0;
|
||||
|
||||
for (int i = 0; i < visibleText.length(); i++) {
|
||||
textWidth = textRenderer.getWidth(visibleText.substring(0, i + 1));
|
||||
|
||||
if (textWidth > mouseX) {
|
||||
break;
|
||||
}
|
||||
|
||||
newCursorPos++;
|
||||
}
|
||||
|
||||
cursorPosition = newCursorPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void charTyped(char chr) {
|
||||
prop.value = prop.value.substring(0, cursorPosition) +
|
||||
chr +
|
||||
prop.value.substring(cursorPosition);
|
||||
|
||||
cursorPosition++;
|
||||
|
||||
onUpdate.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
|
||||
if (cursorPosition > 0) {
|
||||
prop.value = prop.value.substring(0, cursorPosition - 1) +
|
||||
prop.value.substring(cursorPosition);
|
||||
cursorPosition--;
|
||||
}
|
||||
onUpdate.run();
|
||||
} else if (keyCode == GLFW.GLFW_KEY_LEFT) {
|
||||
if (cursorPosition > 0) {
|
||||
cursorPosition--;
|
||||
}
|
||||
} else if (keyCode == GLFW.GLFW_KEY_RIGHT) {
|
||||
if (cursorPosition < prop.value.length()) {
|
||||
cursorPosition++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
SaturnUi.drawHighResGuiTexture(
|
||||
context,
|
||||
Textures.BUTTON,
|
||||
0,
|
||||
0,
|
||||
this.width,
|
||||
this.height,
|
||||
focused
|
||||
? SaturnClientConfig.color.value
|
||||
: SaturnClientConfig.getWhite(this.alpha));
|
||||
|
||||
if (hovering || focused) {
|
||||
SaturnUi.drawHighResGuiTexture(
|
||||
context,
|
||||
Textures.BUTTON_BORDER,
|
||||
0,
|
||||
0,
|
||||
this.width,
|
||||
this.height,
|
||||
hovering
|
||||
? SaturnClientConfig.color.value
|
||||
: SaturnClientConfig.getWhite(this.alpha));
|
||||
}
|
||||
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
matrices.push();
|
||||
|
||||
if (prop.value.isEmpty() && !focused) {
|
||||
SaturnUi.drawHighResTexture(
|
||||
context,
|
||||
Textures.SEARCH,
|
||||
3,
|
||||
3,
|
||||
9,
|
||||
9,
|
||||
hovering
|
||||
? SaturnClientConfig.color.value
|
||||
: SaturnClientConfig.getWhite(this.alpha));
|
||||
|
||||
matrices.scale(0.9f, 0.9f, 1.0f);
|
||||
|
||||
context.drawText(
|
||||
textRenderer,
|
||||
SaturnUi.text("Search"),
|
||||
14,
|
||||
textRenderer.fontHeight / 2 + 1,
|
||||
hovering
|
||||
? SaturnClientConfig.color.value
|
||||
: SaturnClientConfig.getWhite(this.alpha),
|
||||
false);
|
||||
}
|
||||
|
||||
matrices.pop();
|
||||
|
||||
matrices.push();
|
||||
|
||||
matrices.scale(0.9f, 0.9f, 1.0f);
|
||||
|
||||
int scrollOffset = getScrollOffset();
|
||||
String visibleText = getVisibleText(scrollOffset);
|
||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||
context.drawText(
|
||||
textRenderer,
|
||||
SaturnUi.text(visibleText),
|
||||
3,
|
||||
textRenderer.fontHeight / 2,
|
||||
textColor,
|
||||
false);
|
||||
|
||||
if (focused && cursorVisible) {
|
||||
int cursorX = 2 +
|
||||
textRenderer.getWidth(
|
||||
SaturnUi.text(
|
||||
visibleText.substring(0, cursorPosition - scrollOffset)));
|
||||
matrices.translate(cursorX, 0, 0);
|
||||
context.fill(
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
textRenderer.fontHeight + 3,
|
||||
0xFFFFFFFF);
|
||||
}
|
||||
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
public void clearText() {
|
||||
prop.value = "";
|
||||
cursorPosition = 1;
|
||||
}
|
||||
|
||||
private int getScrollOffset() {
|
||||
if (prop.value.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
int maxWidth = width - 4; // Available width for prop.value
|
||||
while (offset < cursorPosition) { // Ensure cursor remains visible
|
||||
String visibleText = prop.value.substring(offset, cursorPosition);
|
||||
if (textRenderer.getWidth(SaturnUi.text(visibleText)) > maxWidth) {
|
||||
offset++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
private String getVisibleText(int scrollOffset) {
|
||||
String visibleText = prop.value.substring(scrollOffset);
|
||||
|
||||
// Ensure prop.value does not overflow past the available width
|
||||
for (int i = 1; i <= visibleText.length(); i++) {
|
||||
if (textRenderer.getWidth(
|
||||
SaturnUi.text(visibleText.substring(0, i))) > width - 4) {
|
||||
return visibleText.substring(0, i - 1); // Trim overflow
|
||||
}
|
||||
}
|
||||
return visibleText;
|
||||
}
|
||||
|
||||
public SaturnInputBox onUpdate(Runnable onUpdate) {
|
||||
this.onUpdate = onUpdate;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (focused) {
|
||||
if (tick < 45 || tick < 60 && cursorVisible) {
|
||||
tick++;
|
||||
} else {
|
||||
tick = 0;
|
||||
cursorVisible = !cursorVisible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
package org.saturnclient.ui.widgets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
|
||||
public class SaturnScroll extends SaturnWidget {
|
||||
|
||||
private int scroll = 0;
|
||||
private int maxScroll = 0;
|
||||
private List<SaturnWidget> children = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void mouseScrolled(
|
||||
int mouseX,
|
||||
int mouseY,
|
||||
double horizontalAmount,
|
||||
double verticalAmount
|
||||
) {
|
||||
verticalAmount *= 2;
|
||||
|
||||
if (scroll - verticalAmount <= 0) {
|
||||
scroll = 0;
|
||||
} else if (scroll - verticalAmount >= maxScroll) {
|
||||
scroll = maxScroll;
|
||||
} else {
|
||||
scroll -= verticalAmount;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY
|
||||
) {
|
||||
context.enableScissor(0, 0, width, height);
|
||||
|
||||
for (SaturnWidget widget : children) {
|
||||
if (!widget.visible) continue;
|
||||
|
||||
double adjustedMouseX = (mouseX - widget.x);
|
||||
double adjustedMouseY = (mouseY - widget.y + scroll);
|
||||
boolean isMouseInside =
|
||||
adjustedMouseX >= 0 &&
|
||||
adjustedMouseX <= (widget.width * widget.scale) &&
|
||||
adjustedMouseY >= 0 &&
|
||||
adjustedMouseY <= (widget.height * widget.scale);
|
||||
|
||||
if (
|
||||
widget.y - scroll < height && widget.y + widget.height > scroll
|
||||
) {
|
||||
MatrixStack matrices = context.getMatrices();
|
||||
matrices.push();
|
||||
matrices.translate(widget.x, widget.y - scroll, 0);
|
||||
matrices.scale(widget.scale, widget.scale, 1.0f);
|
||||
|
||||
widget.render(
|
||||
context,
|
||||
isMouseInside,
|
||||
(int) (adjustedMouseX / widget.scale),
|
||||
(int) (adjustedMouseY / widget.scale)
|
||||
);
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
||||
context.disableScissor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
maxScroll = 0;
|
||||
for (SaturnWidget child : children) {
|
||||
maxScroll = Math.max(maxScroll, child.y + child.height - height);
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(SaturnWidget widget) {
|
||||
synchronized (children) {
|
||||
widget.init();
|
||||
children.add(widget);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isScrollable() {
|
||||
for (SaturnWidget widget : children) {
|
||||
if (widget.y + widget.height > height) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
for (SaturnWidget widget : children) {
|
||||
if (!widget.visible || !widget.focused) {
|
||||
continue;
|
||||
}
|
||||
|
||||
widget.keyPressed(keyCode, scanCode, modifiers);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void charTyped(char typedChar) {
|
||||
for (SaturnWidget widget : children) {
|
||||
if (!widget.visible || !widget.focused) {
|
||||
continue;
|
||||
}
|
||||
|
||||
widget.charTyped(typedChar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
for (SaturnWidget widget : children) {
|
||||
widget.focused = false;
|
||||
if (!widget.visible) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double adjustedMouseX = (mouseX - widget.x);
|
||||
double adjustedMouseY = (mouseY - (widget.y - scroll));
|
||||
boolean isMouseInside =
|
||||
adjustedMouseX >= 0 &&
|
||||
adjustedMouseX <= (widget.width * widget.scale) &&
|
||||
adjustedMouseY >= 0 &&
|
||||
adjustedMouseY <= (widget.height * widget.scale);
|
||||
|
||||
if (isMouseInside) {
|
||||
widget.focused = true;
|
||||
widget.click(
|
||||
(int) (adjustedMouseX / widget.scale),
|
||||
(int) (adjustedMouseY / widget.scale)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
children.clear();
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package org.saturnclient.ui.widgets;
|
||||
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.ColorHelper;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
|
||||
public class SaturnSprite extends SaturnWidget {
|
||||
|
||||
private final Identifier sprite;
|
||||
|
||||
public SaturnSprite(Identifier sprite) {
|
||||
this.sprite = sprite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
SaturnUi.drawHighResGuiTexture(
|
||||
context,
|
||||
sprite,
|
||||
0,
|
||||
0,
|
||||
this.width,
|
||||
this.height,
|
||||
ColorHelper.getWhite(this.alpha));
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package org.saturnclient.ui.widgets;
|
||||
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.ui.SaturnUi;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
|
||||
public class SaturnText extends SaturnWidget {
|
||||
|
||||
private String text;
|
||||
|
||||
public SaturnText(String text) {
|
||||
this.text = text;
|
||||
this.width = SaturnClient.client.textRenderer.getWidth(SaturnUi.text(text));
|
||||
this.height = SaturnClient.client.textRenderer.fontHeight;
|
||||
}
|
||||
|
||||
public SaturnText(String text, int color) {
|
||||
this(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
DrawContext context,
|
||||
boolean hovering,
|
||||
int mouseX,
|
||||
int mouseY) {
|
||||
context.drawText(
|
||||
SaturnClient.client.textRenderer,
|
||||
SaturnUi.text(text),
|
||||
0,
|
||||
0,
|
||||
SaturnClientConfig.getColor(hovering, alpha),
|
||||
false);
|
||||
}
|
||||
}
|
||||
@@ -15,52 +15,62 @@ public class Element {
|
||||
public Animation animation;
|
||||
public float scale = 1.0f;
|
||||
public Function<Double, Double> curve = Curve::easeInOutCubic;
|
||||
public Integer duration = null; // Element duration, will fade out if not null
|
||||
|
||||
public void render(RenderScope renderScope, RenderContext ctx) {
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
}
|
||||
|
||||
public void click(int mouseX, int mouseY) {
|
||||
}
|
||||
|
||||
public final Element dimensions(int width, int height) {
|
||||
public void scroll(int mouseX, int mouseY, double horizontalAmount, double verticalAmount) {
|
||||
}
|
||||
|
||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
}
|
||||
|
||||
public void charTyped(char typedChar) {
|
||||
}
|
||||
|
||||
public Element dimensions(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Element position(int x, int y) {
|
||||
public Element position(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Element centerHorizontal(int w, int h, int offsetX, int offsetY) {
|
||||
public Element centerHorizontal(int w, int h, int offsetX, int offsetY) {
|
||||
this.x = (w - (int) (width * scale)) / 2 + offsetX;
|
||||
this.y = offsetY;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Element center(int w, int h) {
|
||||
public Element center(int w, int h) {
|
||||
this.centerOffset(w, h, 0, 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Element centerOffset(int w, int h, int offsetX, int offsetY) {
|
||||
public Element centerOffset(int w, int h, int offsetX, int offsetY) {
|
||||
this.x = (w - (int) (width * scale)) / 2 + offsetX;
|
||||
this.y = (h - (int) (height * scale)) / 2 + offsetY;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Element animation(Animation animation) {
|
||||
public Element animation(Animation animation) {
|
||||
this.animation = animation;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Element animation(Animation animation, Function<Double, Double> curve) {
|
||||
public Element animation(Animation animation, Function<Double, Double> curve) {
|
||||
this.animation = animation;
|
||||
this.curve = curve;
|
||||
return this;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.saturnclient.ui2;
|
||||
|
||||
public class ElementContext {
|
||||
public int mouseX, mouseY;
|
||||
public int elementWidth, elementHeight;
|
||||
public float elementScale;
|
||||
|
||||
public ElementContext(int mouseX, int mouseY, Element e) {
|
||||
this.mouseX = mouseX - e.x;
|
||||
this.mouseY = mouseY - e.y;
|
||||
this.elementWidth = e.width;
|
||||
this.elementHeight = e.height;
|
||||
this.elementScale = e.scale;
|
||||
}
|
||||
|
||||
public boolean isHovering() {
|
||||
return Utils.isHovering(mouseX, mouseY, elementWidth, elementHeight, elementScale);
|
||||
}
|
||||
|
||||
public boolean isHovering(int x, int y, int width, int height) {
|
||||
return Utils.isHovering(mouseX - x, mouseY - y, width, height, elementScale);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.saturnclient.ui2;
|
||||
|
||||
public class RenderContext {
|
||||
public int mouseX, mouseY;
|
||||
public int elementX, elementY;
|
||||
public int elementWidth, elementHeight;
|
||||
public float elementScale;
|
||||
|
||||
public RenderContext(int mouseX, int mouseY, Element e) {
|
||||
this.mouseX = mouseX;
|
||||
this.mouseY = mouseY;
|
||||
this.elementX = e.x;
|
||||
this.elementY = e.y;
|
||||
this.elementWidth = e.width;
|
||||
this.elementHeight = e.height;
|
||||
this.elementScale = e.scale;
|
||||
}
|
||||
|
||||
public boolean isHovering() {
|
||||
return Utils.isHovering(mouseX - elementX, mouseY - elementY, elementWidth, elementHeight, elementScale);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,12 @@
|
||||
package org.saturnclient.ui2;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
@@ -9,22 +14,39 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.font.TextRenderer.TextLayerType;
|
||||
import net.minecraft.client.gui.ScreenRect;
|
||||
import net.minecraft.client.render.DiffuseLighting;
|
||||
import net.minecraft.client.render.OverlayTexture;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.item.ItemRenderState;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.util.Window;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ModelTransformationMode;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.crash.CrashException;
|
||||
import net.minecraft.util.crash.CrashReport;
|
||||
import net.minecraft.util.crash.CrashReportSection;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class RenderScope {
|
||||
public MatrixStack matrices;
|
||||
public VertexConsumerProvider.Immediate vertexConsumers;
|
||||
private Function<Identifier, RenderLayer> renderLayers;
|
||||
// private Function<Identifier, RenderLayer> renderLayers;
|
||||
private ScissorStack scissorStack = new ScissorStack();
|
||||
private int opacity = 255 << 24;
|
||||
private final ItemRenderState itemRenderState;
|
||||
|
||||
public RenderScope(MatrixStack matrices, VertexConsumerProvider.Immediate vertexConsumers) {
|
||||
this.matrices = matrices;
|
||||
this.vertexConsumers = vertexConsumers;
|
||||
this.scissorStack = new ScissorStack();
|
||||
this.itemRenderState = new ItemRenderState();
|
||||
}
|
||||
|
||||
public void setOpacity(float alpha) {
|
||||
@@ -39,7 +61,7 @@ public class RenderScope {
|
||||
}
|
||||
|
||||
public void setRenderLayer(Function<Identifier, RenderLayer> renderLayers) {
|
||||
this.renderLayers = renderLayers;
|
||||
// this.renderLayers = renderLayers;
|
||||
}
|
||||
|
||||
public void drawRect(int x, int y, int width, int height, int color) {
|
||||
@@ -71,21 +93,29 @@ public class RenderScope {
|
||||
vertexConsumer.vertex(matrix4f, (float) x2, (float) y1, 0).color(color);
|
||||
}
|
||||
|
||||
public void drawText(String text, int x, int y, boolean bold, int color) {
|
||||
color = getColor(color);
|
||||
|
||||
Identifier font = bold ? Fonts.PANTON_BOLD : Fonts.PANTON;
|
||||
|
||||
matrices.push();
|
||||
matrices.translate(x, y, 0);
|
||||
matrices.scale(2.0f, 2.0f, 1.0f);
|
||||
TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
||||
textRenderer.draw(Fonts.setFont(text, font), 0, 0, color, false, this.matrices.peek().getPositionMatrix(),
|
||||
this.vertexConsumers, TextLayerType.NORMAL, 0, 15728880);
|
||||
matrices.pop();
|
||||
public void drawText(String text, int x, int y, int font, int color) {
|
||||
drawText(1.0f, text, x, y, font, color);
|
||||
}
|
||||
|
||||
public void drawRoundedCorner(int width, int height, int radius, int color) {
|
||||
public void drawText(float scale, String text, int x, int y, int font, int color) {
|
||||
if (font == 0) {
|
||||
scale *= 2;
|
||||
}
|
||||
int i = 0;
|
||||
for (String line : text.split("\n")) {
|
||||
color = getColor(color);
|
||||
matrices.push();
|
||||
matrices.translate(x, y + (i * Fonts.getHeight()), 0);
|
||||
matrices.scale(scale, scale, 1.0f);
|
||||
TextRenderer textRenderer = SaturnClient.client.textRenderer;
|
||||
textRenderer.draw(Fonts.setFont(line, Fonts.getFont(font)), 0, font == 0 ? 1: 7, color, false, this.matrices.peek().getPositionMatrix(),
|
||||
this.vertexConsumers, TextLayerType.NORMAL, 0, 15728880);
|
||||
matrices.pop();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private void drawRoundedCorner(int width, int height, int radius, int color) {
|
||||
int w = width * 20;
|
||||
int h = height * 20;
|
||||
|
||||
@@ -152,7 +182,7 @@ public class RenderScope {
|
||||
|
||||
public int getScaledWindowWidth() {
|
||||
return SaturnClient.client.getWindow().getScaledWidth();
|
||||
}
|
||||
}
|
||||
|
||||
public int getScaledWindowHeight() {
|
||||
return SaturnClient.client.getWindow().getScaledHeight();
|
||||
@@ -182,14 +212,159 @@ public class RenderScope {
|
||||
|
||||
matrices.push();
|
||||
matrices.scale(0.25f, 0.25f, 1.0f);
|
||||
RenderSystem.setShaderTexture(0, sprite);
|
||||
RenderLayer renderLayer = (RenderLayer)renderLayers.apply(sprite);
|
||||
Matrix4f matrix4f = this.matrices.peek().getPositionMatrix();
|
||||
VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(renderLayer);
|
||||
vertexConsumer.vertex(matrix4f, (float)x1, (float)y1, 0.0F).texture(u1, v1).color(color);
|
||||
vertexConsumer.vertex(matrix4f, (float)x1, (float)y2, 0.0F).texture(u1, v2).color(color);
|
||||
vertexConsumer.vertex(matrix4f, (float)x2, (float)y2, 0.0F).texture(u2, v2).color(color);
|
||||
vertexConsumer.vertex(matrix4f, (float)x2, (float)y1, 0.0F).texture(u2, v1).color(color);
|
||||
matrices.pop();
|
||||
RenderSystem.setShaderTexture(0, sprite);
|
||||
RenderLayer renderLayer = (RenderLayer)RenderLayer.getGuiTextured(sprite);
|
||||
Matrix4f matrix4f = this.matrices.peek().getPositionMatrix();
|
||||
VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(renderLayer);
|
||||
vertexConsumer.vertex(matrix4f, (float)x1, (float)y1, 0.0F).texture(u1, v1).color(color);
|
||||
vertexConsumer.vertex(matrix4f, (float)x1, (float)y2, 0.0F).texture(u1, v2).color(color);
|
||||
vertexConsumer.vertex(matrix4f, (float)x2, (float)y2, 0.0F).texture(u2, v2).color(color);
|
||||
vertexConsumer.vertex(matrix4f, (float)x2, (float)y1, 0.0F).texture(u2, v1).color(color);
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
public void enableScissor(int x1, int y1, int x2, int y2) {
|
||||
ScreenRect screenRect = (new ScreenRect(x1, y1, x2 - x1, y2 - y1)).transform(this.matrices.peek().getPositionMatrix());
|
||||
this.setScissor(this.scissorStack.push(screenRect));
|
||||
}
|
||||
|
||||
public void disableScissor() {
|
||||
this.setScissor(this.scissorStack.pop());
|
||||
}
|
||||
|
||||
public boolean scissorContains(int x, int y) {
|
||||
return this.scissorStack.containsPoint(x, y);
|
||||
}
|
||||
|
||||
private void setScissor(@Nullable ScreenRect rect) {
|
||||
this.draw();
|
||||
if (rect != null) {
|
||||
Window window = SaturnClient.client.getWindow();
|
||||
int i = window.getFramebufferHeight();
|
||||
double d = window.getScaleFactor();
|
||||
double e = (double)rect.getLeft() * d;
|
||||
double f = (double)i - (double)rect.getBottom() * d;
|
||||
double g = (double)rect.width() * d;
|
||||
double h = (double)rect.height() * d;
|
||||
RenderSystem.enableScissor((int)e, (int)f, Math.max(0, (int)g), Math.max(0, (int)h));
|
||||
} else {
|
||||
RenderSystem.disableScissor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
this.vertexConsumers.draw();
|
||||
}
|
||||
|
||||
public void draw(Consumer<VertexConsumerProvider> drawer) {
|
||||
drawer.accept(this.vertexConsumers);
|
||||
this.vertexConsumers.draw();
|
||||
}
|
||||
|
||||
static class ScissorStack {
|
||||
private final Deque<ScreenRect> stack = new ArrayDeque<>();
|
||||
|
||||
public ScreenRect push(ScreenRect p_281812_) {
|
||||
ScreenRect screenrectangle = this.stack.peekLast();
|
||||
if (screenrectangle != null) {
|
||||
ScreenRect screenrectangle1 = Objects.requireNonNullElse(p_281812_.intersection(screenrectangle), ScreenRect.empty());
|
||||
this.stack.addLast(screenrectangle1);
|
||||
return screenrectangle1;
|
||||
} else {
|
||||
this.stack.addLast(p_281812_);
|
||||
return p_281812_;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ScreenRect pop() {
|
||||
if (this.stack.isEmpty()) {
|
||||
throw new IllegalStateException("Scissor stack underflow");
|
||||
} else {
|
||||
this.stack.removeLast();
|
||||
return this.stack.peekLast();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsPoint(int p_329411_, int p_333404_) {
|
||||
return this.stack.isEmpty() ? true : this.stack.peek().contains(p_329411_, p_333404_);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawItem(ItemStack item, int x, int y) {
|
||||
this.drawItem(SaturnClient.client.player, SaturnClient.client.world, item, x, y, 0);
|
||||
}
|
||||
|
||||
public void drawItem(ItemStack stack, int x, int y, int seed) {
|
||||
this.drawItem(SaturnClient.client.player, SaturnClient.client.world, stack, x, y, seed);
|
||||
}
|
||||
|
||||
public void drawItem(ItemStack stack, int x, int y, int seed, int z) {
|
||||
this.drawItem(SaturnClient.client.player, SaturnClient.client.world, stack, x, y, seed, z);
|
||||
}
|
||||
|
||||
public void drawItemWithoutEntity(ItemStack stack, int x, int y) {
|
||||
this.drawItemWithoutEntity(stack, x, y, 0);
|
||||
}
|
||||
|
||||
public void drawItemWithoutEntity(ItemStack stack, int x, int y, int seed) {
|
||||
this.drawItem((LivingEntity)null, SaturnClient.client.world, stack, x, y, seed);
|
||||
}
|
||||
|
||||
public void drawItem(LivingEntity entity, ItemStack stack, int x, int y, int seed) {
|
||||
this.drawItem(entity, entity.getWorld(), stack, x, y, seed);
|
||||
}
|
||||
|
||||
private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed) {
|
||||
this.drawItem(entity, world, stack, x, y, seed, 0);
|
||||
}
|
||||
|
||||
private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, int z) {
|
||||
if (!stack.isEmpty()) {
|
||||
SaturnClient.client.getItemModelManager().update(this.itemRenderState, stack, ModelTransformationMode.GUI, false, world, entity, seed);
|
||||
this.matrices.push();
|
||||
this.matrices.translate((float)(x + 8), (float)(y + 8), (float)(150 + (this.itemRenderState.hasDepth() ? z : 0)));
|
||||
|
||||
try {
|
||||
this.matrices.scale(16.0F, -16.0F, 16.0F);
|
||||
boolean bl = !this.itemRenderState.isSideLit();
|
||||
if (bl) {
|
||||
this.draw();
|
||||
DiffuseLighting.disableGuiDepthLighting();
|
||||
}
|
||||
|
||||
this.itemRenderState.render(this.matrices, this.vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV);
|
||||
this.draw();
|
||||
if (bl) {
|
||||
DiffuseLighting.enableGuiDepthLighting();
|
||||
}
|
||||
} catch (Throwable var11) {
|
||||
CrashReport crashReport = CrashReport.create(var11, "Rendering item");
|
||||
CrashReportSection crashReportSection = crashReport.addElement("Item being rendered");
|
||||
crashReportSection.add("Item Type", () -> {
|
||||
return String.valueOf(stack.getItem());
|
||||
});
|
||||
crashReportSection.add("Item Components", () -> {
|
||||
return String.valueOf(stack.getComponents());
|
||||
});
|
||||
crashReportSection.add("Item Foil", () -> {
|
||||
return String.valueOf(stack.hasGlint());
|
||||
});
|
||||
throw new CrashException(crashReport);
|
||||
}
|
||||
|
||||
this.matrices.pop();
|
||||
}
|
||||
}
|
||||
|
||||
public void drawSpriteStretched(Sprite sprite, int x, int y, int width, int height) {
|
||||
this.drawSpriteStretched(sprite, x, y, width, height, -1);
|
||||
}
|
||||
|
||||
public void drawSpriteStretched(Sprite sprite, int x, int y, int width, int height, int color) {
|
||||
if (width != 0 && height != 0) {
|
||||
this.drawTexturedQuad(sprite.getAtlasId(), x, x + width, y, y + height, sprite.getMinU(), sprite.getMaxU(), sprite.getMinV(), sprite.getMaxV(), color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,12 @@ package org.saturnclient.ui2;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
||||
import org.saturnclient.ui2.anim.Animation;
|
||||
import org.saturnclient.ui2.anim.SlideXAbsolute;
|
||||
import org.saturnclient.ui2.components.ElementRenderer;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gl.PostEffectProcessor;
|
||||
import net.minecraft.client.gui.CubeMapRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
@@ -49,14 +51,33 @@ public abstract class SaturnScreen extends Screen {
|
||||
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
|
||||
protected void init() {
|
||||
elements.clear();
|
||||
width *= 2;
|
||||
height *= 2;
|
||||
ui(); // abstraction to render the saturn ui and also render extra stuff here
|
||||
ThemeManager.load();
|
||||
|
||||
Animation.execute((Float progress) -> {
|
||||
blurProgress = progress;
|
||||
@@ -92,15 +113,7 @@ public abstract class SaturnScreen extends Screen {
|
||||
|
||||
renderScope.matrices.scale(0.5f, 0.5f, 0.5f);
|
||||
|
||||
for (Element element : elements) {
|
||||
renderScope.matrices.push();
|
||||
renderScope.setOpacity(element.opacity);
|
||||
renderScope.matrices.translate(element.x, element.y, 0);
|
||||
renderScope.matrices.scale(element.scale, element.scale, 1.0f);
|
||||
element.render(renderScope, new RenderContext(mouseX, mouseY, element));
|
||||
renderScope.matrices.pop();
|
||||
renderScope.setRenderLayer(null);
|
||||
}
|
||||
ElementRenderer.render(new ArrayList<>(elements), renderScope, mouseX, mouseY);
|
||||
|
||||
renderScope.matrices.pop();
|
||||
}
|
||||
@@ -109,20 +122,40 @@ public abstract class SaturnScreen extends Screen {
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
mouseX *= 2;
|
||||
mouseY *= 2;
|
||||
if (button == 0) {
|
||||
for (Element element : new ArrayList<>(elements)) {
|
||||
element.focused = false;
|
||||
|
||||
int adjustedMouseX = (int) mouseX - element.x;
|
||||
int adjustedMouseY = (int) mouseY - element.y;
|
||||
|
||||
if (Utils.isHovering(adjustedMouseX, adjustedMouseY, element.width, element.height, element.scale)) {
|
||||
element.focused = true;
|
||||
element.click(adjustedMouseX, adjustedMouseY);
|
||||
}
|
||||
}
|
||||
}
|
||||
ElementRenderer.mouseClicked(elements, mouseX, mouseY, button);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(
|
||||
double mouseX,
|
||||
double mouseY,
|
||||
double horizontalAmount,
|
||||
double verticalAmount) {
|
||||
mouseX *= 2;
|
||||
mouseY *= 2;
|
||||
|
||||
ElementRenderer.mouseScrolled(elements, mouseX, mouseY, horizontalAmount, verticalAmount);
|
||||
|
||||
return super.mouseScrolled(
|
||||
mouseX,
|
||||
mouseY,
|
||||
horizontalAmount,
|
||||
verticalAmount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(MinecraftClient client, int width, int height) {
|
||||
elements.clear();
|
||||
super.resize(client, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
ElementRenderer.keyPressed(elements, keyCode, scanCode, modifiers);
|
||||
|
||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package org.saturnclient.ui2;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
|
||||
public class Utils {
|
||||
public static boolean isHovering(int mouseX, int mouseY, int elementWidth, int elementHeight, float elementScale) {
|
||||
return mouseX >= 0 &&
|
||||
@@ -7,4 +12,44 @@ public class Utils {
|
||||
mouseY >= 0 &&
|
||||
mouseY <= (elementHeight * elementScale);
|
||||
}
|
||||
|
||||
public static char getCharFromKey(int keyCode, int modifiers) {
|
||||
boolean shift = (modifiers & GLFW.GLFW_MOD_SHIFT) != 0;
|
||||
|
||||
// A-Z
|
||||
if (keyCode >= GLFW.GLFW_KEY_A && keyCode <= GLFW.GLFW_KEY_Z) {
|
||||
return (char) (shift
|
||||
? 'A' + (keyCode - GLFW.GLFW_KEY_A)
|
||||
: 'a' + (keyCode - GLFW.GLFW_KEY_A));
|
||||
}
|
||||
|
||||
// 0-9
|
||||
if (keyCode >= GLFW.GLFW_KEY_0 && keyCode <= GLFW.GLFW_KEY_9) {
|
||||
return shift
|
||||
? ")!@#$%^&*(".charAt(keyCode - GLFW.GLFW_KEY_0)
|
||||
: (char) ('0' + (keyCode - GLFW.GLFW_KEY_0));
|
||||
}
|
||||
|
||||
// Special characters
|
||||
return switch (keyCode) {
|
||||
case GLFW.GLFW_KEY_SPACE -> ' ';
|
||||
case GLFW.GLFW_KEY_PERIOD -> shift ? '>' : '.';
|
||||
case GLFW.GLFW_KEY_COMMA -> shift ? '<' : ',';
|
||||
case GLFW.GLFW_KEY_MINUS -> shift ? '_' : '-';
|
||||
case GLFW.GLFW_KEY_EQUAL -> shift ? '+' : '=';
|
||||
case GLFW.GLFW_KEY_SEMICOLON -> shift ? ':' : ';';
|
||||
case GLFW.GLFW_KEY_APOSTROPHE -> shift ? '"' : '\'';
|
||||
case GLFW.GLFW_KEY_SLASH -> shift ? '?' : '/';
|
||||
case GLFW.GLFW_KEY_BACKSLASH -> shift ? '|' : '\\';
|
||||
case GLFW.GLFW_KEY_LEFT_BRACKET -> shift ? '{' : '[';
|
||||
case GLFW.GLFW_KEY_RIGHT_BRACKET -> shift ? '}' : ']';
|
||||
case GLFW.GLFW_KEY_GRAVE_ACCENT -> shift ? '~' : '`';
|
||||
default -> '\0';
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> T getOrNull(List<T> list, int index) {
|
||||
SaturnClient.LOGGER.info("Accessing index {} in list of size {}", index, list.size());
|
||||
return (index >= 0 && index < list.size()) ? list.get(index) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,14 +17,10 @@ public abstract class Animation {
|
||||
|
||||
public static void execute(Consumer<Float> tick, int duration) {
|
||||
new Thread(() -> {
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
Function<Double, Double> curveFunction = Curve::easeInOutCubic;
|
||||
float progress = 0.0f;
|
||||
double incremental = (1000 - duration) / 10000.0;
|
||||
|
||||
System.out.println("Starting animation...");
|
||||
|
||||
for (int i = 0; i <= 100; i++) {
|
||||
float newProgress = (float) (double) curveFunction.apply(i / 100.0);
|
||||
|
||||
@@ -46,8 +42,34 @@ public abstract class Animation {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Animation complete. " + (System.currentTimeMillis() - startTime) + "MS");
|
||||
}).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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.saturnclient.ui2.anim;
|
||||
|
||||
import org.saturnclient.ui2.Element;
|
||||
|
||||
public class FadeOut extends Animation {
|
||||
float targetOpacity;
|
||||
|
||||
public FadeOut(int duration) {
|
||||
super(duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(float progress, Element element) {
|
||||
element.opacity = targetOpacity - progress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Element element) {
|
||||
targetOpacity = element.opacity;
|
||||
// element.opacity = 1.0f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.saturnclient.ui2.anim;
|
||||
|
||||
import org.saturnclient.ui2.Element;
|
||||
|
||||
public class SlideX extends Animation {
|
||||
int offset = 20;
|
||||
int maxOffset = 20;
|
||||
int elementX;
|
||||
|
||||
public SlideX(int duration) {
|
||||
super(duration);
|
||||
}
|
||||
|
||||
public SlideX(int duration, int offset) {
|
||||
super(duration);
|
||||
this.offset = offset;
|
||||
this.maxOffset = offset;
|
||||
}
|
||||
|
||||
public SlideX(int duration, int offset, int maxOffset) {
|
||||
super(duration);
|
||||
this.offset = offset;
|
||||
this.maxOffset = maxOffset; // ✅ fixed
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(float progress, Element element) {
|
||||
element.x = elementX + (int) (offset * progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Element element) {
|
||||
element.x -= offset;
|
||||
elementX = element.x;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.saturnclient.ui2.anim;
|
||||
|
||||
import org.saturnclient.ui2.Element;
|
||||
|
||||
public class SlideXAbsolute extends Animation {
|
||||
int offset = 20;
|
||||
int maxOffset = 20;
|
||||
int elementX;
|
||||
|
||||
public SlideXAbsolute(int duration) {
|
||||
super(duration);
|
||||
}
|
||||
|
||||
public SlideXAbsolute(int duration, int offset) {
|
||||
super(duration);
|
||||
this.offset = offset;
|
||||
this.maxOffset = offset;
|
||||
}
|
||||
|
||||
public SlideXAbsolute(int duration, int offset, int maxOffset) {
|
||||
super(duration);
|
||||
this.offset = offset;
|
||||
this.maxOffset = maxOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(float progress, Element element) {
|
||||
element.x = elementX + (int) (offset * progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Element element) {
|
||||
elementX = element.x;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.saturnclient.ui2.components;
|
||||
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class CosmeticPreview extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("CosmeticPreview", "selected", "hovering");
|
||||
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;
|
||||
private Runnable onClick;
|
||||
private boolean isSelected;
|
||||
|
||||
public CosmeticPreview(boolean isSelected, Identifier sprite, Runnable onClick) {
|
||||
this.sprite = sprite;
|
||||
this.onClick = onClick;
|
||||
this.isSelected = isSelected;
|
||||
|
||||
this.width = 50;
|
||||
this.height = 111;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
if (ctx.isHovering()) {
|
||||
theme.setState("hovering");
|
||||
} else if (isSelected) {
|
||||
theme.setState("selected");
|
||||
}
|
||||
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||
|
||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||
|
||||
int texWidth = width - padding.value;
|
||||
int texHeight = height - padding.value;
|
||||
|
||||
renderScope.drawTexture(sprite, padding.value / 2, padding.value / 2, 0, 0, texWidth, texHeight, fgColor.value);
|
||||
|
||||
theme.setState(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
if (onClick != null) {
|
||||
onClick.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.saturnclient.ui2.components;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.Utils;
|
||||
import org.saturnclient.ui2.anim.Animation;
|
||||
|
||||
public class ElementRenderer {
|
||||
public static void draw(List<Element> elements, Element element) {
|
||||
synchronized (elements) {
|
||||
elements.add(element);
|
||||
}
|
||||
|
||||
if (element.animation != null) {
|
||||
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) {
|
||||
for (Element element : elements) {
|
||||
renderScope.matrices.push();
|
||||
renderScope.setOpacity(element.opacity);
|
||||
renderScope.matrices.translate(element.x, element.y, 0);
|
||||
renderScope.matrices.scale(element.scale, element.scale, 1.0f);
|
||||
element.render(renderScope, new ElementContext(mouseX, mouseY, element));
|
||||
renderScope.matrices.pop();
|
||||
renderScope.setRenderLayer(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void mouseClicked(List<Element> elements, double mouseX, double mouseY, int button) {
|
||||
if (button == 0) {
|
||||
for (Element element : new ArrayList<>(elements)) {
|
||||
element.focused = false;
|
||||
|
||||
int adjustedMouseX = (int) mouseX - element.x;
|
||||
int adjustedMouseY = (int) mouseY - element.y;
|
||||
|
||||
if (element.opacity > 0 && Utils.isHovering(adjustedMouseX, adjustedMouseY, element.width, element.height, element.scale)) {
|
||||
element.focused = true;
|
||||
element.click((int) (adjustedMouseX * element.scale), (int) (adjustedMouseY * element.scale));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void mouseScrolled(
|
||||
List<Element> elements,
|
||||
double mouseX,
|
||||
double mouseY,
|
||||
double horizontalAmount,
|
||||
double verticalAmount) {
|
||||
for (Element element : new ArrayList<>(elements)) {
|
||||
if (Utils.isHovering((int) mouseX - element.x, (int) mouseY - element.y, element.width, element.height, element.scale)) {
|
||||
element.scroll(
|
||||
(int) mouseX - element.x,
|
||||
(int) mouseY - element.y,
|
||||
horizontalAmount,
|
||||
verticalAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void keyPressed(List<Element> elements, int keyCode, int scanCode, int modifiers) {
|
||||
for (Element element : new ArrayList<>(elements)) {
|
||||
if (element.focused && element.opacity > 0) {
|
||||
element.keyPressed(keyCode, scanCode, modifiers);
|
||||
|
||||
char typedChar = Utils.getCharFromKey(keyCode, modifiers);
|
||||
if (typedChar != '\0') {
|
||||
element.charTyped(typedChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package org.saturnclient.ui2.components;
|
||||
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.Utils;
|
||||
import org.saturnclient.ui2.screens.ConfigEditor;
|
||||
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
|
||||
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 {
|
||||
theme.propertyStateDefault("enabled", "bg", 0xFF1d202d);
|
||||
theme.propertyStateDefault("enabled", "icon-bg", 0xFF845eee);
|
||||
theme.propertyStateDefault("hovering", "fg", 0xFF845eee);
|
||||
}
|
||||
|
||||
private Module mod;
|
||||
|
||||
public SaturnModule(Module mod) {
|
||||
this.mod = mod;
|
||||
this.width = 160;
|
||||
this.height = 50;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
int p = 10;
|
||||
int s = 14;
|
||||
boolean settingsHover = false;
|
||||
|
||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||
|
||||
if (mod.isEnabled()) {
|
||||
theme.setState("enabled");
|
||||
}
|
||||
|
||||
if (ctx.isHovering(width - s - p - 5, height - s - p - 5, s + 10, s + 10)) {
|
||||
settingsHover = true;
|
||||
} else if (ctx.isHovering()) {
|
||||
theme.applyState("hovering");
|
||||
}
|
||||
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, radius.value, bgColor.value);
|
||||
|
||||
int h = height-(p * 2);
|
||||
|
||||
renderScope.drawRoundedRectangle(p, p, h, h, iconRadius.value, iconBg.value);
|
||||
|
||||
renderScope.drawTexture(mod.getIconTexture(), p + (p / 2), p + (p / 2), 0, 0, h - p, h - p, iconFg.value);
|
||||
|
||||
renderScope.drawText(0.6f, mod.getName(), p+h+4, p + 1, font.value, fgColor.value);
|
||||
|
||||
renderScope.drawText(0.35f, mod.getVersion(), width - p - (int) (Fonts.getWidth(mod.getVersion(), font.value) * 0.35f), p + 1, font.value, fgColor.value);
|
||||
|
||||
int xt = p + h + 4;
|
||||
for (String tag : mod.getTags()) {
|
||||
int xtb = (int) (Fonts.getWidth(tag, 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);
|
||||
xt += xtb + 9;
|
||||
}
|
||||
|
||||
if (settingsHover) {
|
||||
theme.setState("hovering");
|
||||
}
|
||||
|
||||
renderScope.drawTexture(Textures.SETTINGS, width - s - p, height - s - p, 0, 0, s, s, fgColor.value);
|
||||
|
||||
theme.setState(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
int p = 10;
|
||||
int s = 14;
|
||||
|
||||
if (Utils.isHovering(mouseX - (width - s - p - 5), mouseY - (height - s - p - 5), s + 10, s + 10, 1.0f)) {
|
||||
SaturnClient.client.setScreen(new ConfigEditor(mod.getConfig()));
|
||||
} else {
|
||||
mod.setEnabled(!mod.isEnabled());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package org.saturnclient.ui2.components;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.Utils;
|
||||
import org.saturnclient.ui2.screens.ConfigEditor;
|
||||
import org.saturnclient.ui2.screens.ModMenu;
|
||||
import org.saturnclient.ui2.screens.cosmetics.CloakMenu;
|
||||
import org.saturnclient.ui2.screens.store.CloakStore;
|
||||
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
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 {
|
||||
Runnable onClick;
|
||||
boolean end;
|
||||
Identifier sprite;
|
||||
|
||||
public SidebarComponent(Identifier sprite, Runnable onClick, boolean end) {
|
||||
this.onClick = onClick;
|
||||
this.end = end;
|
||||
this.sprite = sprite;
|
||||
}
|
||||
}
|
||||
|
||||
Runnable onClose;
|
||||
SidebarComponent[] components = {
|
||||
new Sidebar.SidebarComponent(Textures.MODS_TAB, () -> {
|
||||
SaturnClient.client.setScreen(new ModMenu());
|
||||
}, false),
|
||||
new Sidebar.SidebarComponent(Textures.SETTINGS, () -> {
|
||||
SaturnClient.client.setScreen(new ConfigEditor(SaturnClientConfig.config));
|
||||
}, false),
|
||||
|
||||
new Sidebar.SidebarComponent(Textures.SHIRT, () -> {
|
||||
SaturnClient.client.setScreen(new CloakMenu());
|
||||
}, false),
|
||||
|
||||
new Sidebar.SidebarComponent(Textures.CLOSE, () -> {
|
||||
onClose.run();
|
||||
}, true),
|
||||
|
||||
new Sidebar.SidebarComponent(Textures.STORE, () -> {
|
||||
SaturnClient.client.setScreen(new CloakStore());
|
||||
}, true),
|
||||
};
|
||||
int active = 0;
|
||||
|
||||
public Sidebar(int active, Runnable onClose) {
|
||||
this.width = 30;
|
||||
this.height = 350;
|
||||
this.active = active;
|
||||
this.onClose = onClose;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
int topRow = 0;
|
||||
int bottomRow = 0;
|
||||
|
||||
int gap = 5; // 5px gap between icons
|
||||
int sp = 30 - padding.value + gap;
|
||||
int s = 30 - (padding.value * 2);
|
||||
int s2 = s + padding.value;
|
||||
|
||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (SidebarComponent component : components) {
|
||||
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;
|
||||
} 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;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
int topRow = 0;
|
||||
int bottomRow = 0;
|
||||
|
||||
int gap = 5; // same 5px gap here
|
||||
int sp = 30 - padding.value + gap;
|
||||
int s = 30 - (padding.value * 2);
|
||||
int s2 = s + padding.value;
|
||||
|
||||
for (SidebarComponent component : components) {
|
||||
if (component.end) {
|
||||
int y = (height - (sp * bottomRow)) - (s * 2);
|
||||
if (Utils.isHovering(mouseX - (padding.value / 2), mouseY - (y - (padding.value / 2)), s2, s2, scale)) {
|
||||
component.onClick.run();
|
||||
break;
|
||||
}
|
||||
bottomRow += 1;
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
-24
@@ -1,23 +1,31 @@
|
||||
package org.saturnclient.ui.components;
|
||||
package org.saturnclient.ui2.components;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
import org.saturnclient.ui.SaturnWidget;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
import net.minecraft.client.render.DiffuseLighting;
|
||||
import net.minecraft.client.render.entity.EntityRenderDispatcher;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
// If you think this code is bad, it's because it's written by Mojang
|
||||
public class SkinPreview extends Element {
|
||||
private boolean negativeAngle = false;
|
||||
private float angle = 0.0f;
|
||||
|
||||
public class SkinPreview extends SaturnWidget {
|
||||
public static void drawEntity(DrawContext context, int x1, int y1, int x2, int y2, int size, float f, float mouseX,
|
||||
public SkinPreview(float angle, boolean negativeAngle) {
|
||||
this.angle = angle;
|
||||
this.negativeAngle = negativeAngle;
|
||||
}
|
||||
|
||||
public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float f, float mouseX,
|
||||
float mouseY, LivingEntity entity, float angle, boolean negativeAngle) {
|
||||
float g = (float) (x1 + x2) / 2.0F;
|
||||
float h = (float) (y1 + y2) / 2.0F;
|
||||
context.enableScissor(0, 6, x2, y2);
|
||||
renderScope.enableScissor(0, 6, x2, y2);
|
||||
float i = (float) Math.atan((double) ((g - mouseX) / 40.0F));
|
||||
float j = (float) Math.atan((double) ((h - mouseY) / 40.0F));
|
||||
Quaternionf quaternionf = (new Quaternionf()).rotateZ(3.1415927F);
|
||||
@@ -28,15 +36,15 @@ public class SkinPreview extends SaturnWidget {
|
||||
float o = entity.headYaw;
|
||||
entity.setYaw(angle);
|
||||
entity.bodyYaw = angle;
|
||||
entity.setPitch(-j * 20.0F);
|
||||
entity.headYaw = negativeAngle ? -i * 40.0F : i * 40.0F;
|
||||
entity.setPitch(-(j * 20.0F));
|
||||
entity.headYaw = negativeAngle ? (i * 40.0F) + 180f : -(i * 40.0F);
|
||||
entity.prevHeadYaw = entity.getHeadYaw();
|
||||
entity.setCustomNameVisible(false);
|
||||
|
||||
float p = entity.getScale();
|
||||
Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + f * p, 0.0F);
|
||||
float q = (float) size / p;
|
||||
drawEntity(context, g, h, q, vector3f, quaternionf, null, entity);
|
||||
drawEntity(renderScope, g, h, q, vector3f, quaternionf, null, entity);
|
||||
|
||||
entity.setCustomNameVisible(true);
|
||||
entity.bodyYaw = k;
|
||||
@@ -44,36 +52,36 @@ public class SkinPreview extends SaturnWidget {
|
||||
entity.setPitch(m);
|
||||
entity.prevHeadYaw = n;
|
||||
entity.headYaw = o;
|
||||
context.disableScissor();
|
||||
renderScope.disableScissor();
|
||||
}
|
||||
|
||||
public static void drawEntity(DrawContext context, float x, float y, float size, Vector3f vector3f,
|
||||
public static void drawEntity(RenderScope renderScope, float x, float y, float size, Vector3f vector3f,
|
||||
Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) {
|
||||
context.getMatrices().push();
|
||||
context.getMatrices().translate((double) x, (double) y, 50.0);
|
||||
context.getMatrices().scale(size, size, -size);
|
||||
context.getMatrices().translate(vector3f.x, vector3f.y, vector3f.z);
|
||||
context.getMatrices().multiply(quaternionf);
|
||||
context.draw();
|
||||
renderScope.matrices.push();
|
||||
renderScope.matrices.translate((double) x, (double) y, 50.0);
|
||||
renderScope.matrices.scale(size, size, -size);
|
||||
renderScope.matrices.translate(vector3f.x, vector3f.y, vector3f.z);
|
||||
renderScope.matrices.multiply(quaternionf);
|
||||
renderScope.draw();
|
||||
DiffuseLighting.method_34742();
|
||||
EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher();
|
||||
|
||||
entityRenderDispatcher.setRenderShadows(false);
|
||||
context.draw((vertexConsumers) -> {
|
||||
entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, context.getMatrices(), vertexConsumers,
|
||||
renderScope.draw((vertexConsumers) -> {
|
||||
entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, renderScope.matrices, vertexConsumers,
|
||||
15728880);
|
||||
});
|
||||
context.draw();
|
||||
renderScope.draw();
|
||||
entityRenderDispatcher.setRenderShadows(true);
|
||||
context.getMatrices().pop();
|
||||
renderScope.matrices.pop();
|
||||
DiffuseLighting.enableGuiDepthLighting();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context, boolean hovering, int mouseX, int mouseY) {
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
LivingEntity entity = SaturnClient.client.player;
|
||||
if (entity != null) {
|
||||
drawEntity(context, 0, 0, 75, 78, 30, 0.0625F, mouseX, mouseY, entity, -30.0f, true);
|
||||
drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, entity, angle, negativeAngle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package org.saturnclient.ui2.components.inputs;
|
||||
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
public class FloatInput extends Input {
|
||||
public Property<Float> prop;
|
||||
|
||||
public FloatInput(Property<Float> prop) {
|
||||
this.width = 120;
|
||||
this.height = Fonts.getHeight();
|
||||
this.prop = prop;
|
||||
this.text = String.valueOf(prop.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void charTyped(char chr) {
|
||||
if ((Character.isDigit(chr) || chr == '.' || (chr == '-' && cursorPosition == 0)) && text.length() < 10) {
|
||||
if (text.equals("0") && cursorPosition == 1) {
|
||||
text = "" + chr;
|
||||
} else {
|
||||
text = text.substring(0, cursorPosition) +
|
||||
chr +
|
||||
text.substring(cursorPosition);
|
||||
|
||||
try {
|
||||
prop.value = text.isEmpty() ? 0 : Float.parseFloat(text);
|
||||
cursorPosition++;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void backspace() {
|
||||
try {
|
||||
if (text.length() == 0) {
|
||||
text = "0";
|
||||
cursorPosition = 1;
|
||||
}
|
||||
prop.value = Float.parseFloat(text);
|
||||
ConfigManager.save();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkReset() {
|
||||
if (prop.isReset) {
|
||||
this.text = String.valueOf(prop.value);
|
||||
this.cursorPosition = 0;
|
||||
prop.isReset = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.saturnclient.ui2.components.inputs;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.components.dialog.ColorDialog;
|
||||
|
||||
public class HexInput extends Element {
|
||||
public Property<Integer> prop;
|
||||
public SaturnScreen screen;
|
||||
|
||||
public HexInput(Property<Integer> prop, SaturnScreen screen) {
|
||||
this.width = 58;
|
||||
this.height = 20;
|
||||
this.prop = prop;
|
||||
this.scale = 0.8f;
|
||||
this.screen = screen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
SaturnClient.client.setScreen(new ColorDialog(prop, screen));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, 17, prop.value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package org.saturnclient.ui2.components.inputs;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
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 = "";
|
||||
public int cursorPosition = 0;
|
||||
public abstract void checkReset();
|
||||
public abstract void backspace();
|
||||
public boolean validateBackspace() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
|
||||
if (cursorPosition > 0 && validateBackspace()) {
|
||||
text = text.substring(0, cursorPosition - 1) +
|
||||
text.substring(cursorPosition);
|
||||
cursorPosition--;
|
||||
backspace();
|
||||
}
|
||||
} else if (keyCode == GLFW.GLFW_KEY_LEFT) {
|
||||
if (cursorPosition > 0) {
|
||||
cursorPosition--;
|
||||
}
|
||||
} else if (keyCode == GLFW.GLFW_KEY_RIGHT) {
|
||||
if (cursorPosition < text.length()) {
|
||||
cursorPosition++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
int scrollOffset = getScrollOffset();
|
||||
String visibleText = text.substring(scrollOffset);
|
||||
|
||||
int newCursorPos = scrollOffset;
|
||||
float textWidth = 0;
|
||||
|
||||
for (int i = 0; i < visibleText.length(); i++) {
|
||||
textWidth = SaturnClient.client.textRenderer.getWidth(visibleText.substring(0, i + 1)) * 0.6f;
|
||||
|
||||
if (textWidth > mouseX) {
|
||||
break;
|
||||
}
|
||||
|
||||
newCursorPos++;
|
||||
}
|
||||
|
||||
cursorPosition = newCursorPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
checkReset();
|
||||
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, 10, 0xFF000000);
|
||||
|
||||
int scrollOffset = getScrollOffset();
|
||||
String visibleText = getVisibleText(scrollOffset);
|
||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||
renderScope.drawText(0.6f, visibleText, 4, 4, font.value, textColor);
|
||||
|
||||
if (focused) {
|
||||
int cursorX = 4 +
|
||||
(int) (Fonts.getWidth(visibleText.substring(0, cursorPosition - scrollOffset), font.value) * 0.6f);
|
||||
|
||||
renderScope.drawRect(cursorX, 2, 1, height - 4, 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
protected int getScrollOffset() {
|
||||
if (text.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
int maxWidth = width - 4; // Available width for text
|
||||
while (offset < cursorPosition) { // Ensure cursor remains visible
|
||||
String visibleText = text.substring(offset, cursorPosition);
|
||||
if (Fonts.getWidth(visibleText, font.value) > maxWidth) {
|
||||
offset++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
protected String getVisibleText(int scrollOffset) {
|
||||
String visibleText = text.substring(scrollOffset);
|
||||
|
||||
// Ensure text does not overflow past the available width
|
||||
for (int i = 1; i <= visibleText.length(); i++) {
|
||||
if (Fonts.getWidth(visibleText.substring(0, i), font.value) > width - 4) {
|
||||
return visibleText.substring(0, i - 1); // Trim overflow
|
||||
}
|
||||
}
|
||||
return visibleText;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package org.saturnclient.ui2.components.inputs;
|
||||
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
public class IntInput extends Input {
|
||||
public Property<Integer> prop;
|
||||
|
||||
public IntInput(Property<Integer> prop) {
|
||||
this.width = 120;
|
||||
this.height = Fonts.getHeight();
|
||||
this.prop = prop;
|
||||
this.text = String.valueOf(prop.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void charTyped(char chr) {
|
||||
if ((Character.isDigit(chr) || chr == '.' || (chr == '-' && cursorPosition == 0)) && text.length() < 10) {
|
||||
if (text.equals("0") && cursorPosition == 1) {
|
||||
text = "" + chr;
|
||||
} else {
|
||||
text = text.substring(0, cursorPosition) +
|
||||
chr +
|
||||
text.substring(cursorPosition);
|
||||
|
||||
try {
|
||||
prop.value = text.isEmpty() ? 0 : Integer.parseInt(text);
|
||||
cursorPosition++;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void backspace() {
|
||||
try {
|
||||
if (text.length() == 0) {
|
||||
text = "0";
|
||||
cursorPosition = 1;
|
||||
}
|
||||
prop.value = Integer.parseInt(text);
|
||||
ConfigManager.save();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkReset() {
|
||||
if (prop.isReset) {
|
||||
this.text = String.valueOf(prop.value);
|
||||
this.cursorPosition = 0;
|
||||
prop.isReset = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.saturnclient.ui2.components.inputs;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
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;
|
||||
|
||||
public KeybindingSelector(Property<Integer> prop) {
|
||||
this.prop = prop;
|
||||
this.width = 120;
|
||||
this.height = Fonts.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, 10, 0xFF000000);
|
||||
renderScope.drawText(0.6f, prop.value == -1 ? "<NONE>" :
|
||||
GLFW.glfwGetKeyName(prop.value, GLFW.glfwGetKeyScancode(prop.value)).toUpperCase(),
|
||||
4, 4, font.value, textColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (keyCode == GLFW.GLFW_KEY_BACKSPACE) {
|
||||
prop.value = -1;
|
||||
} else {
|
||||
prop.value = keyCode;
|
||||
}
|
||||
focused = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.saturnclient.ui2.components.inputs;
|
||||
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.Utils;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
|
||||
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;
|
||||
|
||||
public Select(Property<Integer> prop) {
|
||||
this.prop = prop;
|
||||
this.width = 150;
|
||||
this.height = 15;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||
|
||||
renderScope.drawText(0.8f, "<", 0, 0, font.value, arrowColor.value);
|
||||
|
||||
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.8f, ">", width - 10, 0, font.value, arrowColor.value);
|
||||
|
||||
theme.setState(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
if (Utils.isHovering(mouseX - (width - 10), mouseY, 10, height, 1.0f)) {
|
||||
prop.next();
|
||||
} else if (Utils.isHovering(mouseX, mouseY, 10, height, 1.0f)) {
|
||||
prop.prev();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.saturnclient.ui2.components.inputs;
|
||||
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
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;
|
||||
|
||||
public Toggle(Property<Boolean> prop) {
|
||||
this.prop = prop;
|
||||
this.width = 60;
|
||||
this.height = 30;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
if (prop.value) {
|
||||
theme.setState("enabled");
|
||||
}
|
||||
|
||||
if (ctx.isHovering()) {
|
||||
theme.applyState("hovering");
|
||||
}
|
||||
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||
|
||||
renderScope.drawRoundedRectangle(prop.value ? 30 : 0, 0, 30, 30, 30, fgColor.value);
|
||||
|
||||
theme.setState(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
prop.value = !prop.value;
|
||||
}
|
||||
}
|
||||
@@ -3,36 +3,32 @@ package org.saturnclient.ui2.elements;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.RenderContext;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class Button extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("Button", "hovering");
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", new Property<Integer>(0xFF000000));
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", new Property<Integer>(0xFFFFFFFF));
|
||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", new Property<Integer>(10));
|
||||
private static Property<Boolean> bold = theme.property("fg-bold", new Property<Boolean>(false));
|
||||
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", 0xFFFF0000);
|
||||
theme.propertyStateDefault("hovering", "fg-color", 0xFF845eee);
|
||||
}
|
||||
|
||||
private String text;
|
||||
private Identifier font;
|
||||
private Runnable onClick;
|
||||
|
||||
public Button(String text, Runnable onClick) {
|
||||
this.text = text;
|
||||
this.font = Fonts.getFont(bold.value);
|
||||
this.onClick = onClick;
|
||||
this.dimensions(Fonts.getWidth(text, font) + 50, Fonts.getHeight() + 20);
|
||||
this.dimensions(Fonts.getWidth(text, font.value) + 50, 38);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, RenderContext ctx) {
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
if (ctx.isHovering()) {
|
||||
theme.setState("hovering");
|
||||
} else {
|
||||
@@ -40,7 +36,8 @@ public class Button extends Element {
|
||||
}
|
||||
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, (width - Fonts.getWidth(text, font)) / 2, (height - Fonts.getHeight()) / 2, bold.value, fgColor.value);
|
||||
renderScope.drawText(text, Fonts.centerX(width, text, font.value), Fonts.centerY(height), font.value, fgColor.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.saturnclient.ui2.elements;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.RenderContext;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
@@ -11,7 +11,7 @@ import net.minecraft.util.Identifier;
|
||||
|
||||
public class ClickableTexture extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("ClickableTexture", "hovering");
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", new Property<Integer>(0xFFFFFFFF));
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", Property.color(0xFFFFFFFF));
|
||||
|
||||
Identifier sprite;
|
||||
private Runnable onClick;
|
||||
@@ -22,7 +22,7 @@ public class ClickableTexture extends Element {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, RenderContext ctx) {
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
if (ctx.isHovering()) {
|
||||
theme.setState("hovering");
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.saturnclient.ui2.elements;
|
||||
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.RenderContext;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
@@ -15,7 +15,7 @@ public class ImageTexture extends Element {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, RenderContext ctx) {
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.setRenderLayer(RenderLayer::getGuiTextured);
|
||||
renderScope.drawTexture(sprite, 0, 0, 0, 0, width, height);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.saturnclient.ui2.elements;
|
||||
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.anim.SlideX;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
|
||||
public class Notification extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("Notification");
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0xFF000000));
|
||||
private static Property<Integer> error = theme.property("error", Property.color(0xFFbf212f));
|
||||
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 {
|
||||
Error,
|
||||
Info,
|
||||
Success,
|
||||
}
|
||||
|
||||
NotificationKind kind;
|
||||
String text;
|
||||
String title;
|
||||
|
||||
public Notification(int width, int height, NotificationKind kind, String title, String text) {
|
||||
this.kind = kind;
|
||||
this.text = text;
|
||||
this.title = title;
|
||||
this.width = (int) Math.max(Fonts.getWidth(text, 1) * 0.6f, Fonts.getWidth(title, 1)) + 20;
|
||||
this.height = 50;
|
||||
this.x = width - this.width - 15;
|
||||
this.y = height - this.height - 15;
|
||||
this.animation = new SlideX(700, -width);
|
||||
this.duration = 3000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, 10, bgColor.value);
|
||||
switch (kind) {
|
||||
case Error:
|
||||
renderScope.drawTexture(Textures.CIRCLE_X, 9, 9, 0, 0, 15, 15, error.value);
|
||||
break;
|
||||
|
||||
case Info:
|
||||
renderScope.drawTexture(Textures.INFO, 9, 9, 0, 0, 15, 15, info.value);
|
||||
break;
|
||||
|
||||
case Success:
|
||||
renderScope.drawTexture(Textures.CHECK, 9, 9, 0, 0, 15, 15, success.value);
|
||||
break;
|
||||
}
|
||||
renderScope.drawText(0.7f, title, 32, 10, 1, -1);
|
||||
renderScope.drawText(0.5f, text, 32, 28, 1, -1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package org.saturnclient.ui2.elements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.components.ElementRenderer;
|
||||
|
||||
public class Scroll extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("Scroll");
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", Property.color(0x90000000));
|
||||
private static Property<Integer> scrollBarColor = theme.property("scrollbar-color", Property.color(-7643914));
|
||||
|
||||
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;
|
||||
|
||||
protected List<Element> children = new ArrayList<>();
|
||||
int scroll = 0;
|
||||
int maxScroll = 0;
|
||||
|
||||
public Scroll(int padding) {
|
||||
this.padding = padding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||
|
||||
renderScope.enableScissor(padding, padding, width - padding, height - padding);
|
||||
renderScope.matrices.push();
|
||||
renderScope.matrices.translate(padding, (-scroll) + padding, 0);
|
||||
ElementRenderer.render(children, renderScope, ctx.mouseX - padding, ctx.mouseY - padding + scroll);
|
||||
renderScope.matrices.pop();
|
||||
renderScope.disableScissor();
|
||||
|
||||
renderScope.drawRoundedRectangle(width - scrollBarWidth.value - scrollBarPadding.value, calculateScrollBarY(), scrollBarWidth.value, calculateScrollBarHeight(), scrollBarRadius.value, scrollBarColor.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scroll(int mouseX, int mouseY, double horizontalAmount, double verticalAmount) {
|
||||
scroll -= verticalAmount;
|
||||
if (scroll < 0) {
|
||||
scroll = 0;
|
||||
} else if (scroll > maxScroll) {
|
||||
scroll = maxScroll;
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
public Element dimensions(int width, int height) {
|
||||
for (Element element : children) {
|
||||
maxScroll = Math.max(maxScroll, element.y + element.height - height);
|
||||
}
|
||||
return super.dimensions(width, height);
|
||||
}
|
||||
|
||||
int calculateScrollBarHeight() {
|
||||
if (maxScroll <= 0) return height - (scrollBarPadding.value * 2); // No scrolling needed
|
||||
return Math.max(20, (height * height) / (height + maxScroll)) - (scrollBarPadding.value * 2); // At least 20px tall
|
||||
}
|
||||
|
||||
int calculateScrollBarY() {
|
||||
int scrollBarHeight = calculateScrollBarHeight();
|
||||
if (maxScroll <= 0) return scrollBarPadding.value;
|
||||
return (scroll * (height - scrollBarHeight)) / maxScroll + scrollBarPadding.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
ElementRenderer.keyPressed(children, keyCode, scanCode, modifiers);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package org.saturnclient.ui2.elements;
|
||||
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.Utils;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
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 {
|
||||
Runnable onClick;
|
||||
Identifier sprite;
|
||||
|
||||
public TabMenuComponent(Identifier sprite, Runnable onClick) {
|
||||
this.onClick = onClick;
|
||||
this.sprite = sprite;
|
||||
}
|
||||
}
|
||||
|
||||
TabMenuComponent[] components;
|
||||
public int selectedScreen = 0;
|
||||
|
||||
public TabMenu(int active, TabMenuComponent... components) {
|
||||
this.components = components;
|
||||
width = 25 * components.length + 6;
|
||||
height = 30;
|
||||
this.selectedScreen = active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value);
|
||||
|
||||
int col = 0;
|
||||
for (TabMenuComponent component : components) {
|
||||
int x = 25 * col + 5;
|
||||
if (ctx.isHovering(x, 5, 20, 20) || selectedScreen == col) {
|
||||
theme.setState("hovering");
|
||||
}
|
||||
|
||||
renderScope.drawRoundedRectangle(x, 5, 20, 20, cornerRadius.value, iconBg.value);
|
||||
renderScope.drawTexture(component.sprite, x + 5, 10, 0, 0, 10, 10, iconFg.value);
|
||||
|
||||
theme.setState(null);
|
||||
col++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
int col = 0;
|
||||
for (TabMenuComponent component : components) {
|
||||
int x = 25 * col + 5;
|
||||
if (Utils.isHovering(mouseX - x, mouseY - 5, 20, 20, 1.0f)) {
|
||||
component.onClick.run();
|
||||
}
|
||||
col++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,21 +3,25 @@ package org.saturnclient.ui2.elements;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.RenderContext;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
public class Text extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("Text");
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", new Property<Integer>(0xFFFFFFFF));
|
||||
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;
|
||||
|
||||
public Text(String text) {
|
||||
this.text = text;
|
||||
width = Fonts.getWidth(text, font.value);
|
||||
height = Fonts.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, RenderContext ctx) {
|
||||
renderScope.drawText(this.text, this.x, this.y, false, fgColor.value);
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.drawText(this.text, 0, 0, font.value, fgColor.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.saturnclient.ui2.elements;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.RenderContext;
|
||||
import org.saturnclient.ui2.ElementContext;
|
||||
import org.saturnclient.ui2.RenderScope;
|
||||
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
@@ -11,14 +11,14 @@ import net.minecraft.util.Identifier;
|
||||
|
||||
public class TextureButton extends Element {
|
||||
private static ThemeManager theme = new ThemeManager("TextureButton", "hovering");
|
||||
private static Property<Integer> bgColor = theme.property("bg-color", new Property<Integer>(0xFF000000));
|
||||
private static Property<Integer> fgColor = theme.property("fg-color", new Property<Integer>(0xFFFFFFFF));
|
||||
private static Property<Integer> padding = theme.property("padding", new Property<Integer>(14));
|
||||
private static Property<Integer> cornerRadius = theme.property("corner-radius", new Property<Integer>(10));
|
||||
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", 0xFFFF0000);
|
||||
theme.propertyStateDefault("hovering", "fg-color", 0xFF845eee);
|
||||
}
|
||||
|
||||
Identifier sprite;
|
||||
@@ -30,7 +30,7 @@ public class TextureButton extends Element {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, RenderContext ctx) {
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
if (ctx.isHovering()) {
|
||||
theme.setState("hovering");
|
||||
} else {
|
||||
|
||||
@@ -6,14 +6,18 @@ import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class Fonts {
|
||||
public static final Identifier PANTON = Identifier.of("saturnclient", "panton");
|
||||
public static final Identifier PANTON_BOLD = Identifier.of("saturnclient", "panton_bold");
|
||||
public static final Identifier INTER = Identifier.of("saturnclient", "inter");
|
||||
public static final Identifier INTER_BOLD = Identifier.of("saturnclient", "inter_bold");
|
||||
public static final Identifier DEFAULT = Identifier.ofVanilla("default");
|
||||
|
||||
public static Identifier getFont(boolean bold) {
|
||||
if (bold) {
|
||||
return PANTON_BOLD;
|
||||
} else {
|
||||
return PANTON;
|
||||
public static Identifier getFont(int font) {
|
||||
switch (font) {
|
||||
case 0:
|
||||
return DEFAULT;
|
||||
case 1:
|
||||
return INTER;
|
||||
default:
|
||||
return INTER_BOLD;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,21 +26,31 @@ public class Fonts {
|
||||
Style.EMPTY.withFont(font));
|
||||
}
|
||||
|
||||
// public static int getWidth(String text, Identifier font) {
|
||||
// return SaturnClient.client.textRenderer.getWidth(Text.literal(text).setStyle(
|
||||
// Style.EMPTY.withFont(font)));
|
||||
// }
|
||||
public static int getWidth(String text, int font) {
|
||||
int w = 0;
|
||||
for (String line : text.split("\n")) {
|
||||
w = Math.max(w, getWidth(line, getFont(font)));
|
||||
}
|
||||
if (font == 0) {
|
||||
return w * 2;
|
||||
} else {
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
// public static int getHeight() {
|
||||
// return SaturnClient.client.textRenderer.fontHeight;
|
||||
// }
|
||||
|
||||
public static int getWidth(String text, Identifier font) {
|
||||
return SaturnClient.client.textRenderer.getWidth(Text.literal(text).setStyle(
|
||||
Style.EMPTY.withFont(font))) * 2;
|
||||
private static int getWidth(String text, Identifier font) {
|
||||
return SaturnClient.client.textRenderer.getWidth(setFont(text, font));
|
||||
}
|
||||
|
||||
public static int getHeight() {
|
||||
return SaturnClient.client.textRenderer.fontHeight * 2;
|
||||
return 18;
|
||||
}
|
||||
|
||||
public static int centerX(int w, String text, int font) {
|
||||
return (w - Fonts.getWidth(text, font)) / 2;
|
||||
}
|
||||
|
||||
public static int centerY(int h) {
|
||||
return (h - 18) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,4 +4,55 @@ import net.minecraft.util.Identifier;
|
||||
|
||||
public class Textures {
|
||||
public static final Identifier CROSSHAIR_RANGE = Identifier.of("saturnclient", "textures/gui/hud/crosshair_range.png");
|
||||
}
|
||||
public static final Identifier COSMETICS = Identifier.of("saturnclient", "textures/gui/components/cosmetics.png");
|
||||
public static final Identifier HUD_ICON = Identifier.of("saturnclient", "textures/gui/components/hud.png");
|
||||
public static final Identifier SEARCH = Identifier.of("saturnclient", "textures/gui/components/search.png");
|
||||
public static final Identifier CLOSE = Identifier.of("saturnclient", "textures/gui/components/close.png");
|
||||
public static final Identifier MODS_TAB = Identifier.of("saturnclient", "textures/gui/components/mods_tab.png");
|
||||
public static final Identifier SETTINGS = Identifier.of("saturnclient", "textures/gui/components/settings.png");
|
||||
public static final Identifier CLOAK = Identifier.of("saturnclient", "textures/gui/components/cloak.png");
|
||||
public static final Identifier HAT = Identifier.of("saturnclient", "textures/gui/components/hat.png");
|
||||
public static final Identifier RESET = Identifier.of("saturnclient", "textures/gui/components/reset.png");
|
||||
public static final Identifier TOGGLE_INDICATOR = Identifier.of("saturnclient",
|
||||
"textures/gui/components/toggle_indicator.png");
|
||||
public static final Identifier LEFT = Identifier.of("saturnclient", "textures/gui/components/left.png");
|
||||
public static final Identifier RIGHT = Identifier.of("saturnclient", "textures/gui/components/right.png");
|
||||
public static final Identifier STORE = Identifier.of("saturnclient", "textures/gui/components/store.png");
|
||||
public static final Identifier COINS = Identifier.of("saturnclient", "textures/gui/components/coins.png");
|
||||
public static final Identifier SHIRT = Identifier.of("saturnclient", "textures/gui/components/shirt.png");
|
||||
public static final Identifier CIRCLE_X = Identifier.of("saturnclient", "textures/gui/components/circle_x.png");
|
||||
public static final Identifier INFO = Identifier.of("saturnclient", "textures/gui/components/info.png");
|
||||
public static final Identifier CHECK = Identifier.of("saturnclient", "textures/gui/components/check.png");
|
||||
|
||||
public static final Identifier LOGO = Identifier.of("saturnclient", "textures/logo/logo.png");
|
||||
public static final Identifier REALISTIC_LOGO = Identifier.of("saturnclient", "textures/logo/realistic.png");
|
||||
public static final Identifier LOGO_TEXT = Identifier.of("saturnclient", "textures/logo/text.png");
|
||||
public static final Identifier LOGO_TEXT_BIG = Identifier.of("saturnclient", "textures/logo/text_big.png");
|
||||
|
||||
// Widgets
|
||||
public static final Identifier BUTTON_BORDER = Identifier.of("saturnclient", "button_border");
|
||||
public static final Identifier BUTTON = Identifier.of("saturnclient", "button");
|
||||
public static final Identifier BUTTON_OP = Identifier.of("saturnclient", "button_op");
|
||||
public static final Identifier SETTINGS_BG = Identifier.of("saturnclient", "settings_bg");
|
||||
public static final Identifier RECT = Identifier.of("saturnclient", "rect");
|
||||
public static final Identifier RECT_BORDER = Identifier.of("saturnclient", "rect_border");
|
||||
public static final Identifier MOD = Identifier.of("saturnclient", "textures/gui/components/mod.png");
|
||||
public static final Identifier MOD_BG = Identifier.of("saturnclient", "textures/gui/components/mod_bg.png");
|
||||
|
||||
public static Identifier getCloakPreview(String cloak) {
|
||||
return Identifier.of("saturnclient", "textures/gui/cloak/" + (cloak.isEmpty() ? "none" : cloak) + ".png");
|
||||
}
|
||||
|
||||
public static Identifier getHatPreview(String hat) {
|
||||
return Identifier.of("saturnclient", "textures/gui/hat/" + (hat.isEmpty() ? "none" : hat) + ".png");
|
||||
}
|
||||
|
||||
public static Identifier getEmotePreview(String emote) {
|
||||
return Identifier.of("saturnclient", "textures/gui/emote/" + (emote == null ? "none" : emote) + ".png");
|
||||
}
|
||||
|
||||
public static Identifier getModIcon(String modId) {
|
||||
return Identifier.of("saturnclient", "textures/gui/mod/" + modId + ".png");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package org.saturnclient.ui2.screens;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.saturnclient.saturnclient.config.ConfigManager;
|
||||
import org.saturnclient.saturnclient.config.Property;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.components.Sidebar;
|
||||
import org.saturnclient.ui2.components.inputs.FloatInput;
|
||||
import org.saturnclient.ui2.components.inputs.HexInput;
|
||||
import org.saturnclient.ui2.components.inputs.IntInput;
|
||||
import org.saturnclient.ui2.components.inputs.KeybindingSelector;
|
||||
import org.saturnclient.ui2.components.inputs.Select;
|
||||
import org.saturnclient.ui2.components.inputs.Toggle;
|
||||
import org.saturnclient.ui2.elements.Scroll;
|
||||
import org.saturnclient.ui2.elements.Text;
|
||||
import org.saturnclient.ui2.resources.Fonts;
|
||||
|
||||
public class ConfigEditor extends SaturnScreen {
|
||||
private ConfigManager config;
|
||||
|
||||
public ConfigEditor(ConfigManager config) {
|
||||
super("Config Editor");
|
||||
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ui() {
|
||||
int p = 10;
|
||||
int g = 10;
|
||||
|
||||
Scroll scroll = new Scroll(p);
|
||||
|
||||
drawProperties(scroll, config.getProperties(), 0, 0, 480 + 10 + (g * 2));
|
||||
|
||||
int scrollWidth = 480 + 10 + (g * 2) + (p * 2);
|
||||
|
||||
draw(scroll.dimensions(scrollWidth, 350).center(width, height));
|
||||
|
||||
draw(new Sidebar(1, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private int drawProperties(Scroll configScroll, Map<String, Property<?>> properties, int row, int col, int w) {
|
||||
for (Map.Entry<String, Property<?>> propEntry : properties.entrySet()) {
|
||||
Property<?> prop = propEntry.getValue();
|
||||
String propName = propEntry.getKey();
|
||||
boolean full = isFull(prop);
|
||||
|
||||
// Always reset to col 0 if full-width component needs to be drawn mid-row
|
||||
if (full && col != 0) {
|
||||
col = 0;
|
||||
row++;
|
||||
}
|
||||
|
||||
int modX = (w / 2) * col; // two-column layout
|
||||
int modY = 25 * row;
|
||||
|
||||
if (prop.getType() == Property.PropertyType.NAMESPACE) {
|
||||
configScroll.draw(
|
||||
new Text(
|
||||
propName
|
||||
).position(Fonts.centerX(520, propName, Text.font.value), modY + 1).scale(0.7f));
|
||||
} else {
|
||||
configScroll.draw(
|
||||
new Text(
|
||||
propName
|
||||
).position(modX, modY + 1).scale(0.7f));
|
||||
}
|
||||
|
||||
switch (prop.getType()) {
|
||||
case BOOLEAN:
|
||||
configScroll.draw(
|
||||
new Toggle((Property<Boolean>) prop)
|
||||
.position(modX + (w / 2) - 40, modY)
|
||||
.scale(0.5f));
|
||||
break;
|
||||
|
||||
case HEX:
|
||||
configScroll.draw(new HexInput((Property<Integer>) prop, this).position(w / 2, modY));
|
||||
break;
|
||||
|
||||
case INTEGER:
|
||||
configScroll.draw(new IntInput((Property<Integer>) prop).position(w / 2, modY));
|
||||
break;
|
||||
|
||||
case FLOAT:
|
||||
configScroll.draw(new FloatInput((Property<Float>) prop).position(w / 2, modY));
|
||||
break;
|
||||
|
||||
case NAMESPACE:
|
||||
Map<String, Property<?>> nestedProperties = (Map<String, Property<?>>) prop.value;
|
||||
row = drawProperties(configScroll, nestedProperties, row + 1, col, w);
|
||||
break;
|
||||
|
||||
case SELECT:
|
||||
configScroll.draw(new Select((Property<Integer>) prop).position(w / 2, modY));
|
||||
break;
|
||||
|
||||
case KEYBINDING:
|
||||
configScroll.draw(new KeybindingSelector((Property<Integer>) prop).position(w / 2, modY));
|
||||
break;
|
||||
|
||||
case STRING:
|
||||
}
|
||||
|
||||
if (full) {
|
||||
row++; // full-width takes a whole row
|
||||
col = 0;
|
||||
} else {
|
||||
col++;
|
||||
if (col > 1) { // max 2 columns
|
||||
col = 0;
|
||||
row++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
public static boolean isFull(Property<?> prop) {
|
||||
switch (prop.getType()) {
|
||||
case BOOLEAN:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package org.saturnclient.ui2.screens;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.auth.Auth;
|
||||
// import org.saturnclient.saturnclient.auth.Auth;
|
||||
import org.saturnclient.saturnclient.cosmetics.Emotes;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.Utils;
|
||||
import org.saturnclient.ui2.anim.Fade;
|
||||
import org.saturnclient.ui2.anim.SlideY;
|
||||
import org.saturnclient.ui2.elements.ImageTexture;
|
||||
import org.saturnclient.ui2.elements.TextureButton;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
|
||||
import dev.kosmx.playerAnim.api.layered.AnimationStack;
|
||||
import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationAccess;
|
||||
import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationRegistry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class EmoteWheel extends SaturnScreen {
|
||||
int page = 1;
|
||||
|
||||
public EmoteWheel() {
|
||||
super("Emote Wheel");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ui() {
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
|
||||
draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(98, 10).centerOffset(width, height, 0, -105)
|
||||
.animation(new Fade(700)));
|
||||
draw(new ImageTexture(SaturnClientConfig.getLogo()).dimensions(98, 98).centerOffset(width, height, 0, -149)
|
||||
.animation(new SlideY(700, -20)));
|
||||
|
||||
draw(new TextureButton(Textures.LEFT, () -> {
|
||||
if (page > 1) {
|
||||
page--;
|
||||
elements.clear();
|
||||
ui();
|
||||
}
|
||||
}).dimensions(30, 30).centerOffset(width, height, -20, 45).animation(new Fade(700)));
|
||||
|
||||
draw(new TextureButton(Textures.RIGHT, () -> {
|
||||
if ((8 * page) < Emotes.availableEmotes.size()) {
|
||||
page++;
|
||||
elements.clear();
|
||||
ui();
|
||||
}
|
||||
}).dimensions(30, 30).centerOffset(width, height, 20, 45).animation(new Fade(700)));
|
||||
|
||||
while (row < 3) {
|
||||
int idx = (row * 3 + col) * page;
|
||||
|
||||
if (row == 1 && col == 1) {
|
||||
col++;
|
||||
}
|
||||
|
||||
String emote = Utils.getOrNull(Emotes.availableEmotes, idx);
|
||||
|
||||
draw(new TextureButton(Textures.getEmotePreview(emote), () -> {
|
||||
if (emote == null) {
|
||||
return;
|
||||
}
|
||||
AnimationStack animationStack = PlayerAnimationAccess.getPlayerAnimLayer(SaturnClient.client.player);
|
||||
if (animationStack.isActive() && animationStack.getPriority() == 1000) {
|
||||
animationStack.removeLayer(1000);
|
||||
}
|
||||
animationStack.addAnimLayer(1000,
|
||||
PlayerAnimationRegistry.getAnimation(Identifier.of("saturnclient",
|
||||
emote)).playAnimation());
|
||||
Auth.emote(emote);
|
||||
close();
|
||||
}).dimensions(70, 70).centerOffset(width, height, -80 + (col * 80), -35 + (row * 80))
|
||||
.animation(new Fade(700)));
|
||||
|
||||
if (col < 2) {
|
||||
col++;
|
||||
} else {
|
||||
col = 0;
|
||||
row++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldPause() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.saturnclient.ui2.screens;
|
||||
|
||||
import org.saturnclient.modules.ModManager;
|
||||
import org.saturnclient.modules.Module;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.components.SaturnModule;
|
||||
import org.saturnclient.ui2.components.Sidebar;
|
||||
import org.saturnclient.ui2.elements.ImageTexture;
|
||||
import org.saturnclient.ui2.elements.Scroll;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
|
||||
public class ModMenu extends SaturnScreen {
|
||||
public ModMenu() {
|
||||
super("Mod Menu");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ui() {
|
||||
int p = 10;
|
||||
int g = 10;
|
||||
|
||||
Scroll scroll = new Scroll(p);
|
||||
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
|
||||
for (Module mod : ModManager.MODS) {
|
||||
scroll.draw(new SaturnModule(mod).position((160 + g) * col, (50 + g) * row));
|
||||
|
||||
if (col == 2) {
|
||||
col = 0;
|
||||
row++;
|
||||
} else {
|
||||
col++;
|
||||
}
|
||||
}
|
||||
|
||||
int scrollWidth = 480 + 10 + (g * 2) + (p * 2);
|
||||
|
||||
draw(scroll.dimensions(scrollWidth, 350).center(width, height));
|
||||
|
||||
draw(new Sidebar(0, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0));
|
||||
|
||||
draw(new ImageTexture(Textures.LOGO_TEXT_BIG).dimensions(180, 18).position(width - 180 - 20, height - 18 - 20));
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,9 @@ package org.saturnclient.ui2.screens;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.menus.CloaksMenu;
|
||||
import org.saturnclient.saturnclient.menus.HudEditor;
|
||||
import org.saturnclient.saturnclient.menus.ModMenu;
|
||||
import org.saturnclient.ui.Textures;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
import org.saturnclient.ui2.screens.cosmetics.CloakMenu;
|
||||
import org.saturnclient.ui2.Element;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.elements.Button;
|
||||
@@ -21,17 +20,17 @@ public class ShiftMenu extends SaturnScreen {
|
||||
|
||||
@Override
|
||||
public void ui() {
|
||||
draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(98, 16).centerOffset(width, height, 0, -36).animation(new Fade(700)));
|
||||
draw(new ImageTexture(SaturnClientConfig.getLogo()).dimensions(98, 98).centerOffset(width, height, 0, -80).animation(new SlideY(700, -40)));
|
||||
draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(98, 10).centerOffset(width, height, 0, -36).animation(new Fade(700)));
|
||||
draw(new ImageTexture(SaturnClientConfig.getLogo()).dimensions(98, 98).centerOffset(width, height, 0, -80).animation(new SlideY(700, -20)));
|
||||
|
||||
Element button = new Button("Settings", () -> {
|
||||
SaturnClient.client.setScreen(new ModMenu());
|
||||
}).center(width, height);
|
||||
}).center(width, height);
|
||||
|
||||
draw(button);
|
||||
|
||||
draw(new TextureButton(Textures.COSMETICS, () -> {
|
||||
client.setScreen(new CloaksMenu());
|
||||
client.setScreen(new CloakMenu());
|
||||
}).dimensions(button.height, button.height).centerOffset(width, height, (button.width / 2) + (button.height / 2) + 4, 0));
|
||||
|
||||
draw(new TextureButton(Textures.HUD_ICON, () -> {
|
||||
|
||||
@@ -2,10 +2,9 @@ package org.saturnclient.ui2.screens;
|
||||
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
import org.saturnclient.saturnclient.SaturnClientConfig;
|
||||
import org.saturnclient.saturnclient.menus.CloaksMenu;
|
||||
import org.saturnclient.saturnclient.menus.HudEditor;
|
||||
import org.saturnclient.saturnclient.menus.ModMenu;
|
||||
import org.saturnclient.ui.Textures;
|
||||
import org.saturnclient.ui2.resources.Textures;
|
||||
import org.saturnclient.ui2.screens.cosmetics.CloakMenu;
|
||||
import org.saturnclient.ui2.SaturnScreen;
|
||||
import org.saturnclient.ui2.anim.Fade;
|
||||
import org.saturnclient.ui2.anim.SlideY;
|
||||
@@ -27,8 +26,8 @@ public class TitleMenu extends SaturnScreen {
|
||||
public void ui() {
|
||||
backgroundBlur = 0;
|
||||
|
||||
draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(98, 16).centerOffset(width, height, 0, -40).animation(new Fade(700)));
|
||||
draw(new ImageTexture(SaturnClientConfig.getLogo()).dimensions(98, 98).centerOffset(width, height, 0, -82).animation(new SlideY(700, -40)));
|
||||
draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(98, 10).centerOffset(width, height, 0, -36).animation(new Fade(700)));
|
||||
draw(new ImageTexture(SaturnClientConfig.getLogo()).dimensions(98, 98).centerOffset(width, height, 0, -82).animation(new SlideY(700, -20)));
|
||||
|
||||
draw(new Button("SINGLEPLAYER", () -> {
|
||||
client.setScreen(new SelectWorldScreen(new TitleMenu()));
|
||||
@@ -57,7 +56,7 @@ public class TitleMenu extends SaturnScreen {
|
||||
}).dimensions(s, s).centerHorizontal(width, height, 0, 8).animation(new SlideY(700, s + 8)));
|
||||
|
||||
draw(new TextureButton(Textures.CLOAK, () -> {
|
||||
client.setScreen(new CloaksMenu());
|
||||
client.setScreen(new CloakMenu());
|
||||
}).dimensions(s, s).centerHorizontal(width, height, s + 2, 8).animation(new SlideY(700, s + 8)));
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user