diff --git a/src/main/java/org/saturnclient/config/Theme.java b/src/main/java/org/saturnclient/config/Theme.java index 8a9af41..dbfca5f 100644 --- a/src/main/java/org/saturnclient/config/Theme.java +++ b/src/main/java/org/saturnclient/config/Theme.java @@ -1,11 +1,15 @@ package org.saturnclient.config; +import java.util.List; + import org.saturnclient.config.property.ColorProperty; import org.saturnclient.config.property.IntProperty; import org.saturnclient.config.property.Property; import org.saturnclient.config.property.SelectProperty; public class Theme { + public static ConfigManager config; + // Main UI background (slightly warm dark to match Saturn tone) public static final ColorProperty BACKGROUND = Property.color(0xFF12100D); @@ -34,8 +38,37 @@ public class Theme { // Font public static final SelectProperty FONT = Property.font(2); + /** + * A full set of theme colors that can be applied in one go. + */ + public record Preset(String name, int background, int foreground, int primary, int primaryFg, int accent, + int accentFg, int scroll) { + + public void apply() { + BACKGROUND.value = background; + FOREGROUND.value = foreground; + PRIMARY.value = primary; + PRIMARY_FG.value = primaryFg; + ACCENT.value = accent; + ACCENT_FG.value = accentFg; + SCROLL.value = scroll; + } + + public boolean isActive() { + return BACKGROUND.value == background && FOREGROUND.value == foreground && PRIMARY.value == primary + && PRIMARY_FG.value == primaryFg && ACCENT.value == accent && ACCENT_FG.value == accentFg + && SCROLL.value == scroll; + } + } + + public static final List PRESETS = List.of( + new Preset("Saturn", 0xFF12100D, 0xFFF2E6D2, 0xFF1C1915, 0xFFEAD9B8, 0xFFE2BF7D, 0xFF1A140A, 0xFFE2BF7D), + new Preset("Midnight", 0xFF0E1117, 0xFFE4EAF5, 0xFF171C26, 0xFFC9D4E8, 0xFF8FB3FF, 0xFF0A1224, 0xFF8FB3FF), + new Preset("Amethyst", 0xFF120F17, 0xFFEDE4F7, 0xFF1C1724, 0xFFD8C9EB, 0xFFC79BFF, 0xFF1A0F2A, 0xFFC79BFF), + new Preset("Emerald", 0xFF0D1210, 0xFFE2F2EA, 0xFF16201B, 0xFFC4E0D2, 0xFF7FD1A8, 0xFF0A1F15, 0xFF7FD1A8)); + public static void init(ConfigManager parent) { - ConfigManager config = new ConfigManager(parent, "UI Style"); + config = new ConfigManager(parent, "UI Style"); config.property("Background", BACKGROUND); config.property("Foreground", FOREGROUND); config.property("Primary", PRIMARY); diff --git a/src/main/java/org/saturnclient/ui/components/ColorGrid.java b/src/main/java/org/saturnclient/ui/components/ColorGrid.java new file mode 100644 index 0000000..3f785fc --- /dev/null +++ b/src/main/java/org/saturnclient/ui/components/ColorGrid.java @@ -0,0 +1,85 @@ +package org.saturnclient.ui.components; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.saturnclient.config.Theme; +import org.saturnclient.config.property.ColorProperty; +import org.saturnclient.config.property.Property; +import org.saturnclient.ui.Element; +import org.saturnclient.ui.ElementContext; +import org.saturnclient.ui.RenderScope; +import org.saturnclient.ui.components.inputs.ColorInput; +import org.saturnclient.ui.elements.Scroll; +import org.saturnclient.ui.resources.Fonts; + +/** + * Lays out the color properties of a config as a two-column grid of tiles, + * each with the color's name and its input. + */ +public final class ColorGrid { + private static final int COLUMNS = 2; + private static final int TILE_HEIGHT = 48; + private static final int GAP = 8; + private static final int INSET = 8; + + private ColorGrid() { + } + + /** + * Adds a tile for every {@link ColorProperty} in {@code properties} to + * {@code scroll}, starting at {@code y}. + * + * @return the y below the grid + */ + public static int draw(Scroll scroll, Map properties, int width, int y) { + int tileWidth = (width - GAP * (COLUMNS - 1)) / COLUMNS; + List inputs = new ArrayList<>(); + int i = 0; + + for (Map.Entry entry : properties.entrySet()) { + if (!(entry.getValue() instanceof ColorProperty color)) { + continue; + } + + int x = (i % COLUMNS) * (tileWidth + GAP); + int tileY = y + (i / COLUMNS) * (TILE_HEIGHT + GAP); + + ColorInput input = new ColorInput(color); + scroll.draw(new Tile(entry.getKey(), tileWidth, input.width).position(x, tileY)); + inputs.add(input.position(x + tileWidth - INSET - input.width, tileY + (TILE_HEIGHT - input.height) / 2)); + i++; + } + + // Inputs go on after every tile, so an open color picker covers the tiles below it. + inputs.forEach(scroll::draw); + + int rows = (i + COLUMNS - 1) / COLUMNS; + return y + rows * TILE_HEIGHT + Math.max(0, rows - 1) * GAP; + } + + private static class Tile extends Element { + private static final float NAME_SCALE = 0.7f; + + private final String name; + private final int inputWidth; + + Tile(String name, int width, int inputWidth) { + this.name = name; + this.inputWidth = inputWidth; + this.width = width; + this.height = TILE_HEIGHT; + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value, 1, + Theme.withAlpha(0.72f, Theme.PRIMARY.value), Theme.withAlpha(0.06f, Theme.FOREGROUND.value)); + + String text = Fonts.ellipsize(name, Theme.FONT.value, NAME_SCALE, width - inputWidth - INSET * 2 - 12); + int nameY = (height - (int) (Fonts.getHeight() * NAME_SCALE)) / 2; + renderScope.drawText(NAME_SCALE, text, 12, nameY, Theme.FONT.value, Theme.FOREGROUND.value); + } + } +} diff --git a/src/main/java/org/saturnclient/ui/components/PropertyList.java b/src/main/java/org/saturnclient/ui/components/PropertyList.java index b576c02..91e1a39 100644 --- a/src/main/java/org/saturnclient/ui/components/PropertyList.java +++ b/src/main/java/org/saturnclient/ui/components/PropertyList.java @@ -66,11 +66,7 @@ public final class PropertyList { } if (prop instanceof NamespaceProperty namespace) { - y += SECTION_GAP; - String title = name.toUpperCase(Locale.ROOT); - scroll.draw(new Label(() -> title, SECTION_SCALE, () -> Theme.FONT.value, Theme::getMutedFg) - .position(0, y)); - y += (int) (Fonts.getHeight() * SECTION_SCALE) + 4; + y = drawSection(scroll, name, y + SECTION_GAP) + 4; y = drawRows(scroll, namespace.value, Set.of(), width, y, controls); continue; } @@ -88,6 +84,17 @@ public final class PropertyList { return y; } + /** + * Adds a section title, such as a namespace's name, at {@code y}. + * + * @return the y below the title + */ + public static int drawSection(Scroll scroll, String name, int y) { + String title = name.toUpperCase(Locale.ROOT); + scroll.draw(new Label(() -> title, SECTION_SCALE, () -> Theme.FONT.value, Theme::getMutedFg).position(0, y)); + return y + (int) (Fonts.getHeight() * SECTION_SCALE); + } + /** * The input for a property, or null for types without one (strings). */ diff --git a/src/main/java/org/saturnclient/ui/components/SectionNav.java b/src/main/java/org/saturnclient/ui/components/SectionNav.java new file mode 100644 index 0000000..307c785 --- /dev/null +++ b/src/main/java/org/saturnclient/ui/components/SectionNav.java @@ -0,0 +1,84 @@ +package org.saturnclient.ui.components; + +import java.util.List; +import java.util.function.IntConsumer; + +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 vertical list of a screen's sections under a small heading, with the + * current one highlighted. + */ +public class SectionNav extends Element { + public record Item(IdentifierRef icon, String name) { + } + + private static final float HEADING_SCALE = 0.6f; + private static final int HEADING_HEIGHT = 26; + private static final int ITEM_HEIGHT = 40; + private static final int ITEM_GAP = 4; + private static final int ICON = 17; + private static final float TEXT_SCALE = 0.7f; + + private final String heading; + private final List items; + private final int active; + private final IntConsumer onSelect; + + public SectionNav(String heading, List items, int active, int width, IntConsumer onSelect) { + this.heading = heading; + this.items = items; + this.active = active; + this.onSelect = onSelect; + this.width = width; + this.height = HEADING_HEIGHT + items.size() * (ITEM_HEIGHT + ITEM_GAP); + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + renderScope.drawText(HEADING_SCALE, heading, 10, 0, Theme.FONT.value, Theme.getMutedFg()); + + for (int i = 0; i < items.size(); i++) { + Item item = items.get(i); + int y = getItemY(i); + boolean selected = i == active; + boolean hovered = ctx.isHovering(0, y, width, ITEM_HEIGHT); + + if (selected || hovered) { + renderScope.drawRoundedRectangle(0, y, width, ITEM_HEIGHT, Theme.WIDGET_RADIUS.value, + Theme.withAlpha(selected ? 0.08f : 0.04f, Theme.FOREGROUND.value)); + } + + renderScope.drawTexture(item.icon(), 12, y + (ITEM_HEIGHT - ICON) / 2, 0, 0, ICON, ICON, + selected ? Theme.ACCENT.value : Theme.getMutedFg()); + + String name = Fonts.ellipsize(item.name(), Theme.FONT.value, TEXT_SCALE, width - 12 - ICON - 10 - 8); + renderScope.drawText(TEXT_SCALE, name, 12 + ICON + 10, y + Field.textY(ITEM_HEIGHT, TEXT_SCALE), + Theme.FONT.value, selected ? Theme.FOREGROUND.value : Theme.PRIMARY_FG.value); + } + } + + @Override + public void click(int mouseX, int mouseY) { + for (int i = 0; i < items.size(); i++) { + int y = getItemY(i); + + if (mouseY >= y && mouseY <= y + ITEM_HEIGHT) { + if (i != active) { + onSelect.accept(i); + } + return; + } + } + } + + private int getItemY(int index) { + return HEADING_HEIGHT + index * (ITEM_HEIGHT + ITEM_GAP); + } +} diff --git a/src/main/java/org/saturnclient/ui/components/Sidebar.java b/src/main/java/org/saturnclient/ui/components/Sidebar.java index e263189..636ed9c 100644 --- a/src/main/java/org/saturnclient/ui/components/Sidebar.java +++ b/src/main/java/org/saturnclient/ui/components/Sidebar.java @@ -2,14 +2,13 @@ package org.saturnclient.ui.components; import org.saturnclient.common.provider.Providers; import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.config.Config; 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.Panel; import org.saturnclient.ui.resources.Textures; -import org.saturnclient.ui.screens.ConfigEditor; +import org.saturnclient.ui.screens.ClientSettings; import org.saturnclient.ui.screens.HudEditor; import org.saturnclient.ui.screens.ModMenu; import org.saturnclient.ui.screens.cosmetics.CloakMenu; @@ -40,8 +39,7 @@ public class Sidebar extends Element { new Item(Textures.ICON_MODS, () -> Providers.saturn.getClient().setScreen(new ModMenu())), new Item(Textures.ICON_COSMETICS, () -> Providers.saturn.getClient().setScreen(new CloakMenu())), new Item(Textures.ICON_HUD_EDITOR, () -> Providers.saturn.getClient().setScreen(new HudEditor())), - new Item(Textures.ICON_SETTINGS, - () -> Providers.saturn.getClient().setScreen(new ConfigEditor(Config.config))), + new Item(Textures.ICON_SETTINGS, () -> Providers.saturn.getClient().setScreen(new ClientSettings())), }; private final int active; diff --git a/src/main/java/org/saturnclient/ui/components/ThemePresetCard.java b/src/main/java/org/saturnclient/ui/components/ThemePresetCard.java new file mode 100644 index 0000000..108f7ec --- /dev/null +++ b/src/main/java/org/saturnclient/ui/components/ThemePresetCard.java @@ -0,0 +1,60 @@ +package org.saturnclient.ui.components; + +import org.saturnclient.config.Theme; +import org.saturnclient.ui.Element; +import org.saturnclient.ui.ElementContext; +import org.saturnclient.ui.RenderScope; +import org.saturnclient.ui.resources.Fonts; + +/** + * A theme preset: a small mock-up of a panel in its colors, and its name. + * Clicking it applies the preset. + */ +public class ThemePresetCard extends Element { + public static final int HEIGHT = 92; + + private static final int PADDING = 10; + private static final int PREVIEW_HEIGHT = 44; + private static final float NAME_SCALE = 0.68f; + + private final Theme.Preset preset; + private final Runnable onApply; + + /** + * @param onApply runs after the preset is applied, to refresh what shows the + * old colors + */ + public ThemePresetCard(Theme.Preset preset, int width, Runnable onApply) { + this.preset = preset; + this.onApply = onApply; + this.width = width; + this.height = HEIGHT; + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + boolean active = preset.isActive(); + int border = active ? Theme.ACCENT.value + : Theme.withAlpha(ctx.isHovering() ? 0.22f : 0.06f, Theme.FOREGROUND.value); + + renderScope.drawRoundedRectangle(0, 0, width, height, Theme.WIDGET_RADIUS.value, active ? 2 : 1, + Theme.withAlpha(0.72f, Theme.PRIMARY.value), border); + + // A panel in the preset's colors: a line of text over an accent and a widget + int previewWidth = width - PADDING * 2; + renderScope.drawRoundedRectangle(PADDING, PADDING, previewWidth, PREVIEW_HEIGHT, 8, preset.background()); + renderScope.drawRoundedRectangle(PADDING + 8, PADDING + 8, previewWidth * 6 / 10, 5, 3, + Theme.withAlpha(0.8f, preset.foreground())); + renderScope.drawRoundedRectangle(PADDING + 8, PADDING + PREVIEW_HEIGHT - 20, 34, 12, 4, preset.accent()); + renderScope.drawRoundedRectangle(PADDING + 47, PADDING + PREVIEW_HEIGHT - 20, 22, 12, 4, preset.primary()); + + int nameY = PADDING + PREVIEW_HEIGHT + (height - PADDING - PREVIEW_HEIGHT - (int) (Fonts.getHeight() * NAME_SCALE)) / 2; + renderScope.drawText(NAME_SCALE, preset.name(), PADDING, nameY, Theme.FONT.value, Theme.FOREGROUND.value); + } + + @Override + public void click(int mouseX, int mouseY) { + preset.apply(); + onApply.run(); + } +} diff --git a/src/main/java/org/saturnclient/ui/elements/Divider.java b/src/main/java/org/saturnclient/ui/elements/Divider.java index abb2c26..664a112 100644 --- a/src/main/java/org/saturnclient/ui/elements/Divider.java +++ b/src/main/java/org/saturnclient/ui/elements/Divider.java @@ -6,7 +6,8 @@ import org.saturnclient.ui.ElementContext; import org.saturnclient.ui.RenderScope; /** - * A faint horizontal line across the element's width. + * A faint line filling the element: horizontal by default, or vertical when + * given a width of 1 and a height. */ public class Divider extends Element { @@ -17,6 +18,6 @@ public class Divider extends Element { @Override public void render(RenderScope renderScope, ElementContext ctx) { - renderScope.drawRectangle(0, 0, width, 1, Theme.getBorder()); + renderScope.drawRectangle(0, 0, width, height, Theme.getBorder()); } } diff --git a/src/main/java/org/saturnclient/ui/resources/Textures.java b/src/main/java/org/saturnclient/ui/resources/Textures.java index f6194e7..04878c8 100644 --- a/src/main/java/org/saturnclient/ui/resources/Textures.java +++ b/src/main/java/org/saturnclient/ui/resources/Textures.java @@ -33,6 +33,9 @@ public class Textures { public static final IdentifierRef ICON_CLOSE = IdentifierRef.ofSaturn("textures/gui/components/close.svg"); public static final IdentifierRef ICON_SEARCH = IdentifierRef.ofSaturn("textures/gui/components/search.svg"); public static final IdentifierRef ICON_SLIDERS = IdentifierRef.ofSaturn("textures/gui/components/sliders.svg"); + public static final IdentifierRef ICON_PALETTE = IdentifierRef.ofSaturn("textures/gui/components/palette.svg"); + public static final IdentifierRef ICON_ANIMATIONS = IdentifierRef + .ofSaturn("textures/gui/components/animations.svg"); public static final IdentifierRef ICON_RESET = IdentifierRef.ofSaturn("textures/gui/components/reset.svg"); public static final IdentifierRef ICON_CHEVRON_LEFT = IdentifierRef .ofSaturn("textures/gui/components/chevron_left.svg"); diff --git a/src/main/java/org/saturnclient/ui/screens/ClientSettings.java b/src/main/java/org/saturnclient/ui/screens/ClientSettings.java new file mode 100644 index 0000000..d002207 --- /dev/null +++ b/src/main/java/org/saturnclient/ui/screens/ClientSettings.java @@ -0,0 +1,151 @@ +package org.saturnclient.ui.screens; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.saturnclient.common.ref.asset.IdentifierRef; +import org.saturnclient.config.AnimationConfig; +import org.saturnclient.config.Config; +import org.saturnclient.config.Theme; +import org.saturnclient.config.property.ColorProperty; +import org.saturnclient.config.property.NamespaceProperty; +import org.saturnclient.config.property.Property; +import org.saturnclient.ui.PanelScreen; +import org.saturnclient.ui.components.ColorGrid; +import org.saturnclient.ui.components.PropertyList; +import org.saturnclient.ui.components.SectionNav; +import org.saturnclient.ui.components.Sidebar; +import org.saturnclient.ui.components.ThemePresetCard; +import org.saturnclient.ui.elements.ActionButton; +import org.saturnclient.ui.elements.Divider; +import org.saturnclient.ui.elements.Label; +import org.saturnclient.ui.elements.Scroll; +import org.saturnclient.ui.resources.Textures; + +/** + * The client's own settings, split into sections picked from a list on the left. + */ +public class ClientSettings extends PanelScreen { + private enum Section { + GENERAL("General", "Title screen, emotes and cosmetics", Textures.ICON_SLIDERS), + UI_STYLE("UI Style", "Colors, corners and font for every Saturn screen", Textures.ICON_PALETTE), + ANIMATIONS("Animations", "How long menu animations take, and their easing", Textures.ICON_ANIMATIONS); + + final String title; + final String description; + final IdentifierRef icon; + + Section(String title, String description, IdentifierRef icon) { + this.title = title; + this.description = description; + this.icon = icon; + } + } + + private static final int NAV_WIDTH = 170; + private static final int NAV_GAP = 16; + private static final int LIST_Y = 58; + private static final int SECTION_GAP = 22; + private static final int PRESET_GAP = 10; + private static final int SCROLLBAR_SPACE = 14; + + private Section section = Section.GENERAL; + + public ClientSettings() { + super("Settings", Sidebar.SETTINGS); + } + + @Override + protected void panel() { + List items = Stream.of(Section.values()) + .map(s -> new SectionNav.Item(s.icon, s.title)) + .toList(); + + draw(new SectionNav("SATURN CLIENT", items, section.ordinal(), NAV_WIDTH, i -> { + section = Section.values()[i]; + init(); + }).position(contentX, contentY + 4)); + + int dividerX = contentX + NAV_WIDTH + NAV_GAP; + draw(new Divider(1).dimensions(1, panelHeight).position(dividerX, panelY)); + + int x = dividerX + 1 + NAV_GAP + 4; + int width = contentX + contentWidth - x; + + // Header + draw(new Label(() -> section.title, 1.15f, () -> Theme.FONT.value, () -> Theme.FOREGROUND.value) + .position(x, contentY + 2)); + draw(new Label(() -> section.description, 0.66f, Theme::getBodyFont, Theme::getMutedFg) + .position(x, contentY + 28)); + + ActionButton reset = new ActionButton(Textures.ICON_RESET, "Reset", true, this::reset); + draw(reset.position(x + width - reset.width, contentY + 4)); + + // The section's settings + Scroll scroll = new Scroll(0).noBackground(); + + switch (section) { + case GENERAL -> PropertyList.draw(scroll, getGeneralProperties(), Set.of(), width, 0); + case UI_STYLE -> drawUiStyle(scroll, width); + case ANIMATIONS -> PropertyList.draw(scroll, AnimationConfig.config.getProperties(), Set.of(), width, 0); + } + + draw(scroll.dimensions(width + SCROLLBAR_SPACE, contentHeight - LIST_Y).position(x, contentY + LIST_Y)); + } + + private void drawUiStyle(Scroll scroll, int width) { + Map properties = Theme.config.getProperties(); + + int y = PropertyList.drawSection(scroll, "Presets", 0) + 10; + int cardWidth = (width - PRESET_GAP * (Theme.PRESETS.size() - 1)) / Theme.PRESETS.size(); + + for (int i = 0; i < Theme.PRESETS.size(); i++) { + // Rebuild so the color inputs show the preset's colors + scroll.draw(new ThemePresetCard(Theme.PRESETS.get(i), cardWidth, this::init) + .position(i * (cardWidth + PRESET_GAP), y)); + } + + y += ThemePresetCard.HEIGHT + SECTION_GAP; + y = PropertyList.drawSection(scroll, "Colors", y) + 10; + y = ColorGrid.draw(scroll, properties, width, y) + SECTION_GAP; + + y = PropertyList.drawSection(scroll, "Shape & type", y) + 4; + PropertyList.draw(scroll, properties, getNames(properties, p -> p instanceof ColorProperty), width, y); + } + + /** + * The top-level settings. The namespaces have sections of their own. + */ + private static Map getGeneralProperties() { + return Config.config.getProperties().entrySet().stream() + .filter(e -> !(e.getValue() instanceof NamespaceProperty)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, + LinkedHashMap::new)); + } + + private static Set getNames(Map properties, Predicate filter) { + return properties.entrySet().stream() + .filter(e -> filter.test(e.getValue())) + .map(Map.Entry::getKey) + .collect(Collectors.toSet()); + } + + /** + * Puts the current section's settings back to their defaults. + */ + private void reset() { + Map properties = switch (section) { + case GENERAL -> getGeneralProperties(); + case UI_STYLE -> Theme.config.getProperties(); + case ANIMATIONS -> AnimationConfig.config.getProperties(); + }; + + properties.values().forEach(Property::reset); + init(); + } +} diff --git a/src/main/java/org/saturnclient/ui/screens/ConfigEditor.java b/src/main/java/org/saturnclient/ui/screens/ConfigEditor.java deleted file mode 100644 index 1bb38ab..0000000 --- a/src/main/java/org/saturnclient/ui/screens/ConfigEditor.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.ui.screens; - -import java.util.Set; - -import org.saturnclient.config.ConfigManager; -import org.saturnclient.config.Theme; -import org.saturnclient.ui.PanelScreen; -import org.saturnclient.ui.components.PropertyList; -import org.saturnclient.ui.components.Sidebar; -import org.saturnclient.ui.elements.Label; -import org.saturnclient.ui.elements.Scroll; - -/** - * Edits every property of a config, such as the client's own settings. - */ -public class ConfigEditor extends PanelScreen { - private static final int SCROLLBAR_SPACE = 14; - private static final int LIST_Y = 44; - - private final ConfigManager config; - - public ConfigEditor(ConfigManager config) { - super("Config Editor", Sidebar.SETTINGS); - this.config = config; - } - - @Override - protected void panel() { - draw(new Label(() -> "Settings", 1.15f, () -> Theme.FONT.value, () -> Theme.FOREGROUND.value) - .position(contentX, contentY + 2)); - - Scroll scroll = new Scroll(0).noBackground(); - PropertyList.draw(scroll, config.getProperties(), Set.of(), contentWidth, 0); - draw(scroll.dimensions(contentWidth + SCROLLBAR_SPACE, contentHeight - LIST_Y) - .position(contentX, contentY + LIST_Y)); - } -} diff --git a/src/main/resources/assets/saturnclient/textures/gui/components/animations.svg b/src/main/resources/assets/saturnclient/textures/gui/components/animations.svg new file mode 100644 index 0000000..7c5fed6 --- /dev/null +++ b/src/main/resources/assets/saturnclient/textures/gui/components/animations.svg @@ -0,0 +1 @@ + diff --git a/src/main/resources/assets/saturnclient/textures/gui/components/palette.svg b/src/main/resources/assets/saturnclient/textures/gui/components/palette.svg new file mode 100644 index 0000000..4993031 --- /dev/null +++ b/src/main/resources/assets/saturnclient/textures/gui/components/palette.svg @@ -0,0 +1 @@ +