Add GUI scale sliders for Saturn's screens

The title screen, the menus and the HUD menus (emote wheel, shift menu)
each get a scale slider, relative to Minecraft's GUI scale. The HUD
editor stays in GUI pixels.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-09-28 18:59:47 +02:00
co-authored by claude
parent ef0ead6bf8
commit a7e3e537b1
6 changed files with 90 additions and 23 deletions
@@ -6,6 +6,7 @@ import java.util.ArrayList;
import java.util.List;
import org.saturnclient.config.Config;
import org.saturnclient.config.property.FloatProperty;
public abstract class SaturnScreen {
/** How long the background blur takes to fade in, in ms */
@@ -14,8 +15,10 @@ public abstract class SaturnScreen {
public static interface ScreenProvider {
public void close();
/** The screen's width in GUI pixels */
public int getWidth();
/** The screen's height in GUI pixels */
public int getHeight();
}
@@ -23,6 +26,10 @@ public abstract class SaturnScreen {
public int width;
public int height;
public String title;
/** GUI pixels per Saturn unit, from {@link #getScale()} when the screen was built */
public float scale = 0.5f;
/** Whether a mouse button is held, so the screen isn't rebuilt under a drag */
private boolean mouseDown = false;
// Saturn Screen
public List<Element> elements = new ArrayList<>();
@@ -51,10 +58,39 @@ public abstract class SaturnScreen {
return Math.round(Config.backgroundBlur.value * Math.min(elapsed / (float) BLUR_FADE_IN, 1f));
}
/**
* The GUI scale setting this screen follows; the menu scale unless the
* screen is another kind.
*/
protected FloatProperty getScaleSetting() {
return Config.menuScale;
}
/**
* GUI pixels per Saturn unit. At 1× a Saturn unit is half a GUI pixel.
* Enlarging stops where the screen would be smaller than 320x240 GUI
* pixels, the least Minecraft's own GUI scale leaves.
*/
public float getScale() {
float fit = Math.min(provider.getWidth() / 320f, provider.getHeight() / 240f);
return 0.5f * Math.min(getScaleSetting().value, Math.max(1f, fit));
}
/**
* Rebuilds the screen if its scale setting changed, once no drag is going
* on (the slider being dragged would be replaced).
*/
public void updateScale() {
if (!mouseDown && getScale() != scale) {
init();
}
}
public void init() {
elements.clear();
width = provider.getWidth();
height = provider.getHeight();
scale = getScale();
width = (int) (provider.getWidth() / scale);
height = (int) (provider.getHeight() / scale);
Popup.reset(width, height);
ui(); // abstraction to render the saturn ui and also render extra stuff here
}
@@ -72,7 +108,7 @@ public abstract class SaturnScreen {
public void render(RenderScope renderScope, int mouseX, int mouseY, float delta, long elapsed) {
renderScope.getMatrixStack().push();
renderScope.getMatrixStack().scale(0.5f, 0.5f);
renderScope.getMatrixStack().scale(scale, scale);
ElementRenderer.render(new ArrayList<>(elements), elapsed, renderScope, mouseX, mouseY);
Popup.render(renderScope, elapsed, mouseX, mouseY);
@@ -85,8 +121,9 @@ public abstract class SaturnScreen {
// --------------
public boolean mouseClicked(double mouseX, double mouseY, int button) {
mouseX *= 2;
mouseY *= 2;
mouseDown = true;
mouseX /= scale;
mouseY /= scale;
if (!Popup.mouseClicked(mouseX, mouseY, button)) {
ElementRenderer.mouseClicked(elements, mouseX, mouseY, button);
@@ -96,8 +133,8 @@ public abstract class SaturnScreen {
}
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
mouseX *= 2;
mouseY *= 2;
mouseX /= scale;
mouseY /= scale;
if (!Popup.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)) {
ElementRenderer.mouseDragged(elements, mouseX, mouseY, button, deltaX, deltaY);
@@ -107,8 +144,9 @@ public abstract class SaturnScreen {
}
public boolean mouseReleased(double mouseX, double mouseY, int button) {
mouseX *= 2;
mouseY *= 2;
mouseDown = false;
mouseX /= scale;
mouseY /= scale;
// Everything hears the release, so no element is left thinking it's being dragged.
Popup.mouseReleased(mouseX, mouseY, button);
@@ -122,8 +160,8 @@ public abstract class SaturnScreen {
double mouseY,
double horizontalAmount,
double verticalAmount) {
mouseX *= 2;
mouseY *= 2;
mouseX /= scale;
mouseY /= scale;
if (!Popup.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)) {
ElementRenderer.mouseScrolled(elements, mouseX, mouseY, horizontalAmount, verticalAmount);