Redesign mod settings
A mod's settings button now opens ModSettings: a header with the mod's icon, name, version, tags and description, a Reset button and an on/off switch, then its properties as rows, with nested namespaces as titled sections and a live preview card beside them for HUD mods. PanelScreen holds the sidebar-and-panel frame that the mod menu, mod settings and config editor share. PropertyList lays out any config as rows. The inputs share one field look: Toggle is a switch, Select steps with arrows, and the number, keybinding and color inputs are boxes. The color picker opens to the left and closes on outside clicks. Every property type now implements reset(), which was a no-op, and ModLayout keeps its settings in order instead of Map.of's. ConfigEditor moves onto the same frame and rows and drops its HUD preview, which added a new element every frame. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
package org.saturnclient.ui.components;
|
||||
|
||||
import org.saturnclient.config.Theme;
|
||||
import org.saturnclient.mod.Mod;
|
||||
import org.saturnclient.ui.Element;
|
||||
import org.saturnclient.ui.ElementContext;
|
||||
import org.saturnclient.ui.RenderScope;
|
||||
import org.saturnclient.ui.resources.Fonts;
|
||||
|
||||
/**
|
||||
* The top of a mod's settings: its icon, name, version and tags, and description.
|
||||
*/
|
||||
public class ModHeader extends Element {
|
||||
public static final int HEIGHT = 60;
|
||||
|
||||
private static final int ICON = 30;
|
||||
private static final int TEXT_X = HEIGHT + 16;
|
||||
private static final float NAME_SCALE = 1.2f;
|
||||
private static final float DESCRIPTION_SCALE = 0.7f;
|
||||
|
||||
private static final int CHIP_HEIGHT = 22;
|
||||
private static final int CHIP_PADDING = 8;
|
||||
private static final int CHIP_GAP = 6;
|
||||
private static final float CHIP_SCALE = 0.58f;
|
||||
|
||||
private final Mod mod;
|
||||
|
||||
public ModHeader(Mod mod, int width) {
|
||||
this.mod = mod;
|
||||
this.width = width;
|
||||
this.height = HEIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
boolean enabled = mod.isEnabled();
|
||||
|
||||
// Icon
|
||||
renderScope.drawRoundedRectangle(0, 0, HEIGHT, HEIGHT, Theme.WIDGET_RADIUS.value + 4,
|
||||
enabled ? Theme.withAlpha(0.18f, Theme.ACCENT.value) : Theme.withAlpha(0.06f, Theme.FOREGROUND.value));
|
||||
renderScope.drawTexture(mod.getIconTexture(), (HEIGHT - ICON) / 2, (HEIGHT - ICON) / 2, 0, 0, ICON, ICON,
|
||||
Theme.PRIMARY_FG.value);
|
||||
|
||||
// Name, then the version and tags as chips
|
||||
int nameHeight = (int) (Fonts.getHeight() * NAME_SCALE);
|
||||
int nameY = 4;
|
||||
renderScope.drawText(NAME_SCALE, mod.getName(), TEXT_X, nameY, Theme.FONT.value, Theme.FOREGROUND.value);
|
||||
|
||||
int chipX = TEXT_X + (int) (Fonts.getWidth(mod.getName(), Theme.FONT.value) * NAME_SCALE) + 12;
|
||||
int chipY = nameY + (nameHeight - CHIP_HEIGHT) / 2;
|
||||
|
||||
if (mod.getVersion() != null) {
|
||||
chipX = drawChip(renderScope, mod.getVersion(), chipX, chipY, false) + CHIP_GAP;
|
||||
}
|
||||
|
||||
for (String tag : mod.getTags()) {
|
||||
chipX = drawChip(renderScope, tag, chipX, chipY, true) + CHIP_GAP;
|
||||
}
|
||||
|
||||
// Description
|
||||
if (mod.getDescription() != null) {
|
||||
String description = Fonts.ellipsize(mod.getDescription(), Theme.getBodyFont(), DESCRIPTION_SCALE,
|
||||
width - TEXT_X);
|
||||
renderScope.drawText(DESCRIPTION_SCALE, description, TEXT_X, nameY + nameHeight + 8,
|
||||
Theme.getBodyFont(), Theme.getMutedFg());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the x after the chip
|
||||
*/
|
||||
private int drawChip(RenderScope renderScope, String text, int x, int y, boolean outlined) {
|
||||
int width = CHIP_PADDING * 2 + (int) (Fonts.getWidth(text, Theme.FONT.value) * CHIP_SCALE);
|
||||
|
||||
if (x + width > this.width) {
|
||||
return x;
|
||||
}
|
||||
|
||||
if (outlined) {
|
||||
renderScope.drawRoundedBorder(x, y, width, CHIP_HEIGHT, 6, 1, Theme.withAlpha(0.14f, Theme.FOREGROUND.value));
|
||||
} else {
|
||||
renderScope.drawRoundedRectangle(x, y, width, CHIP_HEIGHT, 6, Theme.withAlpha(0.07f, Theme.FOREGROUND.value));
|
||||
}
|
||||
|
||||
int textY = y + (CHIP_HEIGHT - (int) (Fonts.getHeight() * CHIP_SCALE)) / 2;
|
||||
renderScope.drawText(CHIP_SCALE, text, x + CHIP_PADDING, textY, Theme.FONT.value,
|
||||
outlined ? Theme.PRIMARY_FG.value : Theme.getMutedFg());
|
||||
|
||||
return x + width;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user