diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/Colors.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/Colors.java index becad47b59..9ae18b1676 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/Colors.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/Colors.java @@ -8,12 +8,13 @@ public class Colors { public static final int THEME = 0xFF94E4D3; public static final int THEME_LIGHTER = 0xFFCCFDEE; - public static final int THEME_DARKER = 0xF06f9090; + // public static final int THEME_DARKER = 0xF06f9090; + public static final int THEME_DARKER = 0xFF7A9E9E; public static final int FOREGROUND = 0xFFFFFFFF; public static final int FOREGROUND_DISABLED = 0xFFAAAAAA; private static final float LIGHTEN_FACTOR = 0.3f; - private static final float DARKEN_FACTOR = -0.3f; + private static final float DARKEN_FACTOR = -0.23f; public static int darken(int color) { return adjust(color, DARKEN_FACTOR); diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/Layout.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/Layout.java new file mode 100644 index 0000000000..620411c89f --- /dev/null +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/Layout.java @@ -0,0 +1,13 @@ +package net.caffeinemc.mods.sodium.client.gui; + +public class Layout { + public static final int BUTTON_SHORT = 20; + public static final int BUTTON_LONG = 65; + public static final int OUTER_MARGIN = 10; + public static final int BUTTON_SHORT_BOTTOM_Y = BUTTON_SHORT + OUTER_MARGIN; + public static final int INNER_MARGIN = 5; + public static final int SCROLLBAR_WIDTH = 5; + public static final int TEXT_LEFT_PADDING = 8; + public static final int TEXT_PARAGRAPH_SPACING = 8; + public static final int TEXT_LINE_SPACING = 2; +} diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/VideoSettingsScreen.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/VideoSettingsScreen.java index 3e2b3dd188..3293eb5972 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/VideoSettingsScreen.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/VideoSettingsScreen.java @@ -9,7 +9,6 @@ import net.caffeinemc.mods.sodium.client.data.fingerprint.HashedFingerprint; import net.caffeinemc.mods.sodium.client.console.Console; import net.caffeinemc.mods.sodium.client.console.message.MessageLevel; -import net.caffeinemc.mods.sodium.client.gui.options.control.Control; import net.caffeinemc.mods.sodium.client.gui.options.control.ControlElement; import net.caffeinemc.mods.sodium.client.gui.prompt.ScreenPrompt; import net.caffeinemc.mods.sodium.client.gui.prompt.ScreenPromptable; @@ -41,14 +40,13 @@ import java.util.List; import java.util.stream.Stream; -// TODO: scrolling in the page list, the options themselves, and the tooltip if necessary -// TODO: make the search bar work // TODO: constrain the tooltip to its safe area if it's too big, then show a scroll bar if it's still too big +// TODO: scrolling the tooltip? +// TODO: make the search bar work // TODO: wrap options within groups in two columns -// TODO: stop the options from overlapping the bottom or top buttons // TODO: make the mod config headers interactive: only show one mod's pages at a time, click on a mod header to open that mod's first settings page and close the previous mod's page list -// TODO: the donation button is gone when the search button is clicked? -// TODO: display each mod's version somewhere (truncate if too long?) +// TODO: truncate mod names and version numbers if too long +// TODO: change the scroll bar colors to make it look better against a lighter gray background public class VideoSettingsScreen extends Screen implements ScreenPromptable { private final List> controls = new ArrayList<>(); @@ -193,14 +191,17 @@ private void rebuildGUI() { this.rebuildGUIOptions(); this.pageList = new PageListWidget(this, new Dim2i(0, 0, 125, this.height)); - this.undoButton = new FlatButtonWidget(new Dim2i(270, this.height - 30, 65, 20), Component.translatable("sodium.options.buttons.undo"), this::undoChanges, true, false); - this.applyButton = new FlatButtonWidget(new Dim2i(130, this.height - 30, 65, 20), Component.translatable("sodium.options.buttons.apply"), this::applyChanges, true, false); - this.closeButton = new FlatButtonWidget(new Dim2i(200, this.height - 30, 65, 20), Component.translatable("gui.done"), this::onClose, true, false); - this.donateButton = new FlatButtonWidget(new Dim2i(this.width - 128, 6, 100, 20), Component.translatable("sodium.options.buttons.donate"), this::openDonationPage, true, false); - this.hideDonateButton = new FlatButtonWidget(new Dim2i(this.width - 26, 6, 20, 20), Component.literal("x"), this::hideDonationButton, true, false); + + this.undoButton = new FlatButtonWidget(new Dim2i(270, Layout.INNER_MARGIN, Layout.BUTTON_LONG, Layout.BUTTON_SHORT), Component.translatable("sodium.options.buttons.undo"), this::undoChanges, true, false); + this.applyButton = new FlatButtonWidget(new Dim2i(130, Layout.INNER_MARGIN, Layout.BUTTON_LONG, Layout.BUTTON_SHORT), Component.translatable("sodium.options.buttons.apply"), this::applyChanges, true, false); + this.closeButton = new FlatButtonWidget(new Dim2i(200, Layout.INNER_MARGIN, Layout.BUTTON_LONG, Layout.BUTTON_SHORT), Component.translatable("gui.done"), this::onClose, true, false); + + this.donateButton = new FlatButtonWidget(new Dim2i(this.width - 128, Layout.INNER_MARGIN, 100, Layout.BUTTON_SHORT), Component.translatable("sodium.options.buttons.donate"), this::openDonationPage, true, false); + this.hideDonateButton = new FlatButtonWidget(new Dim2i(this.width - 26, Layout.INNER_MARGIN, Layout.BUTTON_SHORT, Layout.BUTTON_SHORT), Component.literal("x"), this::hideDonationButton, true, false); if (SodiumClientMod.options().notifications.hasClearedDonationButton) { - this.setDonationButtonVisibility(false); + // TODO: fix, this is for debugging + // this.setDonationButtonVisibility(false); } this.addRenderableWidget(this.pageList); @@ -231,7 +232,7 @@ private void hideDonationButton() { private void rebuildGUIOptions() { this.removeWidget(this.optionList); - this.optionList = this.addRenderableWidget(new OptionListWidget(new Dim2i(130, 0, 210, this.height), this.currentPage, this.currentMod.theme())); + this.optionList = this.addRenderableWidget(new OptionListWidget(new Dim2i(130, Layout.INNER_MARGIN * 2 + Layout.BUTTON_SHORT, 210, this.height - (Layout.INNER_MARGIN * 2 + Layout.OUTER_MARGIN + Layout.BUTTON_SHORT)), this.currentPage, this.currentMod.theme())); } @Override @@ -378,11 +379,6 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { return true; } - @Override - public boolean mouseScrolled(double d, double e, double f, double g) { - return super.mouseScrolled(d, e, f, g); - } - @Override public boolean shouldCloseOnEsc() { return !this.hasPendingChanges; diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/prompt/ScreenPrompt.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/prompt/ScreenPrompt.java index a02621ada3..0dc1d24102 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/prompt/ScreenPrompt.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/prompt/ScreenPrompt.java @@ -2,6 +2,7 @@ import net.caffeinemc.mods.sodium.client.gui.ButtonTheme; import net.caffeinemc.mods.sodium.client.gui.Colors; +import net.caffeinemc.mods.sodium.client.gui.Layout; import net.caffeinemc.mods.sodium.client.gui.widgets.AbstractWidget; import net.caffeinemc.mods.sodium.client.gui.widgets.FlatButtonWidget; import net.caffeinemc.mods.sodium.client.util.Dim2i; @@ -44,9 +45,9 @@ public void init() { int boxX = (parentDimensions.width() / 2) - (this.width / 2); int boxY = (parentDimensions.height() / 2) - (this.height / 2); - this.closeButton = new FlatButtonWidget(new Dim2i((boxX + this.width) - 84, (boxY + this.height) - 24, 80, 20), Component.literal("Close"), this::close, true, false, PROMPT_THEME); + this.closeButton = new FlatButtonWidget(new Dim2i((boxX + this.width) - 84, (boxY + this.height) - 24, 80, Layout.BUTTON_SHORT), Component.literal("Close"), this::close, true, false, PROMPT_THEME); - this.actionButton = new FlatButtonWidget(new Dim2i((boxX + this.width) - 198, (boxY + this.height) - 24, 110, 20), this.action.label, this::runAction, true, false, PROMPT_THEME); + this.actionButton = new FlatButtonWidget(new Dim2i((boxX + this.width) - 198, (boxY + this.height) - 24, 110, Layout.BUTTON_SHORT), this.action.label, this::runAction, true, false, PROMPT_THEME); } public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) { @@ -86,7 +87,7 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) { textY += font.lineHeight + 2; } - textY += 8; + textY += Layout.TEXT_PARAGRAPH_SPACING; } for (var button : getWidgets()) { diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/AbstractParentWidget.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/AbstractParentWidget.java index 7adfa41078..ebcaea07ff 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/AbstractParentWidget.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/AbstractParentWidget.java @@ -45,6 +45,11 @@ protected void clearChildren() { this.renderableChildren.clear(); } + protected void verticalScrollScissorGradient(GuiGraphics graphics, int y) { + var gradientHeight = 10; + graphics.fillGradient(this.getX(), y - gradientHeight, this.getLimitX(), y, 0xFFFF0000, 0xFF00FF00); + } + @Override public void render(@NotNull GuiGraphics graphics, int mouseX, int mouseY, float delta) { for (Renderable element : this.renderableChildren) { diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/CenteredFlatWidget.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/CenteredFlatWidget.java index 95924f290b..1e32ef6672 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/CenteredFlatWidget.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/CenteredFlatWidget.java @@ -3,6 +3,7 @@ import net.caffeinemc.mods.sodium.client.gui.ButtonTheme; import net.caffeinemc.mods.sodium.client.gui.ColorTheme; import net.caffeinemc.mods.sodium.client.gui.Colors; +import net.caffeinemc.mods.sodium.client.gui.Layout; import net.caffeinemc.mods.sodium.client.util.Dim2i; import net.minecraft.client.gui.ComponentPath; import net.minecraft.client.gui.GuiGraphics; @@ -12,8 +13,7 @@ import net.minecraft.network.chat.Component; import org.jetbrains.annotations.Nullable; -public class CenteredFlatWidget extends AbstractWidget implements Renderable { - private final Runnable action; +public abstract class CenteredFlatWidget extends AbstractWidget implements Renderable { private final boolean isSelectable; private final ButtonTheme theme; @@ -22,15 +22,20 @@ public class CenteredFlatWidget extends AbstractWidget implements Renderable { private boolean visible = true; private final Component label; + private final Component subtitle; - public CenteredFlatWidget(Dim2i dim, Component label, Runnable action, boolean isSelectable, ColorTheme theme) { + public CenteredFlatWidget(Dim2i dim, Component label, Component subtitle, boolean isSelectable, ColorTheme theme) { super(dim); this.label = label; - this.action = action; + this.subtitle = subtitle; this.isSelectable = isSelectable; this.theme = new ButtonTheme(theme, 0x05FFFFFF, 0x90000000, 0x40000000); } + public CenteredFlatWidget(Dim2i dim, Component label, boolean isSelectable, ColorTheme theme) { + this(dim, label, null, isSelectable, theme); + } + @Override public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) { if (!this.visible) { @@ -58,7 +63,13 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) { this.drawRect(graphics, x2 - 3, y1, x2, y2, this.theme.themeLighter); } - this.drawString(graphics, text, x1 + 8, (int) Math.ceil(((y1 + (this.getHeight() - this.font.lineHeight) * 0.5f))), textColor); + if (this.subtitle == null) { + this.drawString(graphics, text, x1 + Layout.TEXT_LEFT_PADDING, (int) Math.ceil(((y1 + (this.getHeight() - this.font.lineHeight) * 0.5f))), textColor); + } else { + var center = y1 + this.getHeight() * 0.5f; + this.drawString(graphics, text, x1 + Layout.TEXT_LEFT_PADDING, (int) Math.ceil(center - (this.font.lineHeight + Layout.TEXT_LINE_SPACING * 0.5f)), textColor); + this.drawString(graphics, this.subtitle, x1 + Layout.TEXT_LEFT_PADDING, (int) Math.ceil(center + Layout.TEXT_LINE_SPACING * 0.5f), textColor); + } if (this.enabled && this.isFocused()) { this.drawBorder(graphics, x1, y1, x2, y2, Colors.FOREGROUND); @@ -97,8 +108,10 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { return false; } + abstract void onAction(); + private void doAction() { - this.action.run(); + this.onAction(); this.playClickSound(); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/FlatButtonWidget.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/FlatButtonWidget.java index 0069cf085e..57ba603eb0 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/FlatButtonWidget.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/FlatButtonWidget.java @@ -2,6 +2,7 @@ import net.caffeinemc.mods.sodium.client.gui.ButtonTheme; import net.caffeinemc.mods.sodium.client.gui.Colors; +import net.caffeinemc.mods.sodium.client.gui.Layout; import net.caffeinemc.mods.sodium.client.util.Dim2i; import net.minecraft.client.gui.ComponentPath; import net.minecraft.client.gui.GuiGraphics; @@ -57,7 +58,7 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) { this.drawRect(graphics, this.getX(), this.getY(), this.getLimitX(), this.getLimitY(), backgroundColor); } - this.drawString(graphics, this.label, this.leftAlign ? this.getX() + 5 : (this.getCenterX() - (strWidth / 2)), this.getCenterY() - 4, textColor); + this.drawString(graphics, this.label, this.leftAlign ? this.getX() + Layout.TEXT_LEFT_PADDING : (this.getCenterX() - (strWidth / 2)), this.getCenterY() - 4, textColor); if (this.enabled && this.selected) { this.drawRect(graphics, this.getX(), this.getLimitY() - 1, this.getLimitX(), this.getLimitY(), Colors.THEME); diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/OptionListWidget.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/OptionListWidget.java index fc7556e40e..73f4b6441f 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/OptionListWidget.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/OptionListWidget.java @@ -4,6 +4,7 @@ import net.caffeinemc.mods.sodium.client.config.structure.OptionGroup; import net.caffeinemc.mods.sodium.client.config.structure.OptionPage; import net.caffeinemc.mods.sodium.client.gui.ColorTheme; +import net.caffeinemc.mods.sodium.client.gui.Layout; import net.caffeinemc.mods.sodium.client.gui.options.control.Control; import net.caffeinemc.mods.sodium.client.gui.options.control.ControlElement; import net.caffeinemc.mods.sodium.client.util.Dim2i; @@ -24,10 +25,10 @@ public OptionListWidget(Dim2i dim, OptionPage page, ColorTheme theme) { this.page = page; this.theme = theme; this.controls = new ArrayList<>(); - this.init(); + this.rebuild(); } - private void init() { + private void rebuild() { int x = this.getX(); int y = this.getY(); int width = this.getWidth(); @@ -36,10 +37,10 @@ private void init() { int maxWidth = 0; this.clearChildren(); - this.scrollbar = this.addRenderableChild(new ScrollbarWidget(new Dim2i(x + width - 5, y, 5, height))); + this.scrollbar = this.addRenderableChild(new ScrollbarWidget(new Dim2i(x + width - Layout.SCROLLBAR_WIDTH, y, Layout.SCROLLBAR_WIDTH, height))); int entryHeight = 18; - int listHeight = 23; + int listHeight = 0; for (OptionGroup group : this.page.groups()) { // Add each option's control element for (Option option : group.options()) { @@ -56,16 +57,19 @@ private void init() { } // Add padding beneath each option group - listHeight += 4; + listHeight += Layout.INNER_MARGIN; } - this.scrollbar.setScrollbarContext(height, listHeight + 5); + this.scrollbar.setScrollbarContext(listHeight - Layout.INNER_MARGIN); } @Override public void render(@NotNull GuiGraphics graphics, int mouseX, int mouseY, float delta) { graphics.enableScissor(this.getX(), this.getY(), this.getLimitX(), this.getLimitY()); super.render(graphics, mouseX, mouseY, delta); + +// this.verticalScrollScissorGradient(graphics, this.getLimitY()); + graphics.disableScissor(); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/PageListWidget.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/PageListWidget.java index c88c43d789..bea12ee421 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/PageListWidget.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/PageListWidget.java @@ -2,9 +2,11 @@ import net.caffeinemc.mods.sodium.client.config.ConfigManager; import net.caffeinemc.mods.sodium.client.config.structure.ExternalPage; +import net.caffeinemc.mods.sodium.client.config.structure.ModOptions; import net.caffeinemc.mods.sodium.client.config.structure.OptionPage; import net.caffeinemc.mods.sodium.client.config.structure.Page; import net.caffeinemc.mods.sodium.client.gui.ColorTheme; +import net.caffeinemc.mods.sodium.client.gui.Layout; import net.caffeinemc.mods.sodium.client.gui.VideoSettingsScreen; import net.caffeinemc.mods.sodium.client.util.Dim2i; import net.minecraft.ChatFormatting; @@ -14,6 +16,7 @@ public class PageListWidget extends AbstractParentWidget { private final VideoSettingsScreen parent; + private CenteredFlatWidget selected; private ScrollbarWidget scrollbar; private FlatButtonWidget search; @@ -23,15 +26,6 @@ public PageListWidget(VideoSettingsScreen parent, Dim2i dim) { this.rebuild(); } - @Override - public void render(@NotNull GuiGraphics graphics, int mouseX, int mouseY, float delta) { - graphics.fillGradient(this.getX(), this.getY(), this.getWidth(), this.getHeight(), 0x40000000, 0x90000000); - graphics.enableScissor(this.getX(), this.getY(), this.getLimitX(), this.getLimitY() - 30); - super.render(graphics, mouseX, mouseY, delta); - graphics.disableScissor(); - this.search.render(graphics, mouseX, mouseY, delta); - } - public void rebuild() { int x = this.getX(); int y = this.getY(); @@ -39,32 +33,32 @@ public void rebuild() { int height = this.getHeight(); this.clearChildren(); - this.scrollbar = this.addRenderableChild(new ScrollbarWidget(new Dim2i(x + width - 5, y, 5, height - 30))); - this.search = this.addChild(new FlatButtonWidget(new Dim2i(x, y + height - 30, width, 20), Component.literal("Search...").withStyle(ChatFormatting.ITALIC, ChatFormatting.GRAY), () -> { + this.scrollbar = this.addRenderableChild(new ScrollbarWidget(new Dim2i(x + width - Layout.SCROLLBAR_WIDTH, y, Layout.SCROLLBAR_WIDTH, height - Layout.BUTTON_SHORT_BOTTOM_Y))); + this.search = this.addChild(new FlatButtonWidget(new Dim2i(x, y + height - Layout.BUTTON_SHORT_BOTTOM_Y, width, Layout.BUTTON_SHORT), Component.literal("Search...").withStyle(ChatFormatting.ITALIC, ChatFormatting.GRAY), () -> { // TODO: implement search }, true, true)); - int listHeight = 5; int entryHeight = this.font.lineHeight * 2; + var headerHeight = this.font.lineHeight * 3; + int listHeight = Layout.BUTTON_SHORT + Layout.INNER_MARGIN * 2 - headerHeight; for (var modOptions : ConfigManager.CONFIG.getModOptions()) { var theme = modOptions.theme(); - CenteredFlatWidget header = new EntryWidget(new Dim2i(x, y + listHeight, width, entryHeight), Component.literal(modOptions.name()), () -> { - }, false, theme); + CenteredFlatWidget header = new HeaderEntryWidget(new Dim2i(x, y + listHeight, width, headerHeight), modOptions, theme); - listHeight += entryHeight; + listHeight += headerHeight; this.addRenderableChild(header); for (Page page : modOptions.pages()) { CenteredFlatWidget button; if (page instanceof OptionPage optionPage) { - button = createEntryWidget(() -> this.parent.setPage(modOptions, optionPage), - page, x, y, listHeight, width, entryHeight, theme); - button.setSelected(this.parent.getPage() == page); + button = new PageEntryWidget(new Dim2i(x, y + listHeight, width, entryHeight), optionPage, modOptions, theme); + if (this.parent.getPage() == page) { + this.switchSelected(button); + } } else if (page instanceof ExternalPage externalPage) { - button = createEntryWidget(() -> externalPage.currentScreenConsumer().accept(this.parent), - page, x, y, listHeight, width, entryHeight, theme); + button = new ExternalPageEntryWidget(new Dim2i(x, y + listHeight, width, entryHeight), externalPage, theme); } else { throw new IllegalStateException("Unknown page type: " + page.getClass()); } @@ -75,11 +69,20 @@ public void rebuild() { } } - this.scrollbar.setScrollbarContext(height - 30, listHeight + 5); + this.scrollbar.setScrollbarContext(listHeight + Layout.INNER_MARGIN); } - private @NotNull EntryWidget createEntryWidget(Runnable clickHandler, Page page, int x, int y, int listHeight, int width, int entryHeight, ColorTheme theme) { - return new EntryWidget(new Dim2i(x, y + listHeight, width, entryHeight), page.name(), clickHandler, true, theme); + @Override + public void render(@NotNull GuiGraphics graphics, int mouseX, int mouseY, float delta) { + graphics.fillGradient(this.getX(), this.getY(), this.getLimitX(), this.getLimitY(), 0x40000000, 0x90000000); + var scissorEnd = this.getLimitY() - Layout.BUTTON_SHORT_BOTTOM_Y; + graphics.enableScissor(this.getX(), this.getY(), this.getLimitX(), scissorEnd); + super.render(graphics, mouseX, mouseY, delta); + graphics.disableScissor(); + +// this.verticalScrollScissorGradient(graphics, scissorEnd); + + this.search.render(graphics, mouseX, mouseY, delta); } @Override @@ -88,9 +91,25 @@ public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmou return true; } - public class EntryWidget extends CenteredFlatWidget { - public EntryWidget(Dim2i dim, Component label, Runnable action, boolean isSelectable, ColorTheme theme) { - super(dim, label, action, isSelectable, theme); + private void switchSelected(CenteredFlatWidget widget) { + if (this.selected != null) { + this.selected.setSelected(false); + } + this.selected = widget; + this.selected.setSelected(true); + } + + private class EntryWidget extends CenteredFlatWidget { + EntryWidget(Dim2i dim, Component label, boolean isSelectable, ColorTheme theme) { + super(dim, label, isSelectable, theme); + } + + EntryWidget(Dim2i dim, Component label, Component subtitle, boolean isSelectable, ColorTheme theme) { + super(dim, label, subtitle, isSelectable, theme); + } + + @Override + void onAction() { } @Override @@ -98,4 +117,41 @@ public int getY() { return super.getY() - PageListWidget.this.scrollbar.getScrollAmount(); } } + + private class HeaderEntryWidget extends EntryWidget { + HeaderEntryWidget(Dim2i dim, ModOptions modOptions, ColorTheme theme) { + super(dim, Component.literal(modOptions.name()), Component.literal(modOptions.version()), false, theme); + } + } + + private class PageEntryWidget extends EntryWidget { + private final OptionPage page; + private final ModOptions modOptions; + + PageEntryWidget(Dim2i dim, OptionPage page, ModOptions modOptions, ColorTheme theme) { + super(dim, page.name(), true, theme); + this.page = page; + this.modOptions = modOptions; + } + + @Override + void onAction() { + PageListWidget.this.switchSelected(this); + PageListWidget.this.parent.setPage(this.modOptions, this.page); + } + } + + private class ExternalPageEntryWidget extends EntryWidget { + private final ExternalPage page; + + ExternalPageEntryWidget(Dim2i dim, ExternalPage page, ColorTheme theme) { + super(dim, page.name(), true, theme); + this.page = page; + } + + @Override + void onAction() { + this.page.currentScreenConsumer().accept(PageListWidget.this.parent); + } + } } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/ScrollbarWidget.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/ScrollbarWidget.java index a7b4286acd..84f53d8d3c 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/ScrollbarWidget.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/widgets/ScrollbarWidget.java @@ -37,6 +37,10 @@ public void setScrollbarContext(int visible, int total) { this.scrollAmount = Math.max(0, Math.min(total - visible, this.scrollAmount)); } + public void setScrollbarContext(int total) { + this.setScrollbarContext(this.horizontal ? this.width : this.height, total); + } + public boolean canScroll() { return this.total > this.visible; }