From 4d9c629eaf4f5d315d772d7e07336ff237369390 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Mon, 28 Sep 2026 20:43:44 +0200 Subject: [PATCH] Frost translucent panels with glass Panels whose background isn't solid draw the blurred game behind them, cut to the same rounded rectangle texture as the background, where the version supports glass. Panel screens then leave the rest of the game unblurred. Co-Authored-By: Claude Opus 5.5 --- .../common/provider/SaturnProvider.java | 6 +++ .../java/org/saturnclient/ui/PanelScreen.java | 4 ++ .../java/org/saturnclient/ui/RenderScope.java | 40 +++++++++++++++++-- .../org/saturnclient/ui/SaturnScreen.java | 16 ++++++-- .../org/saturnclient/ui/elements/Panel.java | 8 +++- 5 files changed, 65 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/saturnclient/common/provider/SaturnProvider.java b/src/main/java/org/saturnclient/common/provider/SaturnProvider.java index 4d63eec..998f539 100644 --- a/src/main/java/org/saturnclient/common/provider/SaturnProvider.java +++ b/src/main/java/org/saturnclient/common/provider/SaturnProvider.java @@ -28,6 +28,12 @@ public interface SaturnProvider { */ public IdentifierRef getPlayerSkin(); + /** + * Whether this version draws glass (the blurred game behind translucent + * panels), so screens needn't blur the whole background. + */ + public boolean supportsGlass(); + /** Shows a warning toast. Safe to call from any thread. */ public void showWarning(String title, String message); } diff --git a/src/main/java/org/saturnclient/ui/PanelScreen.java b/src/main/java/org/saturnclient/ui/PanelScreen.java index 2bf84a2..e8c8380 100644 --- a/src/main/java/org/saturnclient/ui/PanelScreen.java +++ b/src/main/java/org/saturnclient/ui/PanelScreen.java @@ -1,5 +1,6 @@ package org.saturnclient.ui; +import org.saturnclient.common.provider.Providers; import org.saturnclient.ui.components.Sidebar; import org.saturnclient.ui.elements.ImageTexture; import org.saturnclient.ui.elements.Panel; @@ -38,6 +39,9 @@ public abstract class PanelScreen extends SaturnScreen { @Override public final void ui() { + // The panels are frosted themselves, so the rest of the game stays clear. + blurBackground = !Providers.saturn.supportsGlass(); + panelWidth = Math.min(MAX_WIDTH, width - MARGIN * 2 - Sidebar.WIDTH - GAP); panelHeight = Math.min(MAX_HEIGHT, height - MARGIN * 2); diff --git a/src/main/java/org/saturnclient/ui/RenderScope.java b/src/main/java/org/saturnclient/ui/RenderScope.java index 0bbc677..808da81 100644 --- a/src/main/java/org/saturnclient/ui/RenderScope.java +++ b/src/main/java/org/saturnclient/ui/RenderScope.java @@ -34,6 +34,14 @@ public interface RenderScope { if (color == 0) return; + drawTexture(getRoundedRectangle(width, height, radius), x, y, 0, 0, width, height, color); + } + + /** + * The white rounded rectangle that {@link #drawRoundedRectangle} tints, as a + * cached texture. + */ + default IdentifierRef getRoundedRectangle(int width, int height, int radius) { radius = Math.min(radius, width / 2); radius = Math.min(radius, height / 2); @@ -42,7 +50,24 @@ public interface RenderScope { width, height, radius, radius); - drawSvgShape(rect, "rounded_" + width + "_" + height + "_" + radius, x, y, width, height, color); + return getSvgShape(rect, "rounded_" + width + "_" + height + "_" + radius, width, height); + } + + /** + * Frosts a rounded rectangle for a translucent background to be drawn over: + * the game behind the screen, blurred, cut to exactly the shape + * {@link #drawRoundedRectangle} draws. Draws nothing on versions without + * glass. + */ + default void drawGlass(int x, int y, int width, int height, int radius) { + drawGlass(getRoundedRectangle(width, height, radius), x, y, width, height); + } + + /** + * Draws the blurred game behind the screen where {@code mask}, stretched + * over the area, is opaque. + */ + default void drawGlass(IdentifierRef mask, int x, int y, int width, int height) { } /** @@ -89,15 +114,22 @@ public interface RenderScope { * {@code color}. */ private void drawSvgShape(String shape, String cacheKey, int x, int y, int width, int height, int color) { + drawTexture(getSvgShape(shape, cacheKey, width, height), x, y, 0, 0, width, height, color); + } + + /** + * {@code shape} (SVG elements in a {@code width} x {@code height} canvas, + * drawn in white) rendered to a cached texture. + */ + private IdentifierRef getSvgShape(String shape, String cacheKey, int width, int height) { String svg = String.format( "%s", width, height, shape); InputStream svgStream = new ByteArrayInputStream(svg.getBytes(StandardCharsets.UTF_8)); - drawTexture(SvgTexture.getSvg(svgStream, - IdentifierRef.ofSaturn("textures/gui/tmp_rect/" + cacheKey), - width * 4, height * 4), x, y, 0, 0, width, height, color); + return SvgTexture.getSvg(svgStream, IdentifierRef.ofSaturn("textures/gui/tmp_rect/" + cacheKey), + width * 4, height * 4); } void drawBorder(int x, int y, int width, int height, int color); diff --git a/src/main/java/org/saturnclient/ui/SaturnScreen.java b/src/main/java/org/saturnclient/ui/SaturnScreen.java index 14e6b46..a730b3d 100644 --- a/src/main/java/org/saturnclient/ui/SaturnScreen.java +++ b/src/main/java/org/saturnclient/ui/SaturnScreen.java @@ -46,11 +46,11 @@ public abstract class SaturnScreen { } /** - * How much to blur the game behind this screen right now: the client's - * setting, faded in over the screen's first moments. + * How much to blur the game behind this screen and its glass right now: the + * client's setting, faded in over the screen's first moments. */ - public int getBackgroundBlur() { - if (!blurBackground || start == null) { + public int getBlurRadius() { + if (start == null) { return 0; } @@ -58,6 +58,14 @@ public abstract class SaturnScreen { return Math.round(Config.backgroundBlur.value * Math.min(elapsed / (float) BLUR_FADE_IN, 1f)); } + /** + * How much to blur the whole game behind this screen right now, or 0 when it + * isn't. + */ + public int getBackgroundBlur() { + return blurBackground ? getBlurRadius() : 0; + } + /** * The GUI scale setting this screen follows; the menu scale unless the * screen is another kind. diff --git a/src/main/java/org/saturnclient/ui/elements/Panel.java b/src/main/java/org/saturnclient/ui/elements/Panel.java index 2b3369e..5392842 100644 --- a/src/main/java/org/saturnclient/ui/elements/Panel.java +++ b/src/main/java/org/saturnclient/ui/elements/Panel.java @@ -6,7 +6,8 @@ import org.saturnclient.ui.ElementContext; import org.saturnclient.ui.RenderScope; /** - * The translucent, outlined surface that screens lay their content on. + * The translucent, outlined surface that screens lay their content on, + * frosted over the game where glass is supported. */ public class Panel extends Element { @@ -16,6 +17,11 @@ public class Panel extends Element { } public static void drawBackground(RenderScope renderScope, int width, int height) { + // Frosted behind a background that isn't solid + if (Theme.getPanelBg() >>> 24 < 0xFF) { + renderScope.drawGlass(0, 0, width, height, Theme.BG_RADIUS.value); + } + renderScope.drawRoundedRectangle(0, 0, width, height, Theme.BG_RADIUS.value, 1, Theme.getPanelBg(), Theme.getBorder()); }