diff --git a/.factorypath b/.factorypath
new file mode 100644
index 0000000..d0b65a4
--- /dev/null
+++ b/.factorypath
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/org/saturnclient/saturnclient/menus/ConfigEditor.java b/src/main/java/org/saturnclient/saturnclient/menus/ConfigEditor.java
index 0c97e2a..8f0783a 100644
--- a/src/main/java/org/saturnclient/saturnclient/menus/ConfigEditor.java
+++ b/src/main/java/org/saturnclient/saturnclient/menus/ConfigEditor.java
@@ -7,6 +7,7 @@ import org.saturnclient.saturnclient.config.Property;
import org.saturnclient.ui.SaturnUi;
import org.saturnclient.ui.Textures;
import org.saturnclient.ui.animations.Slide;
+import org.saturnclient.ui.components.SaturnInteger;
import org.saturnclient.ui.components.SaturnToggle;
import org.saturnclient.ui.widgets.SaturnScroll;
import org.saturnclient.ui.widgets.SaturnSprite;
@@ -29,14 +30,14 @@ public class ConfigEditor extends SaturnUi {
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(new Slide(1, 10))
- );
+ // draw(
+ // new SaturnSprite(Textures.SETTINGS_BG)
+ // .setX(rectX)
+ // .setY(rectY)
+ // .setWidth(rectWidth)
+ // .setHeight(rectHeight)
+ // .setAnimations(new Slide(1, 10))
+ // );
int tabsX = (width - 43) / 2;
int tabsY = rectY - 17;
@@ -100,9 +101,12 @@ public class ConfigEditor extends SaturnUi {
);
configScroll.draw(
- new SaturnText("" + prop.value)
- .setX((rectWidth / 2) - 17)
- .setY(modY)
+ new SaturnInteger(
+ (Property) prop,
+ (rectWidth / 2) - 17,
+ modY,
+ 40
+ )
);
break;
}
diff --git a/src/main/java/org/saturnclient/ui/SaturnUi.java b/src/main/java/org/saturnclient/ui/SaturnUi.java
index 7de6326..354667d 100644
--- a/src/main/java/org/saturnclient/ui/SaturnUi.java
+++ b/src/main/java/org/saturnclient/ui/SaturnUi.java
@@ -5,21 +5,23 @@ import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
-
-import org.lwjgl.glfw.GLFW;
-
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
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 ScheduledExecutorService scheduler =
+ Executors.newSingleThreadScheduledExecutor();
public static MutableText text(String text) {
- return Text.literal(text).setStyle(Style.EMPTY.withFont(Identifier.of("saturnclient:panton")));
+ return Text.literal(text).setStyle(
+ Style.EMPTY.withFont(Identifier.of("saturnclient:panton"))
+ );
}
public List widgets = new ArrayList<>();
@@ -31,7 +33,12 @@ public class SaturnUi extends Screen {
@Override
protected void init() {
- scheduler.scheduleAtFixedRate(this::saturnTick, 0, 7, TimeUnit.MILLISECONDS);
+ scheduler.scheduleAtFixedRate(
+ this::saturnTick,
+ 0,
+ 7,
+ TimeUnit.MILLISECONDS
+ );
super.init();
}
@@ -43,16 +50,22 @@ public class SaturnUi extends Screen {
}
@Override
- public void render(DrawContext context, int mouseX, int mouseY, float delta) {
+ public void render(
+ DrawContext context,
+ int mouseX,
+ int mouseY,
+ float delta
+ ) {
renderBackground(context, mouseX, mouseY, delta);
for (SaturnWidget widget : new ArrayList<>(widgets)) {
- if (!widget.visible) {
- continue;
- }
+ if (!widget.visible) continue;
- boolean isMouseInside = widget.x < mouseX && widget.x + widget.width > mouseX
- && widget.y < mouseY && widget.y + widget.height > mouseY;
+ boolean isMouseInside =
+ widget.x < mouseX &&
+ widget.x + widget.width > mouseX &&
+ widget.y < mouseY &&
+ widget.y + widget.height > mouseY;
widget.render(context, isMouseInside, mouseX, mouseY);
}
}
@@ -61,13 +74,16 @@ public class SaturnUi extends Screen {
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (button == 0) {
for (SaturnWidget widget : new ArrayList<>(widgets)) {
- if (!widget.visible) {
- continue;
- }
+ widget.focused = false;
+ if (!widget.visible) continue;
- boolean isMouseInside = widget.x < mouseX && widget.x + widget.width > mouseX
- && widget.y < mouseY && widget.y + widget.height > mouseY;
+ boolean isMouseInside =
+ widget.x < mouseX &&
+ widget.x + widget.width > mouseX &&
+ widget.y < mouseY &&
+ widget.y + widget.height > mouseY;
if (isMouseInside) {
+ widget.focused = true;
widget.click((int) mouseX, (int) mouseY);
}
}
@@ -79,9 +95,7 @@ public class SaturnUi extends Screen {
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
for (SaturnWidget widget : new ArrayList<>(widgets)) {
- if (!widget.visible) {
- continue;
- }
+ if (!widget.visible && !widget.focused) continue;
widget.keyPressed(keyCode, scanCode, modifiers);
@@ -94,17 +108,35 @@ public class SaturnUi extends Screen {
}
@Override
- public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {
+ public boolean mouseScrolled(
+ double mouseX,
+ double mouseY,
+ double horizontalAmount,
+ double verticalAmount
+ ) {
for (SaturnWidget widget : new ArrayList<>(widgets)) {
- boolean isMouseInside = widget.x < mouseX && widget.x + widget.width > mouseX
- && widget.y < mouseY && widget.y + widget.height > mouseY;
+ boolean isMouseInside =
+ widget.x < mouseX &&
+ widget.x + widget.width > mouseX &&
+ widget.y < mouseY &&
+ widget.y + widget.height > mouseY;
if (isMouseInside) {
- widget.mouseScrolled((int) mouseX, (int) mouseY, horizontalAmount, verticalAmount);
+ widget.mouseScrolled(
+ (int) mouseX,
+ (int) mouseY,
+ horizontalAmount,
+ verticalAmount
+ );
}
}
- return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount);
+ return super.mouseScrolled(
+ mouseX,
+ mouseY,
+ horizontalAmount,
+ verticalAmount
+ );
}
private char getCharFromKey(int keyCode, int modifiers) {
@@ -112,12 +144,16 @@ public class SaturnUi extends Screen {
// 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));
+ 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));
+ return shift
+ ? ")!@#$%^&*(".charAt(keyCode - GLFW.GLFW_KEY_0)
+ : (char) ('0' + (keyCode - GLFW.GLFW_KEY_0));
}
// Special characters
@@ -143,7 +179,10 @@ public class SaturnUi extends Screen {
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 != null &&
+ tick - animation.lastTick == animation.delay
+ ) {
if (animation.run(widget, tick)) {
animation = null;
} else {
diff --git a/src/main/java/org/saturnclient/ui/SaturnWidget.java b/src/main/java/org/saturnclient/ui/SaturnWidget.java
index efaf8f1..a5ba0b2 100644
--- a/src/main/java/org/saturnclient/ui/SaturnWidget.java
+++ b/src/main/java/org/saturnclient/ui/SaturnWidget.java
@@ -11,6 +11,7 @@ public class SaturnWidget {
public float alpha = 1.0f;
public SaturnAnimation[] animations = null;
public boolean visible = true;
+ public boolean focused = false;
public void init() {}
diff --git a/src/main/java/org/saturnclient/ui/components/SaturnInteger.java b/src/main/java/org/saturnclient/ui/components/SaturnInteger.java
new file mode 100644
index 0000000..34c968e
--- /dev/null
+++ b/src/main/java/org/saturnclient/ui/components/SaturnInteger.java
@@ -0,0 +1,185 @@
+package org.saturnclient.ui.components;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.render.RenderLayer;
+import org.lwjgl.glfw.GLFW;
+import org.saturnclient.saturnclient.SaturnClient;
+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 prop;
+ public int cursorPosition = 0;
+ private TextRenderer textRenderer = MinecraftClient.getInstance()
+ .textRenderer;
+
+ public SaturnInteger(Property 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;
+ }
+
+ @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 - x)) {
+ break;
+ }
+
+ newCursorPos++;
+ }
+
+ cursorPosition = newCursorPos;
+ }
+
+ @Override
+ public void charTyped(char chr) {
+ SaturnClient.LOGGER.info("current digit: " + 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);
+
+ 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);
+ }
+ } 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
+ ) {
+ context.drawGuiTexture(
+ RenderLayer::getGuiTextured,
+ Textures.BUTTON,
+ this.x,
+ this.y,
+ this.width,
+ this.height,
+ SaturnClient.getWhite(this.alpha)
+ );
+
+ int scrollOffset = getScrollOffset();
+ String visibleText = getVisibleText(scrollOffset);
+
+ int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
+ context.drawText(
+ textRenderer,
+ SaturnUi.text(visibleText),
+ x + 2,
+ y + 2,
+ textColor,
+ false
+ );
+
+ if (focused) {
+ int cursorX =
+ x +
+ 2 +
+ textRenderer.getWidth(
+ SaturnUi.text(
+ visibleText.substring(0, cursorPosition - scrollOffset)
+ )
+ );
+ context.fill(
+ cursorX,
+ y + 2,
+ cursorX + 1,
+ y + 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 (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;
+ }
+}
diff --git a/src/main/java/org/saturnclient/ui/widgets/SaturnScroll.java b/src/main/java/org/saturnclient/ui/widgets/SaturnScroll.java
index ae5a550..5376135 100644
--- a/src/main/java/org/saturnclient/ui/widgets/SaturnScroll.java
+++ b/src/main/java/org/saturnclient/ui/widgets/SaturnScroll.java
@@ -2,19 +2,22 @@ package org.saturnclient.ui.widgets;
import java.util.ArrayList;
import java.util.List;
-
+import net.minecraft.client.gui.DrawContext;
import org.saturnclient.ui.SaturnWidget;
-import net.minecraft.client.gui.DrawContext;
-
public class SaturnScroll extends SaturnWidget {
+
private int scroll = 0;
private int maxScroll = 0;
private List children = new ArrayList<>();
@Override
- public void mouseScrolled(int mouseX, int mouseY, double horizontalAmount,
- double verticalAmount) {
+ public void mouseScrolled(
+ int mouseX,
+ int mouseY,
+ double horizontalAmount,
+ double verticalAmount
+ ) {
if (scroll - verticalAmount <= 0) {
scroll = 0;
} else if (scroll - verticalAmount >= maxScroll) {
@@ -25,18 +28,28 @@ public class SaturnScroll extends SaturnWidget {
}
@Override
- public void render(DrawContext context, boolean hovering, int mouseX, int mouseY) {
+ public void render(
+ DrawContext context,
+ boolean hovering,
+ int mouseX,
+ int mouseY
+ ) {
context.enableScissor(x, y, x + width, y + height);
for (SaturnWidget child : children) {
+ if (!child.visible) continue;
+
int xx = child.x;
int yy = child.y;
child.x += x;
child.y += y - scroll;
- boolean isMouseInside = child.x < mouseX && child.x + child.width > mouseX
- && child.y < mouseY && child.y + child.height > mouseY;
+ boolean isMouseInside =
+ child.x < mouseX &&
+ child.x + child.width > mouseX &&
+ child.y < mouseY &&
+ child.y + child.height > mouseY;
if (child.y < y + height && child.y + child.height > y) {
child.render(context, isMouseInside, mouseX, mouseY);
@@ -49,21 +62,6 @@ public class SaturnScroll extends SaturnWidget {
context.disableScissor();
}
- @Override
- public void click(int mouseX, int mouseY) {
- mouseX = mouseX - x;
- mouseY = mouseY - y;
- for (SaturnWidget child : children) {
- boolean isMouseInside = child.x < mouseX && child.x + child.width > mouseX
- && child.y < mouseY && child.y + child.height > mouseY;
-
- if (isMouseInside) {
- child.click(mouseX, mouseY);
- return;
- }
- }
- }
-
@Override
public void init() {
if (isScrollable()) {
@@ -88,4 +86,88 @@ public class SaturnScroll extends SaturnWidget {
}
return false;
}
+
+ @Override
+ public void keyPressed(int keyCode, int scanCode, int modifiers) {
+ System.out.println(
+ "[SaturnScroll] Key Pressed: keyCode=" +
+ keyCode +
+ ", scanCode=" +
+ scanCode +
+ ", modifiers=" +
+ modifiers
+ );
+
+ for (SaturnWidget child : children) {
+ if (!child.visible || !child.focused) {
+ System.out.println(
+ "[SaturnScroll] Skipping child " +
+ child +
+ " (Not visible or focused)"
+ );
+ continue;
+ }
+
+ System.out.println(
+ "[SaturnScroll] Passing key event to child: " + child
+ );
+ child.keyPressed(keyCode, scanCode, modifiers);
+ break;
+ }
+ }
+
+ @Override
+ public void charTyped(char typedChar) {
+ System.out.println("[SaturnScroll] Char Typed: '" + typedChar + "'");
+
+ for (SaturnWidget child : children) {
+ if (!child.visible || !child.focused) {
+ System.out.println(
+ "[SaturnScroll] Skipping child " +
+ child +
+ " (Not visible or focused)"
+ );
+ continue;
+ }
+
+ System.out.println(
+ "[SaturnScroll] Passing char event to child: " + child
+ );
+ child.charTyped(typedChar);
+ break;
+ }
+ }
+
+ @Override
+ public void click(int mouseX, int mouseY) {
+ System.out.println(
+ "[SaturnScroll] Click at: x=" + mouseX + ", y=" + mouseY
+ );
+
+ mouseX -= x;
+ mouseY -= (y - scroll);
+
+ for (SaturnWidget widget : children) {
+ widget.focused = false;
+ if (!widget.visible) {
+ System.out.println(
+ "[SaturnScroll] Skipping hidden child: " + widget
+ );
+ continue;
+ }
+
+ boolean isMouseInside =
+ widget.x < mouseX &&
+ widget.x + widget.width > mouseX &&
+ widget.y < mouseY &&
+ widget.y + widget.height > mouseY;
+
+ if (isMouseInside) {
+ System.out.println("[SaturnScroll] Child clicked: " + widget);
+ widget.focused = true;
+ widget.click(mouseX, mouseY);
+ break;
+ }
+ }
+ }
}