diff --git a/src/main/java/org/saturnclient/common/minecraft/MinecraftProvider.java b/src/main/java/org/saturnclient/common/minecraft/MinecraftProvider.java index b8d0998..928f604 100644 --- a/src/main/java/org/saturnclient/common/minecraft/MinecraftProvider.java +++ b/src/main/java/org/saturnclient/common/minecraft/MinecraftProvider.java @@ -1,6 +1,8 @@ package org.saturnclient.common.minecraft; import org.saturnclient.common.minecraft.bindings.SaturnIdentifier; +import org.saturnclient.ui.SaturnScreen; + import java.awt.image.BufferedImage; public abstract class MinecraftProvider { @@ -8,6 +10,8 @@ public abstract class MinecraftProvider { public abstract IMinecraftClient getClient(); + public abstract void setScreen(SaturnScreen screen); + public abstract Object createIdentifier(String namespace, String path); public abstract boolean isKeyPressed(int key); diff --git a/src/main/java/org/saturnclient/ui/SaturnScreen.java b/src/main/java/org/saturnclient/ui/SaturnScreen.java new file mode 100644 index 0000000..fe47578 --- /dev/null +++ b/src/main/java/org/saturnclient/ui/SaturnScreen.java @@ -0,0 +1,117 @@ +package org.saturnclient.ui; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +public abstract class SaturnScreen { + public static interface ScreenProvider { + public void close(); + } + + // General + public int width; + public int height; + public String title; + + // Saturn Screen + public List elements = new ArrayList<>(); + public float backgroundOpacity = 1.0f; + protected Instant start = null; + public int backgroundBlur = 10; + + // Provider + public ScreenProvider provider; + + public SaturnScreen(String title) { + this.title = title; + } + + protected void init() { + elements.clear(); + width *= 2; + height *= 2; + ui(); // abstraction to render the saturn ui and also render extra stuff here + } + + public abstract void ui(); + + public void draw(Element element) { + ElementRenderer.INSTANCE.draw(elements, element); + } + + // -------------- + // Rendering + // -------------- + + public void render(RenderScope renderScope, int mouseX, int mouseY, float delta, long elapsed) { + renderScope.getMatrixStack().push(); + + renderScope.getMatrixStack().scale(0.5f, 0.5f, 0.5f); + + ElementRenderer.INSTANCE.render(new ArrayList<>(elements), elapsed, renderScope, mouseX, mouseY); + + renderScope.getMatrixStack().pop(); + } + + // -------------- + // Events + // -------------- + + public boolean mouseClicked(double mouseX, double mouseY, int button) { + mouseX *= 2; + mouseY *= 2; + + ElementRenderer.INSTANCE.mouseClicked(elements, mouseX, mouseY, button); + + return false; + } + + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + mouseX *= 2; + mouseY *= 2; + + ElementRenderer.INSTANCE.mouseDragged(elements, mouseX, mouseY, button, deltaX, deltaY); + + return false; + } + + public boolean mouseReleased(double mouseX, double mouseY, int button) { + mouseX *= 2; + mouseY *= 2; + + ElementRenderer.INSTANCE.mouseReleased(elements, mouseX, mouseY, button); + + return false; + } + + public boolean mouseScrolled( + double mouseX, + double mouseY, + double horizontalAmount, + double verticalAmount) { + mouseX *= 2; + mouseY *= 2; + + ElementRenderer.INSTANCE.mouseScrolled(elements, mouseX, mouseY, horizontalAmount, verticalAmount); + + return false; + } + + public void resize(int width, int height) { + elements.clear(); + } + + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + ElementRenderer.INSTANCE.keyPressed(elements, keyCode, scanCode, modifiers); + + return false; + } + + public boolean shouldPause() { + return true; + } + + public void onClose() { + } +} diff --git a/src/main/java/org/saturnclient/ui/components/SaturnModule.java b/src/main/java/org/saturnclient/ui/components/SaturnModule.java index 140b57b..4ce7864 100644 --- a/src/main/java/org/saturnclient/ui/components/SaturnModule.java +++ b/src/main/java/org/saturnclient/ui/components/SaturnModule.java @@ -1,7 +1,7 @@ package org.saturnclient.ui.components; import org.saturnclient.modules.Module; -import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.common.minecraft.MinecraftProvider; import org.saturnclient.config.Theme; import org.saturnclient.ui.Element; import org.saturnclient.ui.ElementContext; @@ -141,7 +141,7 @@ public class SaturnModule extends Element { 1.0f); if (settingsHover) { - SaturnClient.client.setScreen(new ConfigEditor(mod.getConfig())); + MinecraftProvider.PROVIDER.setScreen(new ConfigEditor(mod.getConfig())); } else { mod.setEnabled(!mod.isEnabled()); } diff --git a/src/main/java/org/saturnclient/ui/components/Sidebar.java b/src/main/java/org/saturnclient/ui/components/Sidebar.java index 8c4ef45..9a781ce 100644 --- a/src/main/java/org/saturnclient/ui/components/Sidebar.java +++ b/src/main/java/org/saturnclient/ui/components/Sidebar.java @@ -1,6 +1,6 @@ package org.saturnclient.ui.components; -import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.common.minecraft.MinecraftProvider; import org.saturnclient.common.minecraft.bindings.SaturnIdentifier; import org.saturnclient.config.Config; import org.saturnclient.config.Theme; @@ -30,14 +30,14 @@ public class Sidebar extends Element { Runnable onClose; SidebarComponent[] components = { new Sidebar.SidebarComponent(Textures.MODS_TAB, () -> { - SaturnClient.client.setScreen(new ModMenu()); + MinecraftProvider.PROVIDER.setScreen(new ModMenu()); }, false), new Sidebar.SidebarComponent(Textures.SETTINGS, () -> { - SaturnClient.client.setScreen(new ConfigEditor(Config.config)); + MinecraftProvider.PROVIDER.setScreen(new ConfigEditor(Config.config)); }, false), new Sidebar.SidebarComponent(Textures.SHIRT, () -> { - SaturnClient.client.setScreen(new CloakMenu()); + MinecraftProvider.PROVIDER.setScreen(new CloakMenu()); }, false), new Sidebar.SidebarComponent(Textures.CLOSE, () -> { @@ -45,7 +45,7 @@ public class Sidebar extends Element { }, true), new Sidebar.SidebarComponent(Textures.STORE, () -> { - SaturnClient.client.setScreen(new CloakStore()); + MinecraftProvider.PROVIDER.setScreen(new CloakStore()); }, true), }; int active = 0; diff --git a/src/main/java/org/saturnclient/ui/screens/HudEditor.java b/src/main/java/org/saturnclient/ui/screens/HudEditor.java new file mode 100644 index 0000000..178d068 --- /dev/null +++ b/src/main/java/org/saturnclient/ui/screens/HudEditor.java @@ -0,0 +1,132 @@ +package org.saturnclient.ui.screens; + +import org.saturnclient.modules.HudMod; +import org.saturnclient.modules.ModDimensions; +import org.saturnclient.modules.ModManager; +import org.saturnclient.modules.Module; +import org.saturnclient.common.minecraft.render.IMatrixStack; +import org.saturnclient.config.manager.ConfigManager; +import org.saturnclient.ui.RenderScope; +import org.saturnclient.ui.SaturnScreen; + +import java.util.ArrayList; +import java.util.List; + +public class HudEditor extends SaturnScreen { + private final List hudMods = new ArrayList<>(); + private HudMod draggingMod = null; + private boolean resizing = false; + private int offsetX, offsetY; + private static final int RESIZE_MARGIN = 3; + + public HudEditor() { + super("HUD Editor"); + for (Module m : ModManager.ENABLED_MODS) { + if (m.isEnabled() && m instanceof HudMod) { + hudMods.add((HudMod) m); + } + } + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (button == 0) { + for (int m = hudMods.size() - 1; m >= 0; m--) { + HudMod mod = hudMods.get(m); + ModDimensions dim = mod.getDimensions(); + + // Check if clicking the corner for resizing + if (isCorner(mouseX, mouseY, dim)) { + draggingMod = mod; + resizing = true; + offsetX = (int) (mouseX - (dim.x.value + dim.width * dim.scale.value)); + offsetY = (int) (mouseY - (dim.y.value + dim.height * dim.scale.value)); + return true; + } + + // Check if clicking inside the mod + if (isInside(mouseX, mouseY, dim)) { + draggingMod = mod; + resizing = false; + offsetX = (int) (mouseX - dim.x.value); + offsetY = (int) (mouseY - dim.y.value); + return true; + } + } + } + return super.mouseClicked(mouseX, mouseY, button); + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + if (button == 0) { + draggingMod = null; + resizing = false; + } + return super.mouseReleased(mouseX, mouseY, button); + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + if (draggingMod != null) { + ModDimensions dim = draggingMod.getDimensions(); + + if (resizing) { + // Scale based on cursor movement + float newScale = Math.max(0.5f, ((float) (mouseX - dim.x.value) / dim.width)); + dim.scale.value = newScale; + } else { + // Move the mod + dim.x.value = (int) mouseX - offsetX; + dim.y.value = (int) mouseY - offsetY; + } + } + return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + } + + @Override + public void ui() { + } + + @Override + public void render(RenderScope renderScope, int mouseX, int mouseY, float delta, long elapsed) { + for (HudMod mod : hudMods) { + ModDimensions dim = mod.getDimensions(); + IMatrixStack matrices = renderScope.getMatrixStack(); + matrices.push(); + + matrices.translate(dim.x.value, dim.y.value, 0); + matrices.scale(dim.scale.value, dim.scale.value, 1.0f); + + // Render the mod + mod.renderDummy(renderScope); + + matrices.pop(); + + // Draw border around mod + int borderX = dim.x.value; + int borderY = dim.y.value; + int borderW = (int) (dim.width * dim.scale.value); + int borderH = (int) (dim.height * dim.scale.value); + + renderScope.drawBorder(borderX, borderY, borderW, borderH, 0xFFFFFFFF); // White border + } + } + + private boolean isInside(double mouseX, double mouseY, ModDimensions dim) { + return mouseX >= dim.x.value && mouseX <= dim.x.value + (dim.width * dim.scale.value) && + mouseY >= dim.y.value && mouseY <= dim.y.value + (dim.height * dim.scale.value); + } + + private boolean isCorner(double mouseX, double mouseY, ModDimensions dim) { + float rightX = dim.x.value + dim.width * dim.scale.value; + float bottomY = dim.y.value + dim.height * dim.scale.value; + + return Math.abs(mouseX - rightX) < RESIZE_MARGIN && Math.abs(mouseY - bottomY) < RESIZE_MARGIN; + } + + @Override + public void onClose() { + ConfigManager.save(); + } +}