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:
@@ -0,0 +1,54 @@
|
||||
package org.saturnclient.ui.components;
|
||||
|
||||
import org.saturnclient.client.ServiceClient;
|
||||
import org.saturnclient.common.provider.Providers;
|
||||
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;
|
||||
import org.saturnclient.ui.elements.Field;
|
||||
import org.saturnclient.ui.resources.Fonts;
|
||||
|
||||
/**
|
||||
* The signed-in player: their skin's face, their name, and a dot that's green
|
||||
* while connected to Saturn.
|
||||
*/
|
||||
public class AccountChip extends Element {
|
||||
public static final int HEIGHT = 40;
|
||||
|
||||
private static final int HEAD = 28;
|
||||
private static final int PADDING = 6;
|
||||
private static final int DOT = 7;
|
||||
private static final float NAME_SCALE = 0.7f;
|
||||
private static final int CONNECTED = 0xFF7FD1A8;
|
||||
|
||||
private final String name;
|
||||
|
||||
public AccountChip() {
|
||||
String username = Providers.saturn.getClient().getUsername();
|
||||
this.name = username != null ? username : "Player";
|
||||
this.height = HEIGHT;
|
||||
this.width = PADDING + HEAD + 10 + (int) (Fonts.getWidth(name, Theme.FONT.value) * NAME_SCALE) + 10 + DOT + 12;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value, 1, Theme.getPanelBg(),
|
||||
Theme.getBorder());
|
||||
|
||||
// The face, then the hat layer over it, from the 64x64 skin
|
||||
IdentifierRef skin = Providers.saturn.getPlayerSkin();
|
||||
int headY = (height - HEAD) / 2;
|
||||
renderScope.drawTexture(skin, PADDING, headY, 8, 8, HEAD, HEAD, 8, 8, 64, 64);
|
||||
renderScope.drawTexture(skin, PADDING, headY, 40, 8, HEAD, HEAD, 8, 8, 64, 64);
|
||||
|
||||
int nameX = PADDING + HEAD + 10;
|
||||
renderScope.drawText(NAME_SCALE, name, nameX, Field.textY(height, NAME_SCALE), Theme.FONT.value,
|
||||
Theme.FOREGROUND.value);
|
||||
|
||||
int dotX = nameX + (int) (Fonts.getWidth(name, Theme.FONT.value) * NAME_SCALE) + 10;
|
||||
renderScope.drawRoundedRectangle(dotX, (height - DOT) / 2, DOT, DOT, DOT / 2,
|
||||
ServiceClient.isConnected() ? CONNECTED : Theme.withAlpha(0.3f, Theme.FOREGROUND.value));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package org.saturnclient.ui.components;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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;
|
||||
import org.saturnclient.ui.elements.Field;
|
||||
import org.saturnclient.ui.resources.Fonts;
|
||||
|
||||
/**
|
||||
* A glass bar of buttons, each an icon with its label.
|
||||
*/
|
||||
public class Dock extends Element {
|
||||
public record Item(IdentifierRef icon, String label, Runnable onClick) {
|
||||
}
|
||||
|
||||
public static final int HEIGHT = 52;
|
||||
|
||||
private static final int PADDING = 6;
|
||||
private static final int ITEM_HEIGHT = HEIGHT - PADDING * 2;
|
||||
private static final int ITEM_PADDING = 14;
|
||||
private static final int ICON = 17;
|
||||
private static final int ICON_GAP = 8;
|
||||
private static final int GAP = 4;
|
||||
private static final float TEXT_SCALE = 0.7f;
|
||||
|
||||
private final List<Item> items;
|
||||
|
||||
public Dock(List<Item> items) {
|
||||
this.items = items;
|
||||
this.height = HEIGHT;
|
||||
this.width = getItemX(items.size()) - GAP + PADDING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value + 4, 1, Theme.getPanelBg(),
|
||||
Theme.withAlpha(0.1f, Theme.FOREGROUND.value));
|
||||
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
Item item = items.get(i);
|
||||
int x = getItemX(i);
|
||||
int itemWidth = getItemWidth(item);
|
||||
boolean hovered = ctx.isHovering(x, PADDING, itemWidth, ITEM_HEIGHT);
|
||||
|
||||
if (hovered) {
|
||||
renderScope.drawRoundedRectangle(x, PADDING, itemWidth, ITEM_HEIGHT, Theme.WIDGET_RADIUS.value,
|
||||
Theme.withAlpha(0.08f, Theme.FOREGROUND.value));
|
||||
}
|
||||
|
||||
int color = hovered ? Theme.ACCENT.value : Theme.PRIMARY_FG.value;
|
||||
renderScope.drawTexture(item.icon(), x + ITEM_PADDING, PADDING + (ITEM_HEIGHT - ICON) / 2, 0, 0, ICON,
|
||||
ICON, color);
|
||||
renderScope.drawText(TEXT_SCALE, item.label(), x + ITEM_PADDING + ICON + ICON_GAP,
|
||||
PADDING + Field.textY(ITEM_HEIGHT, TEXT_SCALE), Theme.FONT.value,
|
||||
hovered ? Theme.FOREGROUND.value : Theme.PRIMARY_FG.value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(int mouseX, int mouseY) {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
int x = getItemX(i);
|
||||
if (mouseX >= x && mouseX <= x + getItemWidth(items.get(i))) {
|
||||
items.get(i).onClick().run();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getItemX(int index) {
|
||||
int x = PADDING;
|
||||
for (int i = 0; i < index; i++) {
|
||||
x += getItemWidth(items.get(i)) + GAP;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
private static int getItemWidth(Item item) {
|
||||
return ITEM_PADDING * 2 + ICON + ICON_GAP + (int) (Fonts.getWidth(item.label(), Theme.FONT.value) * TEXT_SCALE);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user