diff --git a/src/main/java/de/hysky/skyblocker/config/HudConfigScreen.java b/src/main/java/de/hysky/skyblocker/config/HudConfigScreen.java
index ac1d89666b..06bec73751 100644
--- a/src/main/java/de/hysky/skyblocker/config/HudConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/config/HudConfigScreen.java
@@ -1,7 +1,7 @@
package de.hysky.skyblocker.config;
-import de.hysky.skyblocker.skyblock.tabhud.widget.HudWidget;
import de.hysky.skyblocker.utils.render.RenderHelper;
+import de.hysky.skyblocker.utils.render.gui.AbstractWidget;
import it.unimi.dsi.fastutil.ints.IntIntMutablePair;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
@@ -13,129 +13,140 @@
/**
* A screen for configuring the positions of HUD widgets.
*
+ * Note: This is currently only used for title container. There is a new system for other HUD widgets, see {@link de.hysky.skyblocker.skyblock.tabhud.config.WidgetsConfigurationScreen}
+ *
* This class takes care of rendering the widgets, dragging them, and resetting their positions.
* Create one subclass for each collection of HUD widgets that are displayed at the same time.
* (i.e. one for dwarven mines, one for the end, etc.) See an implementation for an example.
*/
public abstract class HudConfigScreen extends Screen {
- private final Screen parent;
- private final List widgets;
-
- private HudWidget draggingWidget;
- private double mouseClickRelativeX;
- private double mouseClickRelativeY;
-
- /**
- * Creates a new HudConfigScreen with the passed title, parent, and widget
- * @param title the title of the screen
- * @param parent the parent screen
- * @param widget the widget to configure
- */
- public HudConfigScreen(Text title, Screen parent, HudWidget widget) {
- this(title, parent, List.of(widget));
- }
-
- /**
- * Creates a new HudConfigScreen with the passed title, parent, and widgets
- * @param title the title of the screen
- * @param parent the parent screen
- * @param widgets the widgets to configure
- */
- public HudConfigScreen(Text title, Screen parent, List widgets) {
- super(title);
- this.parent = parent;
- this.widgets = widgets;
- resetPos();
- }
-
- @Override
- public final void render(DrawContext context, int mouseX, int mouseY, float delta) {
- super.render(context, mouseX, mouseY, delta);
- renderWidget(context, widgets);
- context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width / 2, height / 2, Color.GRAY.getRGB());
- }
-
- /**
- * Renders the widgets using the default {@link HudWidget#render(DrawContext)} method. Override to change the behavior.
- * @param context the context to render in
- * @param widgets the widgets to render
- */
- protected void renderWidget(DrawContext context, List widgets) {
- for (HudWidget widget : widgets) {
- widget.render(context);
- }
- }
-
- @Override
- public final boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
- if (button == 0 && draggingWidget != null) {
- draggingWidget.setX((int) Math.clamp(mouseX - mouseClickRelativeX, 0, this.width - draggingWidget.getWidth()));
- draggingWidget.setY((int) Math.clamp(mouseY - mouseClickRelativeY, 0, this.height - draggingWidget.getHeight()));
- }
- return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
- }
-
- @Override
- public final boolean mouseClicked(double mouseX, double mouseY, int button) {
- if (button == 0) {
- for (HudWidget widget : widgets) {
- if (RenderHelper.pointIsInArea(mouseX, mouseY, widget.getX(), widget.getY(), widget.getX() + widget.getWidth(), widget.getY() + widget.getHeight())) {
- draggingWidget = widget;
- mouseClickRelativeX = mouseX - widget.getX();
- mouseClickRelativeY = mouseY - widget.getY();
- break;
- }
- }
- } else if (button == 1) {
- resetPos();
- }
- return super.mouseClicked(mouseX, mouseY, button);
- }
-
- @Override
- public final boolean mouseReleased(double mouseX, double mouseY, int button) {
- draggingWidget = null;
- return super.mouseReleased(mouseX, mouseY, button);
- }
-
- /**
- * Resets the positions of the widgets to the positions in the config. Override to change the behavior.
- */
- protected void resetPos() {
- List configPositions = getConfigPos(SkyblockerConfigManager.get());
- if (configPositions.size() != widgets.size()) {
- throw new IllegalStateException("The number of positions (" + configPositions.size() + ") does not match the number of widgets (" + widgets.size() + ")");
- }
- for (int i = 0; i < widgets.size(); i++) {
- HudWidget widget = widgets.get(i);
- IntIntMutablePair configPos = configPositions.get(i);
- widget.setX(configPos.leftInt());
- widget.setY(configPos.rightInt());
- }
- }
-
- /**
- * Returns the positions of the widgets in the config
- * @param config the config to get the positions from
- * @return the positions of the widgets
- */
- protected abstract List getConfigPos(SkyblockerConfig config);
-
- @Override
- public final void close() {
- SkyblockerConfig skyblockerConfig = SkyblockerConfigManager.get();
- savePos(skyblockerConfig, widgets);
- SkyblockerConfigManager.save();
-
- client.setScreen(parent);
- }
-
- /**
- * Saves the passed positions to the config.
- *
- * NOTE: The parent class will call {@link SkyblockerConfigManager#save()} right after this method
- * @param configManager the config so you don't have to get it
- * @param widgets the widgets to save
- */
- protected abstract void savePos(SkyblockerConfig configManager, List widgets);
+ protected final Screen parent;
+ protected final List widgets;
+
+ private AbstractWidget draggingWidget;
+ private double mouseClickRelativeX;
+ private double mouseClickRelativeY;
+
+ /**
+ * Creates a new HudConfigScreen with the passed title, parent, and widget
+ *
+ * @param title the title of the screen
+ * @param parent the parent screen
+ * @param widget the widget to configure
+ */
+ public HudConfigScreen(Text title, Screen parent, AbstractWidget widget) {
+ this(title, parent, List.of(widget));
+ }
+
+ /**
+ * Creates a new HudConfigScreen with the passed title, parent, and widgets
+ *
+ * @param title the title of the screen
+ * @param parent the parent screen
+ * @param widgets the widgets to configure
+ */
+ public HudConfigScreen(Text title, Screen parent, List widgets) {
+ super(title);
+ this.parent = parent;
+ this.widgets = widgets;
+ resetPos();
+ }
+
+ @Override
+ public final void render(DrawContext context, int mouseX, int mouseY, float delta) {
+ super.render(context, mouseX, mouseY, delta);
+ renderWidget(context, widgets, delta);
+ context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width / 2, height / 2, Color.GRAY.getRGB());
+ }
+
+ /**
+ * Renders the widgets using the default {@link AbstractWidget#render(DrawContext, int, int, float)} method. Override to change the behavior.
+ *
+ * @param context the context to render in
+ * @param widgets the widgets to render
+ */
+ protected void renderWidget(DrawContext context, List widgets, float delta) {
+ for (AbstractWidget widget : widgets) {
+ widget.render(context, -1, -1, delta);
+ }
+ }
+
+ @Override
+ public final boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
+ if (button == 0 && draggingWidget != null) {
+ draggingWidget.setX((int) Math.clamp(mouseX - mouseClickRelativeX, 0, this.width - draggingWidget.getWidth()) - getWidgetXOffset(draggingWidget));
+ draggingWidget.setY((int) Math.clamp(mouseY - mouseClickRelativeY, 0, this.height - draggingWidget.getHeight()));
+ }
+ return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
+ }
+
+ @Override
+ public final boolean mouseClicked(double mouseX, double mouseY, int button) {
+ if (button == 0) {
+ for (AbstractWidget widget : widgets) {
+ if (RenderHelper.pointIsInArea(mouseX, mouseY, widget.getX() + getWidgetXOffset(widget), widget.getY(), widget.getX() + getWidgetXOffset(widget) + widget.getWidth(), widget.getY() + widget.getHeight())) {
+ draggingWidget = widget;
+ mouseClickRelativeX = mouseX - widget.getX() - getWidgetXOffset(widget);
+ mouseClickRelativeY = mouseY - widget.getY();
+ break;
+ }
+ }
+ } else if (button == 1) {
+ resetPos();
+ }
+ return super.mouseClicked(mouseX, mouseY, button);
+ }
+
+ @Override
+ public final boolean mouseReleased(double mouseX, double mouseY, int button) {
+ draggingWidget = null;
+ return super.mouseReleased(mouseX, mouseY, button);
+ }
+
+ protected int getWidgetXOffset(AbstractWidget widget) {
+ return 0;
+ }
+
+ /**
+ * Resets the positions of the widgets to the positions in the config. Override to change the behavior.
+ */
+ protected void resetPos() {
+ List configPositions = getConfigPos(SkyblockerConfigManager.get());
+ if (configPositions.size() != widgets.size()) {
+ throw new IllegalStateException("The number of positions (" + configPositions.size() + ") does not match the number of widgets (" + widgets.size() + ")");
+ }
+ for (int i = 0; i < widgets.size(); i++) {
+ AbstractWidget widget = widgets.get(i);
+ IntIntMutablePair configPos = configPositions.get(i);
+ widget.setX(configPos.leftInt());
+ widget.setY(configPos.rightInt());
+ }
+ }
+
+ /**
+ * Returns the positions of the widgets in the config
+ *
+ * @param config the config to get the positions from
+ * @return the positions of the widgets
+ */
+ protected abstract List getConfigPos(SkyblockerConfig config);
+
+ @Override
+ public final void close() {
+ SkyblockerConfig skyblockerConfig = SkyblockerConfigManager.get();
+ savePos(skyblockerConfig, widgets);
+ SkyblockerConfigManager.save();
+
+ client.setScreen(parent);
+ }
+
+ /**
+ * Saves the passed positions to the config.
+ *
+ * NOTE: The parent class will call {@link SkyblockerConfigManager#save()} right after this method
+ *
+ * @param configManager the config so you don't have to get it
+ * @param widgets the widgets to save
+ */
+ protected abstract void savePos(SkyblockerConfig configManager, List widgets);
}
diff --git a/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java
index 55ec50941e..deb981a180 100644
--- a/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java
+++ b/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java
@@ -131,10 +131,14 @@ public static class TitleContainer {
public int y = 10;
@SerialEntry
- public Direction direction = Direction.HORIZONTAL;
+ public Direction direction = Direction.VERTICAL;
@SerialEntry
public Alignment alignment = Alignment.MIDDLE;
+
+ public float getRenderScale() {
+ return titleContainerScale * 0.03f;
+ }
}
public enum Direction {
@@ -147,7 +151,7 @@ public String toString() {
}
public enum Alignment {
- LEFT, RIGHT, MIDDLE;
+ LEFT, MIDDLE, RIGHT;
@Override
public String toString() {
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java
index 90f7ddc19b..ee3f747a14 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java
@@ -31,7 +31,6 @@ public DungeonMapConfigScreen(Screen parent) {
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
- renderBackground(context, mouseX, mouseY, delta);
renderHUDMap(context, mapX, mapY);
renderHUDScore(context, scoreX, scoreY);
context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width >> 1, height >> 1, Color.GRAY.getRGB());
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java
index e3a94bcded..18c8905a06 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/EditBarWidget.java
@@ -1,5 +1,6 @@
package de.hysky.skyblocker.skyblock.fancybars;
+import de.hysky.skyblocker.utils.EnumUtils;
import it.unimi.dsi.fastutil.booleans.BooleanConsumer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
@@ -211,7 +212,7 @@ public void setCurrent(T current) {
@Override
public void onClick(double mouseX, double mouseY) {
- current = values[(current.ordinal() + 1) % values.length];
+ current = EnumUtils.cycle(current);
if (onChange != null) onChange.accept(current);
super.onClick(mouseX, mouseY);
}
@@ -334,4 +335,4 @@ protected int getContentsHeightWithPadding() {
protected double getDeltaYPerScroll() {
return 0;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java b/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java
index a5043e0650..9008fb4e9b 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java
@@ -1,6 +1,7 @@
package de.hysky.skyblocker.skyblock.item;
import com.mojang.serialization.Codec;
+import de.hysky.skyblocker.utils.EnumUtils;
import net.minecraft.util.Formatting;
import net.minecraft.util.StringIdentifiable;
@@ -41,6 +42,6 @@ public String asString() {
}
public SkyblockItemRarity next() {
- return values()[(ordinal() + 1) % values().length];
+ return EnumUtils.cycle(this);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/config/preview/PreviewTab.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/config/preview/PreviewTab.java
index f72bc2938a..2cd743ac74 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/config/preview/PreviewTab.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/config/preview/PreviewTab.java
@@ -11,6 +11,7 @@
import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr;
import de.hysky.skyblocker.skyblock.tabhud.widget.HudWidget;
import de.hysky.skyblocker.skyblock.tabhud.widget.TabHudWidget;
+import de.hysky.skyblocker.utils.EnumUtils;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.Location;
import de.hysky.skyblocker.utils.render.gui.DropdownWidget;
@@ -307,8 +308,7 @@ void onHudWidgetSelected(@Nullable HudWidget hudWidget) {
widgetOptions.addWidget(ButtonWidget.builder(Text.literal(ye), button -> {
ScreenBuilder builder = ScreenMaster.getScreenBuilder(getCurrentLocation());
PositionRule rule = builder.getPositionRuleOrDefault(hudWidget.getInternalID());
- ScreenMaster.ScreenLayer[] values = ScreenMaster.ScreenLayer.values();
- ScreenMaster.ScreenLayer newLayer = values[(rule.screenLayer().ordinal() + 1) % values.length];
+ ScreenMaster.ScreenLayer newLayer = EnumUtils.cycle(rule.screenLayer());
PositionRule newRule = new PositionRule(
rule.parent(),
diff --git a/src/main/java/de/hysky/skyblocker/utils/EnumUtils.java b/src/main/java/de/hysky/skyblocker/utils/EnumUtils.java
new file mode 100644
index 0000000000..ba1ad1d2dc
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/EnumUtils.java
@@ -0,0 +1,13 @@
+package de.hysky.skyblocker.utils;
+
+public class EnumUtils {
+ public static > T cycle(T current) {
+ T[] values = current.getDeclaringClass().getEnumConstants();
+ return values[(current.ordinal() + 1) % values.length];
+ }
+
+ public static > T cycleBackwards(T current) {
+ T[] values = current.getDeclaringClass().getEnumConstants();
+ return values[(current.ordinal() - 1 + values.length) % values.length];
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/EmptyWidget.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/EmptyWidget.java
new file mode 100644
index 0000000000..6d1324ec08
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/EmptyWidget.java
@@ -0,0 +1,8 @@
+package de.hysky.skyblocker.utils.render.gui;
+
+import net.minecraft.client.gui.DrawContext;
+
+public class EmptyWidget extends AbstractWidget {
+ @Override
+ public void render(DrawContext context, int mouseX, int mouseY, float delta) {}
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/title/Title.java b/src/main/java/de/hysky/skyblocker/utils/render/title/Title.java
index 890976aea4..6b32da7d9e 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/title/Title.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/title/Title.java
@@ -1,5 +1,6 @@
package de.hysky.skyblocker.utils.render.title;
+import com.demonwav.mcdev.annotations.Translatable;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
@@ -10,46 +11,46 @@
* @see TitleContainer
*/
public class Title {
- private MutableText text;
- protected float x = -1;
- protected float y = -1;
-
- /**
- * Constructs a new title with the given translation key and formatting to be applied.
- *
- * @param textKey the translation key
- * @param formatting the formatting to be applied to the text
- */
- public Title(String textKey, Formatting formatting) {
- this(Text.translatable(textKey).formatted(formatting));
- }
-
- /**
- * Constructs a new title with the given {@link MutableText}.
- * Use {@link Text#literal(String)} or {@link Text#translatable(String)} to create a {@link MutableText}
- *
- * @param text the mutable text
- */
- public Title(MutableText text) {
- this.text = text;
- }
-
- public MutableText getText() {
- return text;
- }
-
- public Title setText(MutableText text) {
- this.text = text;
-
- return this;
- }
-
- protected boolean isDefaultPos() {
- return x == -1 && y == -1;
- }
-
- protected void resetPos() {
- this.x = -1;
- this.y = -1;
- }
+ private MutableText text;
+ protected float x = -1;
+ protected float y = -1;
+
+ /**
+ * Constructs a new title with the given translation key and formatting to be applied.
+ *
+ * @param textKey the translation key
+ * @param formatting the formatting to be applied to the text
+ */
+ public Title(@Translatable String textKey, Formatting formatting) {
+ this(Text.translatable(textKey).formatted(formatting));
+ }
+
+ /**
+ * Constructs a new title with the given {@link MutableText}.
+ * Use {@link Text#literal(String)} or {@link Text#translatable(String)} to create a {@link MutableText}
+ *
+ * @param text the mutable text
+ */
+ public Title(MutableText text) {
+ this.text = text;
+ }
+
+ public MutableText getText() {
+ return text;
+ }
+
+ public Title setText(MutableText text) {
+ this.text = text;
+
+ return this;
+ }
+
+ protected boolean isDefaultPos() {
+ return x == -1 && y == -1;
+ }
+
+ protected void resetPos() {
+ this.x = -1;
+ this.y = -1;
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainer.java b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainer.java
index c3d7faa463..8354497691 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainer.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainer.java
@@ -17,162 +17,156 @@
import java.util.Set;
public class TitleContainer {
- /**
- * The set of titles which will be rendered.
- *
- * @see #containsTitle(Title)
- * @see #addTitle(Title)
- * @see #addTitle(Title, int)
- * @see #removeTitle(Title)
- */
- private static final Set titles = new LinkedHashSet<>();
-
- @Init
- public static void init() {
- HudRenderEvents.BEFORE_CHAT.register(TitleContainer::render);
- ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker")
- .then(ClientCommandManager.literal("hud")
- .then(ClientCommandManager.literal("titleContainer")
- .executes(Scheduler.queueOpenScreenCommand(TitleContainerConfigScreen::new))))));
- }
-
- /**
- * Returns {@code true} if the title is currently shown.
- *
- * @param title the title to check
- * @return whether the title in currently shown
- */
- public static boolean containsTitle(Title title) {
- return titles.contains(title);
- }
-
- /**
- * Adds a title to be shown
- *
- * @param title the title to be shown
- * @return whether the title is already currently being shown
- */
- public static boolean addTitle(Title title) {
- if (titles.add(title)) {
- title.resetPos();
- return true;
- }
- return false;
- }
-
- /**
- * Adds a title to be shown for a set number of ticks
- *
- * @param title the title to be shown
- * @param ticks the number of ticks to show the title
- * @return whether the title is already currently being shown
- */
- public static boolean addTitle(Title title, int ticks) {
- if (addTitle(title)) {
- Scheduler.INSTANCE.schedule(() -> TitleContainer.removeTitle(title), ticks);
- return true;
- }
- return false;
- }
-
- /**
- * Stops showing a title
- *
- * @param title the title to stop showing
- */
- public static void removeTitle(Title title) {
- titles.remove(title);
- }
-
- private static void render(DrawContext context, RenderTickCounter tickCounter) {
- render(context, titles, SkyblockerConfigManager.get().uiAndVisuals.titleContainer.x, SkyblockerConfigManager.get().uiAndVisuals.titleContainer.y, tickCounter.getTickDelta(true));
- }
-
- protected static void render(DrawContext context, Set titles, int xPos, int yPos, float tickDelta) {
- var client = MinecraftClient.getInstance();
- TextRenderer textRenderer = client.textRenderer;
-
- // Calculate Scale to use
- float scale = 3F * (SkyblockerConfigManager.get().uiAndVisuals.titleContainer.titleContainerScale / 100F);
-
- // Grab direction and alignment values
- UIAndVisualsConfig.Direction direction = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.direction;
- UIAndVisualsConfig.Alignment alignment = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment;
- // x/y refer to the starting position for the text
- // y always starts at yPos
- float x = 0;
- float y = yPos;
-
- //Calculate the width of combined text
- float width = 0;
- for (Title title : titles) {
- width += textRenderer.getWidth(title.getText()) * scale + 10;
- }
-
- if (alignment == UIAndVisualsConfig.Alignment.MIDDLE) {
- if (direction == UIAndVisualsConfig.Direction.HORIZONTAL) {
- //If middle aligned horizontally, start the xPosition at half of the width to the left.
- x = xPos - (width / 2);
- } else {
- //If middle aligned vertically, start at xPos, we will shift each text to the left later
- x = xPos;
- }
- }
- if (alignment == UIAndVisualsConfig.Alignment.LEFT || alignment == UIAndVisualsConfig.Alignment.RIGHT) {
- //If left or right aligned, start at xPos, we will shift each text later
- x = xPos;
- }
-
- for (Title title : titles) {
-
- //Calculate which x the text should use
- float xToUse;
- if (direction == UIAndVisualsConfig.Direction.HORIZONTAL) {
- xToUse = alignment == UIAndVisualsConfig.Alignment.RIGHT ?
- x - (textRenderer.getWidth(title.getText()) * scale) : //if right aligned we need the text position to be aligned on the right side.
- x;
- } else {
- xToUse = alignment == UIAndVisualsConfig.Alignment.MIDDLE ?
- x - (textRenderer.getWidth(title.getText()) * scale) / 2 : //if middle aligned we need the text position to be aligned in the middle.
- alignment == UIAndVisualsConfig.Alignment.RIGHT ?
- x - (textRenderer.getWidth(title.getText()) * scale) : //if right aligned we need the text position to be aligned on the right side.
- x;
- }
-
- //Start displaying the title at the correct position, not at the default position
- if (title.isDefaultPos()) {
- title.x = xToUse;
- title.y = y;
- }
-
- //Lerp the texts x and y variables
- title.x = MathHelper.lerp(tickDelta * 0.5F, title.x, xToUse);
- title.y = MathHelper.lerp(tickDelta * 0.5F, title.y, y);
-
- //Translate the matrix to the texts position and scale
- context.getMatrices().push();
- context.getMatrices().translate(title.x, title.y, 0);
- context.getMatrices().scale(scale, scale, scale);
-
- //Draw text
- context.drawTextWithShadow(textRenderer, title.getText(), 0, 0, 0xFFFFFF);
- context.getMatrices().pop();
-
- //Calculate the x and y positions for the next title
- if (direction == UIAndVisualsConfig.Direction.HORIZONTAL) {
- if (alignment == UIAndVisualsConfig.Alignment.MIDDLE || alignment == UIAndVisualsConfig.Alignment.LEFT) {
- //Move to the right if middle or left aligned
- x += textRenderer.getWidth(title.getText()) * scale + 10;
- }
-
- if (alignment == UIAndVisualsConfig.Alignment.RIGHT) {
- //Move to the left if right aligned
- x -= textRenderer.getWidth(title.getText()) * scale + 10;
- }
- } else {
- //Y always moves by the same amount if vertical
- y += textRenderer.fontHeight * scale + 10;
- }
- }
- }
+ /**
+ * The set of titles which will be rendered.
+ *
+ * @see #containsTitle(Title)
+ * @see #addTitle(Title)
+ * @see #addTitle(Title, int)
+ * @see #removeTitle(Title)
+ */
+ private static final Set titles = new LinkedHashSet<>();
+
+ @Init
+ public static void init() {
+ HudRenderEvents.BEFORE_CHAT.register(TitleContainer::render);
+ ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker")
+ .then(ClientCommandManager.literal("hud")
+ .then(ClientCommandManager.literal("titleContainer")
+ .executes(Scheduler.queueOpenScreenCommand(TitleContainerConfigScreen::new))))));
+ }
+
+ /**
+ * Returns {@code true} if the title is currently shown.
+ *
+ * @param title the title to check
+ * @return whether the title in currently shown
+ */
+ public static boolean containsTitle(Title title) {
+ return titles.contains(title);
+ }
+
+ /**
+ * Adds a title to be shown
+ *
+ * @param title the title to be shown
+ * @return whether the title is already currently being shown
+ */
+ public static boolean addTitle(Title title) {
+ if (titles.add(title)) {
+ title.resetPos();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Adds a title to be shown for a set number of ticks
+ *
+ * @param title the title to be shown
+ * @param ticks the number of ticks to show the title
+ * @return whether the title is already currently being shown
+ */
+ public static boolean addTitle(Title title, int ticks) {
+ if (addTitle(title)) {
+ Scheduler.INSTANCE.schedule(() -> TitleContainer.removeTitle(title), ticks);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Stops showing a title
+ *
+ * @param title the title to stop showing
+ */
+ public static void removeTitle(Title title) {
+ titles.remove(title);
+ }
+
+ private static void render(DrawContext context, RenderTickCounter tickCounter) {
+ render(context, titles, SkyblockerConfigManager.get().uiAndVisuals.titleContainer.x, SkyblockerConfigManager.get().uiAndVisuals.titleContainer.y, tickCounter.getTickDelta(true));
+ }
+
+ protected static void render(DrawContext context, Set titles, int xPos, int yPos, float tickDelta) {
+ TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
+
+ // Calculate Scale to use
+ float scale = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.getRenderScale();
+ // Grab direction and alignment values
+ UIAndVisualsConfig.Direction direction = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.direction;
+ UIAndVisualsConfig.Alignment alignment = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment;
+
+ // x/y refer to the starting position for the text
+ // If left or right aligned or middle aligned vertically, start at xPos, we will shift each text later
+ float x = xPos;
+ // y always starts at yPos
+ float y = yPos;
+
+ // Calculate the width of combined text
+ float totalWidth = getWidth(textRenderer, titles);
+ if (alignment == UIAndVisualsConfig.Alignment.MIDDLE && direction == UIAndVisualsConfig.Direction.HORIZONTAL) {
+ // If middle aligned horizontally, start the xPosition at half of the width to the left.
+ x = xPos - totalWidth / 2;
+ }
+
+ for (Title title : titles) {
+ //Calculate which x the text should use
+ float xTextLeft = x;
+ if (alignment == UIAndVisualsConfig.Alignment.RIGHT) {
+ //if right aligned we need the text position to be aligned on the right side.
+ xTextLeft = x - textRenderer.getWidth(title.getText()) * scale;
+ } else if (direction == UIAndVisualsConfig.Direction.VERTICAL && alignment == UIAndVisualsConfig.Alignment.MIDDLE) {
+ //if middle aligned we need the text position to be aligned in the middle.
+ xTextLeft = x - (textRenderer.getWidth(title.getText()) * scale) / 2;
+ }
+
+ //Start displaying the title at the correct position, not at the default position
+ if (title.isDefaultPos()) {
+ title.x = xTextLeft;
+ title.y = y;
+ }
+
+ //Lerp the texts x and y variables
+ title.x = MathHelper.lerp(tickDelta * 0.5F, title.x, xTextLeft);
+ title.y = MathHelper.lerp(tickDelta * 0.5F, title.y, y);
+
+ //Translate the matrix to the texts position and scale
+ context.getMatrices().push();
+ context.getMatrices().translate(title.x, title.y, 0);
+ context.getMatrices().scale(scale, scale, scale);
+
+ //Draw text
+ context.drawTextWithShadow(textRenderer, title.getText(), 0, 0, 0xFFFFFF);
+ context.getMatrices().pop();
+
+ //Calculate the x and y positions for the next title
+ if (direction == UIAndVisualsConfig.Direction.HORIZONTAL) {
+ if (alignment == UIAndVisualsConfig.Alignment.MIDDLE || alignment == UIAndVisualsConfig.Alignment.LEFT) {
+ //Move to the right if middle or left aligned
+ x += (textRenderer.getWidth(title.getText()) + 10) * scale;
+ } else if (alignment == UIAndVisualsConfig.Alignment.RIGHT) {
+ //Move to the left if right aligned
+ x -= (textRenderer.getWidth(title.getText()) + 10) * scale;
+ }
+ } else {
+ //Y always moves by the same amount if vertical
+ y += (textRenderer.fontHeight + 1) * scale;
+ }
+ }
+ }
+
+ protected static int getWidth(TextRenderer textRenderer, Set titles) {
+ float scale = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.getRenderScale();
+ return SkyblockerConfigManager.get().uiAndVisuals.titleContainer.direction == UIAndVisualsConfig.Direction.HORIZONTAL ?
+ (int) ((titles.stream().map(Title::getText).mapToInt(textRenderer::getWidth).mapToDouble(width -> width + 10).sum() - 10) * scale) :
+ (int) (titles.stream().map(Title::getText).mapToInt(textRenderer::getWidth).max().orElse(0) * scale);
+ }
+
+ protected static int getHeight(TextRenderer textRenderer, Set titles) {
+ float scale = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.getRenderScale();
+ return SkyblockerConfigManager.get().uiAndVisuals.titleContainer.direction == UIAndVisualsConfig.Direction.HORIZONTAL ?
+ (int) (textRenderer.fontHeight * scale) :
+ (int) ((textRenderer.fontHeight + 1) * titles.size() * scale);
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java
index a8fbbea87c..69ba60a168 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java
@@ -1,191 +1,143 @@
package de.hysky.skyblocker.utils.render.title;
+import com.google.common.collect.ImmutableSet;
+import de.hysky.skyblocker.config.HudConfigScreen;
+import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.config.configs.UIAndVisualsConfig;
-import de.hysky.skyblocker.utils.render.RenderHelper;
+import de.hysky.skyblocker.utils.EnumUtils;
+import de.hysky.skyblocker.utils.render.gui.AbstractWidget;
+import de.hysky.skyblocker.utils.render.gui.EmptyWidget;
import dev.isxander.yacl3.api.ConfigCategory;
-import dev.isxander.yacl3.api.Option;
import dev.isxander.yacl3.api.OptionGroup;
import dev.isxander.yacl3.gui.YACLScreen;
+import it.unimi.dsi.fastutil.ints.IntIntMutablePair;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.resource.language.I18n;
-import net.minecraft.client.util.math.Vector2f;
import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableTextContent;
import net.minecraft.util.Formatting;
-import net.minecraft.util.Pair;
import org.lwjgl.glfw.GLFW;
import java.awt.*;
+import java.util.List;
import java.util.Set;
-public class TitleContainerConfigScreen extends Screen {
- private final Title example1 = new Title(Text.literal("Test1").formatted(Formatting.RED));
- private final Title example2 = new Title(Text.literal("Test23").formatted(Formatting.AQUA));
- private final Title example3 = new Title(Text.literal("Testing1234").formatted(Formatting.DARK_GREEN));
- private float hudX = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.x;
- private float hudY = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.y;
- private final Screen parent;
- private boolean changedScale;
-
- protected TitleContainerConfigScreen() {
- this(null);
- }
-
- public TitleContainerConfigScreen(Screen parent) {
- super(Text.of("Title Container HUD Config"));
- this.parent = parent;
- }
-
- @Override
- public void render(DrawContext context, int mouseX, int mouseY, float delta) {
- super.render(context, mouseX, mouseY, delta);
- renderBackground(context, mouseX, mouseY, delta);
- TitleContainer.render(context, Set.of(example1, example2, example3), (int) hudX, (int) hudY, delta);
- UIAndVisualsConfig.Direction direction = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.direction;
- UIAndVisualsConfig.Alignment alignment = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment;
- context.drawCenteredTextWithShadow(textRenderer, "Press Q/E to change Alignment: " + alignment, width / 2, textRenderer.fontHeight * 2, Color.WHITE.getRGB());
- context.drawCenteredTextWithShadow(textRenderer, "Press R to change Direction: " + direction, width / 2, textRenderer.fontHeight * 3 + 5, Color.WHITE.getRGB());
- context.drawCenteredTextWithShadow(textRenderer, "Press +/- to change Scale", width / 2, textRenderer.fontHeight * 4 + 10, Color.WHITE.getRGB());
- context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width / 2, textRenderer.fontHeight * 5 + 15, Color.GRAY.getRGB());
-
- Pair boundingBox = getSelectionBoundingBox();
- int x1 = (int) boundingBox.getLeft().getX();
- int y1 = (int) boundingBox.getLeft().getY();
- int x2 = (int) boundingBox.getRight().getX();
- int y2 = (int) boundingBox.getRight().getY();
-
- context.drawHorizontalLine(x1, x2, y1, Color.RED.getRGB());
- context.drawHorizontalLine(x1, x2, y2, Color.RED.getRGB());
- context.drawVerticalLine(x1, y1, y2, Color.RED.getRGB());
- context.drawVerticalLine(x2, y1, y2, Color.RED.getRGB());
- }
-
- private Pair getSelectionBoundingBox() {
- UIAndVisualsConfig.Alignment alignment = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment;
-
- float midWidth = getSelectionWidth() / 2F;
- float x1 = 0;
- float x2 = 0;
- float y1 = hudY;
- float y2 = hudY + getSelectionHeight();
- switch (alignment) {
- case RIGHT -> {
- x1 = hudX - midWidth * 2;
- x2 = hudX;
- }
- case MIDDLE -> {
- x1 = hudX - midWidth;
- x2 = hudX + midWidth;
- }
- case LEFT -> {
- x1 = hudX;
- x2 = hudX + midWidth * 2;
- }
- }
- return new Pair<>(new Vector2f(x1, y1), new Vector2f(x2, y2));
- }
-
- private float getSelectionHeight() {
- float scale = (3F * (SkyblockerConfigManager.get().uiAndVisuals.titleContainer.titleContainerScale / 100F));
- return SkyblockerConfigManager.get().uiAndVisuals.titleContainer.direction == UIAndVisualsConfig.Direction.HORIZONTAL ?
- (textRenderer.fontHeight * scale) :
- (textRenderer.fontHeight + 10F) * 3F * scale;
- }
-
- private float getSelectionWidth() {
- float scale = (3F * (SkyblockerConfigManager.get().uiAndVisuals.titleContainer.titleContainerScale / 100F));
- return SkyblockerConfigManager.get().uiAndVisuals.titleContainer.direction == UIAndVisualsConfig.Direction.HORIZONTAL ?
- (textRenderer.getWidth("Test1") + 10 + textRenderer.getWidth("Test23") + 10 + textRenderer.getWidth("Testing1234")) * scale :
- textRenderer.getWidth("Testing1234") * scale;
- }
-
- @Override
- public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
- float midWidth = getSelectionWidth() / 2;
- float midHeight = getSelectionHeight() / 2;
- var alignment = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment;
-
- Pair boundingBox = getSelectionBoundingBox();
- float x1 = boundingBox.getLeft().getX();
- float y1 = boundingBox.getLeft().getY();
- float x2 = boundingBox.getRight().getX();
- float y2 = boundingBox.getRight().getY();
-
- if (RenderHelper.pointIsInArea(mouseX, mouseY, x1, y1, x2, y2) && button == 0) {
- hudX = switch (alignment) {
- case LEFT -> (int) mouseX - midWidth;
- case MIDDLE -> (int) mouseX;
- case RIGHT -> (int) mouseX + midWidth;
- };
- hudY = (int) (mouseY - midHeight);
- }
- return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
- }
-
- @Override
- public boolean mouseClicked(double mouseX, double mouseY, int button) {
- if (button == 1) {
- hudX = (float) this.width / 2;
- hudY = this.height * 0.6F;
- }
- return super.mouseClicked(mouseX, mouseY, button);
- }
-
- @Override
- public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
- if (keyCode == GLFW.GLFW_KEY_Q) {
- UIAndVisualsConfig.Alignment current = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment;
- SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment = switch (current) {
- case LEFT -> UIAndVisualsConfig.Alignment.MIDDLE;
- case MIDDLE -> UIAndVisualsConfig.Alignment.RIGHT;
- case RIGHT -> UIAndVisualsConfig.Alignment.LEFT;
- };
- }
- if (keyCode == GLFW.GLFW_KEY_E) {
- UIAndVisualsConfig.Alignment current = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment;
- SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment = switch (current) {
- case LEFT -> UIAndVisualsConfig.Alignment.RIGHT;
- case MIDDLE -> UIAndVisualsConfig.Alignment.LEFT;
- case RIGHT -> UIAndVisualsConfig.Alignment.MIDDLE;
- };
- }
- if (keyCode == GLFW.GLFW_KEY_R) {
- UIAndVisualsConfig.Direction current = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.direction;
- SkyblockerConfigManager.get().uiAndVisuals.titleContainer.direction = switch (current) {
- case HORIZONTAL -> UIAndVisualsConfig.Direction.VERTICAL;
- case VERTICAL -> UIAndVisualsConfig.Direction.HORIZONTAL;
- };
- }
- if (keyCode == GLFW.GLFW_KEY_EQUAL) {
- SkyblockerConfigManager.get().uiAndVisuals.titleContainer.titleContainerScale += 10;
- changedScale = true;
- }
- if (keyCode == GLFW.GLFW_KEY_MINUS) {
- SkyblockerConfigManager.get().uiAndVisuals.titleContainer.titleContainerScale -= 10;
- changedScale = true;
- }
- return super.keyPressed(keyCode, scanCode, modifiers);
- }
-
-
- @Override
- public void close() {
- SkyblockerConfigManager.get().uiAndVisuals.titleContainer.x = (int) hudX;
- SkyblockerConfigManager.get().uiAndVisuals.titleContainer.y = (int) hudY;
-
- //TODO Come up with a better, less hacky solution for this in the future (:
- if (parent instanceof YACLScreen yaclScreen) {
- ConfigCategory category = yaclScreen.config.categories().stream().filter(cat -> cat.name().getString().equals(I18n.translate("skyblocker.config.uiAndVisuals"))).findFirst().orElseThrow();
- OptionGroup group = category.groups().stream().filter(grp -> grp.name().getString().equals(I18n.translate("skyblocker.config.uiAndVisuals.titleContainer"))).findFirst().orElseThrow();
-
- Option> scaleOpt = group.options().getFirst();
-
- // Refresh the value in the config with the bound value
- if (changedScale) scaleOpt.forgetPendingValue();
- }
-
- SkyblockerConfigManager.save();
- this.client.setScreen(parent);
- }
+public class TitleContainerConfigScreen extends HudConfigScreen {
+ // ImmutableSet preserves insertion order
+ private static final Set EXAMPLES = ImmutableSet.of(
+ new Title(Text.literal("Test1").formatted(Formatting.RED)),
+ new Title(Text.literal("Test23").formatted(Formatting.AQUA)),
+ new Title(Text.literal("Testing1234").formatted(Formatting.DARK_GREEN))
+ );
+ private boolean changedScale;
+
+ protected TitleContainerConfigScreen() {
+ this(null);
+ }
+
+ public TitleContainerConfigScreen(Screen parent) {
+ super(Text.of("Title Container HUD Config"), parent, new EmptyWidget());
+ }
+
+ @Override
+ protected void init() {
+ super.init();
+ // Load the config positions here since #getConfigPos is used for resetting. This loads the config pos after the supertype constructor calls HudConfigScreen#resetPos.
+ widgets.getFirst().setPosition(SkyblockerConfigManager.get().uiAndVisuals.titleContainer.x, SkyblockerConfigManager.get().uiAndVisuals.titleContainer.y);
+ // Set the dimensions here or else Screen#textRenderer is null.
+ updateWidgetDimensions();
+ }
+
+ @Override
+ protected void renderWidget(DrawContext context, List widgets, float delta) {
+ super.renderWidget(context, widgets, delta);
+ TitleContainer.render(context, EXAMPLES, widgets.getFirst().getX(), widgets.getFirst().getY(), delta);
+ UIAndVisualsConfig.Direction direction = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.direction;
+ UIAndVisualsConfig.Alignment alignment = SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment;
+ context.drawCenteredTextWithShadow(textRenderer, "Press Q/E to change Alignment: " + alignment, width / 2, textRenderer.fontHeight * 2, Color.WHITE.getRGB());
+ context.drawCenteredTextWithShadow(textRenderer, "Press R to change Direction: " + direction, width / 2, textRenderer.fontHeight * 3 + 5, Color.WHITE.getRGB());
+ context.drawCenteredTextWithShadow(textRenderer, "Press +/- to change Scale", width / 2, textRenderer.fontHeight * 4 + 10, Color.WHITE.getRGB());
+ context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width / 2, textRenderer.fontHeight * 5 + 15, Color.GRAY.getRGB());
+
+ int selectionWidth = getSelectionWidth();
+ int x1 = switch (alignment) {
+ case LEFT -> widgets.getFirst().getX();
+ case MIDDLE -> widgets.getFirst().getX() - selectionWidth / 2;
+ case RIGHT -> widgets.getFirst().getX() - selectionWidth;
+ };
+ int y1 = widgets.getFirst().getY();
+ int x2 = x1 + selectionWidth;
+ int y2 = y1 + getSelectionHeight();
+
+ context.drawHorizontalLine(x1, x2, y1, Color.RED.getRGB());
+ context.drawHorizontalLine(x1, x2, y2, Color.RED.getRGB());
+ context.drawVerticalLine(x1, y1, y2, Color.RED.getRGB());
+ context.drawVerticalLine(x2, y1, y2, Color.RED.getRGB());
+ }
+
+ private void updateWidgetDimensions() {
+ widgets.getFirst().setDimensions(getSelectionWidth(), getSelectionHeight());
+ }
+
+ private int getSelectionWidth() {
+ return TitleContainer.getWidth(textRenderer, EXAMPLES);
+ }
+
+ private int getSelectionHeight() {
+ return TitleContainer.getHeight(textRenderer, EXAMPLES);
+ }
+
+ @Override
+ public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
+ switch (keyCode) {
+ case GLFW.GLFW_KEY_Q -> SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment = EnumUtils.cycle(SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment);
+ case GLFW.GLFW_KEY_E -> SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment = EnumUtils.cycleBackwards(SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment);
+ case GLFW.GLFW_KEY_R -> {
+ SkyblockerConfigManager.get().uiAndVisuals.titleContainer.direction = EnumUtils.cycle(SkyblockerConfigManager.get().uiAndVisuals.titleContainer.direction);
+ updateWidgetDimensions();
+ }
+ case GLFW.GLFW_KEY_EQUAL -> {
+ SkyblockerConfigManager.get().uiAndVisuals.titleContainer.titleContainerScale += 10;
+ updateWidgetDimensions();
+ changedScale = true;
+ }
+ case GLFW.GLFW_KEY_MINUS -> {
+ SkyblockerConfigManager.get().uiAndVisuals.titleContainer.titleContainerScale -= 10;
+ updateWidgetDimensions();
+ changedScale = true;
+ }
+ }
+ return super.keyPressed(keyCode, scanCode, modifiers);
+ }
+
+ @Override
+ protected int getWidgetXOffset(AbstractWidget widget) {
+ return switch (SkyblockerConfigManager.get().uiAndVisuals.titleContainer.alignment) {
+ case LEFT -> 0;
+ case MIDDLE -> -getSelectionWidth() / 2;
+ case RIGHT -> -getSelectionWidth();
+ };
+ }
+
+ @Override
+ protected List getConfigPos(SkyblockerConfig config) {
+ // This gets the reset pos. The actual config pos is loaded in #init.
+ return List.of(IntIntMutablePair.of(this.width / 2, (int) (this.height * 0.6)));
+ }
+
+ @Override
+ protected void savePos(SkyblockerConfig configManager, List widgets) {
+ SkyblockerConfigManager.get().uiAndVisuals.titleContainer.x = widgets.getFirst().getX();
+ SkyblockerConfigManager.get().uiAndVisuals.titleContainer.y = widgets.getFirst().getY();
+
+ //TODO Come up with a better, less hacky solution for this in the future (:
+ if (changedScale && parent instanceof YACLScreen yaclScreen) {
+ ConfigCategory category = yaclScreen.config.categories().stream().filter(cat -> cat.name().getContent() instanceof TranslatableTextContent translatable && translatable.getKey().equals("skyblocker.config.uiAndVisuals")).findFirst().orElseThrow();
+ OptionGroup group = category.groups().stream().filter(grp -> grp.name().getContent() instanceof TranslatableTextContent translatable && translatable.getKey().equals("skyblocker.config.uiAndVisuals.titleContainer")).findFirst().orElseThrow();
+
+ // Refresh the value in the config with the bound value
+ group.options().getFirst().forgetPendingValue();
+ }
+ }
}