Restyle buttons, the Shift menu and the title screen
Button is now primary (accent fill) or secondary (a translucent outlined surface), and IconButton is a square secondary button with a Lucide icon, replacing the PNG TextureButtons. Neither is scaled with Element.scale any more, which multiplied click positions instead of dividing them. The Shift menu is the HUD editor, the mod menu (its button was labelled "Settings") and cosmetics. The title screen centers the logo over a compact stack of the game's menus, with the player, a dock of Saturn's screens and the version along the bottom. The player chip shows the player's face from their skin and whether they're connected to Saturn. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -6,24 +6,52 @@ import org.saturnclient.ui.ElementContext;
|
||||
import org.saturnclient.ui.RenderScope;
|
||||
import org.saturnclient.ui.resources.Fonts;
|
||||
|
||||
/**
|
||||
* A text button: primary (filled with the accent color) for the main action,
|
||||
* or secondary (a translucent, outlined surface) for the rest.
|
||||
*/
|
||||
public class Button extends Element {
|
||||
private String text;
|
||||
private Runnable onClick;
|
||||
public static final int HEIGHT = 40;
|
||||
|
||||
public Button(String text, Runnable onClick) {
|
||||
private static final float TEXT_SCALE = 0.72f;
|
||||
|
||||
private final String text;
|
||||
private final boolean primary;
|
||||
private final Runnable onClick;
|
||||
|
||||
public Button(String text, boolean primary, Runnable onClick) {
|
||||
this.text = text;
|
||||
this.primary = primary;
|
||||
this.onClick = onClick;
|
||||
this.dimensions(Fonts.getWidth(text, Theme.FONT.value) + 50, 38);
|
||||
this.width = (int) (Fonts.getWidth(text, Theme.FONT.value) * TEXT_SCALE) + 48;
|
||||
this.height = HEIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value,
|
||||
ctx.isHovering() ? Theme.ACCENT.value : Theme.PRIMARY.value);
|
||||
boolean hovered = ctx.isHovering();
|
||||
drawSurface(renderScope, width, height, primary, hovered);
|
||||
|
||||
renderScope.drawText(text, Fonts.centerX(width, text, Theme.FONT.value), Fonts.centerY(height),
|
||||
Theme.FONT.value,
|
||||
ctx.isHovering() ? Theme.ACCENT_FG.value : Theme.PRIMARY_FG.value);
|
||||
int textX = (width - (int) (Fonts.getWidth(text, Theme.FONT.value) * TEXT_SCALE)) / 2;
|
||||
renderScope.drawText(TEXT_SCALE, text, textX, Field.textY(height, TEXT_SCALE), Theme.FONT.value,
|
||||
primary ? Theme.ACCENT_FG.value : hovered ? Theme.FOREGROUND.value : Theme.PRIMARY_FG.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The button's surface, shared with {@link IconButton}.
|
||||
*/
|
||||
static void drawSurface(RenderScope renderScope, int width, int height, boolean primary, boolean hovered) {
|
||||
if (primary) {
|
||||
// Lighten the accent on hover by laying white over it
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value, Theme.ACCENT.value);
|
||||
if (hovered) {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value, 0x26FFFFFF);
|
||||
}
|
||||
} else {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value, 1,
|
||||
hovered ? Theme.withAlpha(0.9f, Theme.PRIMARY.value) : Theme.getPanelBg(),
|
||||
Theme.withAlpha(hovered ? 0.25f : 0.1f, Theme.FOREGROUND.value));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.saturnclient.ui.elements;
|
||||
|
||||
import org.saturnclient.common.ref.asset.IdentifierRef;
|
||||
import org.saturnclient.config.Theme;
|
||||
import org.saturnclient.ui.Element;
|
||||
import org.saturnclient.ui.ElementContext;
|
||||
import org.saturnclient.ui.RenderScope;
|
||||
|
||||
/**
|
||||
* A square secondary {@link Button} showing an icon, which turns the accent
|
||||
* color on hover.
|
||||
*/
|
||||
public class IconButton extends Element {
|
||||
private static final float ICON_RATIO = 0.48f;
|
||||
|
||||
private final IdentifierRef icon;
|
||||
private final Runnable onClick;
|
||||
|
||||
public IconButton(IdentifierRef icon, Runnable onClick) {
|
||||
this.icon = icon;
|
||||
this.onClick = onClick;
|
||||
this.width = Button.HEIGHT;
|
||||
this.height = Button.HEIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
boolean hovered = ctx.isHovering();
|
||||
Button.drawSurface(renderScope, width, height, false, hovered);
|
||||
|
||||
int size = (int) (Math.min(width, height) * ICON_RATIO);
|
||||
renderScope.drawTexture(icon, (width - size) / 2, (height - size) / 2, 0, 0, size, size,
|
||||
hovered ? Theme.ACCENT.value : Theme.PRIMARY_FG.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
onClick.run();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user