aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisXander <xandersmith2008@gmail.com>2022-12-01 18:17:59 +0000
committerisXander <xandersmith2008@gmail.com>2022-12-01 18:17:59 +0000
commitaba4bcb529e7613de181ea7410fc3d371c9b3d07 (patch)
tree52244a40a4cc88267ae1692edb720b13160a1daa
parent60a06e94e2fc176294f9ff426fee6d0621946c22 (diff)
downloadYetAnotherConfigLib-aba4bcb529e7613de181ea7410fc3d371c9b3d07.tar.gz
YetAnotherConfigLib-aba4bcb529e7613de181ea7410fc3d371c9b3d07.tar.bz2
YetAnotherConfigLib-aba4bcb529e7613de181ea7410fc3d371c9b3d07.zip
generify element list widgets and prevent wrapping soft-lock
-rw-r--r--src/client/java/dev/isxander/yacl/gui/CategoryListWidget.java20
-rw-r--r--src/client/java/dev/isxander/yacl/gui/ElementListWidgetExt.java152
-rw-r--r--src/client/java/dev/isxander/yacl/gui/OptionListWidget.java125
-rw-r--r--src/client/java/dev/isxander/yacl/gui/YACLScreen.java5
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/BooleanController.java9
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java4
6 files changed, 187 insertions, 128 deletions
diff --git a/src/client/java/dev/isxander/yacl/gui/CategoryListWidget.java b/src/client/java/dev/isxander/yacl/gui/CategoryListWidget.java
index 46a9fdf..4dbcb11 100644
--- a/src/client/java/dev/isxander/yacl/gui/CategoryListWidget.java
+++ b/src/client/java/dev/isxander/yacl/gui/CategoryListWidget.java
@@ -11,11 +11,11 @@ import net.minecraft.client.util.math.MatrixStack;
import java.util.List;
-public class CategoryListWidget extends ElementListWidget<CategoryListWidget.CategoryEntry> {
+public class CategoryListWidget extends ElementListWidgetExt<CategoryListWidget.CategoryEntry> {
private final YACLScreen yaclScreen;
public CategoryListWidget(MinecraftClient client, YACLScreen yaclScreen, int screenWidth, int screenHeight) {
- super(client, screenWidth / 3, yaclScreen.searchFieldWidget.getY() - 5, 0, yaclScreen.searchFieldWidget.getY() - 5, 21);
+ super(client, 0, 0, screenWidth / 3, yaclScreen.searchFieldWidget.getY() - 5, true);
this.yaclScreen = yaclScreen;
setRenderBackground(false);
setRenderHorizontalShadows(false);
@@ -26,10 +26,10 @@ public class CategoryListWidget extends ElementListWidget<CategoryListWidget.Cat
}
@Override
- protected void renderList(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+ public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
double d = this.client.getWindow().getScaleFactor();
RenderSystem.enableScissor(0, (int)((yaclScreen.height - bottom) * d), (int)(width * d), (int)(height * d));
- super.renderList(matrices, mouseX, mouseY, delta);
+ super.render(matrices, mouseX, mouseY, delta);
RenderSystem.disableScissor();
}
@@ -54,6 +54,11 @@ public class CategoryListWidget extends ElementListWidget<CategoryListWidget.Cat
return width - 2;
}
+ @Override
+ protected void renderBackground(MatrixStack matrices) {
+
+ }
+
public class CategoryEntry extends Entry<CategoryEntry> {
private final CategoryWidget categoryButton;
public final int categoryIndex;
@@ -79,11 +84,16 @@ public class CategoryListWidget extends ElementListWidget<CategoryListWidget.Cat
categoryButton.render(matrices, mouseX, mouseY, tickDelta);
}
- private void postRender(MatrixStack matrices, int mouseX, int mouseY, float tickDelta) {
+ public void postRender(MatrixStack matrices, int mouseX, int mouseY, float tickDelta) {
categoryButton.renderHoveredTooltip(matrices);
}
@Override
+ public int getItemHeight() {
+ return 21;
+ }
+
+ @Override
public List<? extends Element> children() {
return ImmutableList.of(categoryButton);
}
diff --git a/src/client/java/dev/isxander/yacl/gui/ElementListWidgetExt.java b/src/client/java/dev/isxander/yacl/gui/ElementListWidgetExt.java
new file mode 100644
index 0000000..f2a19f2
--- /dev/null
+++ b/src/client/java/dev/isxander/yacl/gui/ElementListWidgetExt.java
@@ -0,0 +1,152 @@
+package dev.isxander.yacl.gui;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.widget.ElementListWidget;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.util.math.MathHelper;
+import org.jetbrains.annotations.Nullable;
+
+public class ElementListWidgetExt<E extends ElementListWidgetExt.Entry<E>> extends ElementListWidget<E> {
+ protected final int x, y;
+
+ private double smoothScrollAmount = getScrollAmount();
+ private boolean returnSmoothAmount = false;
+ private final boolean doSmoothScrolling;
+
+ public ElementListWidgetExt(MinecraftClient client, int x, int y, int width, int height, boolean smoothScrolling) {
+ super(client, width, height, y, y + height, 22);
+ this.x = x;
+ this.y = y;
+ this.left = x;
+ this.right = this.left + width;
+ this.doSmoothScrolling = smoothScrolling;
+ }
+
+ @Override
+ public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
+ // default implementation bases scroll step from total height of entries, this is constant
+ this.setScrollAmount(this.getScrollAmount() - amount * 20);
+ return true;
+ }
+
+ @Override
+ protected void renderBackground(MatrixStack matrices) {
+ // render transparent background if in-game.
+ setRenderBackground(client.world == null);
+ if (client.world != null)
+ fill(matrices, left, top, right, bottom, 0x6B000000);
+ }
+
+ @Override
+ protected int getScrollbarPositionX() {
+ // default implementation does not respect left/right
+ return this.right - 2;
+ }
+
+ @Override
+ public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+ smoothScrollAmount = MathHelper.lerp(MinecraftClient.getInstance().getLastFrameDuration() * 0.5, smoothScrollAmount, getScrollAmount());
+ returnSmoothAmount = true;
+ super.render(matrices, mouseX, mouseY, delta);
+ returnSmoothAmount = false;
+ }
+
+ /**
+ * awful code to only use smooth scroll state when rendering,
+ * not other code that needs target scroll amount
+ */
+ @Override
+ public double getScrollAmount() {
+ if (returnSmoothAmount && doSmoothScrolling)
+ return smoothScrollAmount;
+
+ return super.getScrollAmount();
+ }
+
+ protected void resetSmoothScrolling() {
+ this.smoothScrollAmount = getScrollAmount();
+ }
+
+ public void postRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+ for (E entry : children()) {
+ entry.postRender(matrices, mouseX, mouseY, delta);
+ }
+ }
+
+ /*
+ below code is licensed from cloth-config under LGPL3
+ modified to inherit vanilla's EntryListWidget and use yarn mappings
+
+ code is responsible for having dynamic item heights
+ */
+
+ @Nullable
+ @Override
+ protected E getEntryAtPosition(double x, double y) {
+ int listMiddleX = this.left + this.width / 2;
+ int minX = listMiddleX - this.getRowWidth() / 2;
+ int maxX = listMiddleX + this.getRowWidth() / 2;
+ int currentY = MathHelper.floor(y - (double) this.top) - this.headerHeight + (int) this.getScrollAmount() - 4;
+ int itemY = 0;
+ int itemIndex = -1;
+ for (int i = 0; i < children().size(); i++) {
+ E item = children().get(i);
+ itemY += item.getItemHeight();
+ if (itemY > currentY) {
+ itemIndex = i;
+ break;
+ }
+ }
+ return x < (double) this.getScrollbarPositionX() && x >= minX && y <= maxX && itemIndex >= 0 && currentY >= 0 && itemIndex < this.getEntryCount() ? this.children().get(itemIndex) : null;
+ }
+
+ @Override
+ protected int getMaxPosition() {
+ return children().stream().map(E::getItemHeight).reduce(0, Integer::sum) + headerHeight;
+ }
+
+ @Override
+ protected void centerScrollOn(E entry) {
+ double d = (this.bottom - this.top) / -2d;
+ for (int i = 0; i < this.children().indexOf(entry) && i < this.getEntryCount(); i++)
+ d += children().get(i).getItemHeight();
+ this.setScrollAmount(d);
+ }
+
+ @Override
+ protected int getRowTop(int index) {
+ int integer = top + 4 - (int) this.getScrollAmount() + headerHeight;
+ for (int i = 0; i < children().size() && i < index; i++)
+ integer += children().get(i).getItemHeight();
+ return integer;
+ }
+
+ @Override
+ protected void renderList(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+ int left = this.getRowLeft();
+ int right = this.getRowWidth();
+ int count = this.getEntryCount();
+
+ for(int i = 0; i < count; ++i) {
+ E entry = children().get(i);
+ int top = this.getRowTop(i);
+ int bottom = top + entry.getItemHeight();
+ int entryHeight = entry.getItemHeight() - 4;
+ if (bottom >= this.top && top <= this.bottom) {
+ this.renderEntry(matrices, mouseX, mouseY, delta, i, left, top, right, entryHeight);
+ }
+ }
+ }
+
+ /* END cloth config code */
+
+ public abstract static class Entry<E extends ElementListWidgetExt.Entry<E>> extends ElementListWidget.Entry<E> {
+ public void postRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+
+ }
+
+ public int getItemHeight() {
+ return 22;
+ }
+ }
+}
diff --git a/src/client/java/dev/isxander/yacl/gui/OptionListWidget.java b/src/client/java/dev/isxander/yacl/gui/OptionListWidget.java
index eed3aff..785f4e2 100644
--- a/src/client/java/dev/isxander/yacl/gui/OptionListWidget.java
+++ b/src/client/java/dev/isxander/yacl/gui/OptionListWidget.java
@@ -22,20 +22,15 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.function.Supplier;
-public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry> {
+public class OptionListWidget extends ElementListWidgetExt<OptionListWidget.Entry> {
private final YACLScreen yaclScreen;
private boolean singleCategory = false;
private ImmutableList<Entry> viewableChildren;
- private double smoothScrollAmount = getScrollAmount();
- private boolean returnSmoothAmount = false;
-
public OptionListWidget(YACLScreen screen, MinecraftClient client, int width, int height) {
- super(client, width / 3 * 2, height, 0, height, 22);
+ super(client, width / 3, 0, width / 3 * 2, height, true);
this.yaclScreen = screen;
- left = width - this.width;
- right = width;
refreshOptions();
}
@@ -78,6 +73,7 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
recacheViewableChildren();
setScrollAmount(0);
+ resetSmoothScrolling();
}
public void expandAllGroups() {
@@ -88,97 +84,6 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
}
}
- /*
- below code is licensed from cloth-config under LGPL3
- modified to inherit vanilla's EntryListWidget and use yarn mappings
- */
-
- @Nullable
- @Override
- protected Entry getEntryAtPosition(double x, double y) {
- int listMiddleX = this.left + this.width / 2;
- int minX = listMiddleX - this.getRowWidth() / 2;
- int maxX = listMiddleX + this.getRowWidth() / 2;
- int currentY = MathHelper.floor(y - (double) this.top) - this.headerHeight + (int) this.getScrollAmount() - 4;
- int itemY = 0;
- int itemIndex = -1;
- for (int i = 0; i < children().size(); i++) {
- Entry item = children().get(i);
- itemY += item.getItemHeight();
- if (itemY > currentY) {
- itemIndex = i;
- break;
- }
- }
- return x < (double) this.getScrollbarPositionX() && x >= minX && y <= maxX && itemIndex >= 0 && currentY >= 0 && itemIndex < this.getEntryCount() ? this.children().get(itemIndex) : null;
- }
-
- @Override
- protected int getMaxPosition() {
- return children().stream().map(Entry::getItemHeight).reduce(0, Integer::sum) + headerHeight;
- }
-
- @Override
- protected void centerScrollOn(Entry entry) {
- double d = (this.bottom - this.top) / -2d;
- for (int i = 0; i < this.children().indexOf(entry) && i < this.getEntryCount(); i++)
- d += children().get(i).getItemHeight();
- this.setScrollAmount(d);
- }
-
- @Override
- protected int getRowTop(int index) {
- int integer = top + 4 - (int) this.getScrollAmount() + headerHeight;
- for (int i = 0; i < children().size() && i < index; i++)
- integer += children().get(i).getItemHeight();
- return integer;
- }
-
- @Override
- protected void renderList(MatrixStack matrices, int mouseX, int mouseY, float delta) {
- int left = this.getRowLeft();
- int right = this.getRowWidth();
- int count = this.getEntryCount();
-
- for(int i = 0; i < count; ++i) {
- Entry entry = children().get(i);
- int top = this.getRowTop(i);
- int bottom = top + entry.getItemHeight();
- int entryHeight = entry.getItemHeight() - 4;
- if (bottom >= this.top && top <= this.bottom) {
- this.renderEntry(matrices, mouseX, mouseY, delta, i, left, top, right, entryHeight);
- }
- }
- }
-
- /* END cloth config code */
-
- @Override
- public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
- smoothScrollAmount = MathHelper.lerp(MinecraftClient.getInstance().getLastFrameDuration() * 0.5, smoothScrollAmount, getScrollAmount());
- returnSmoothAmount = true;
- super.render(matrices, mouseX, mouseY, delta);
- returnSmoothAmount = false;
- }
-
- /**
- * awful code to only use smooth scroll state when rendering,
- * not other code that needs target scroll amount
- */
- @Override
- public double getScrollAmount() {
- if (returnSmoothAmount)
- return smoothScrollAmount;
-
- return super.getScrollAmount();
- }
-
- public void postRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
- for (Entry entry : children()) {
- entry.postRender(matrices, mouseX, mouseY, delta);
- }
- }
-
@Override
public int getRowWidth() {
return Math.min(396, (int)(width / 1.3f));
@@ -196,12 +101,13 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
+ super.mouseScrolled(mouseX, mouseY, amount);
+
for (Entry child : children()) {
if (child.mouseScrolled(mouseX, mouseY, amount))
- return true;
+ break;
}
- this.setScrollAmount(this.getScrollAmount() - amount * 20 /* * (double) (getMaxScroll() / getEntryCount()) / 2.0D */);
return true;
}
@@ -227,14 +133,7 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
@Override
protected int getScrollbarPositionX() {
- return left + width - (int)(width * 0.05f);
- }
-
- @Override
- protected void renderBackground(MatrixStack matrices) {
- setRenderBackground(client.world == null);
- if (client.world != null)
- fill(matrices, left, top, right, bottom, 0x6B000000);
+ return right - (int)(width * 0.05f);
}
public void recacheViewableChildren() {
@@ -254,19 +153,11 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
return viewableChildren;
}
- public abstract class Entry extends ElementListWidget.Entry<Entry> {
- public void postRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
-
- }
-
+ public abstract class Entry extends ElementListWidgetExt.Entry<Entry> {
public boolean isViewable() {
return true;
}
- public int getItemHeight() {
- return 22;
- }
-
protected boolean isHovered() {
return Objects.equals(getHoveredEntry(), this);
}
diff --git a/src/client/java/dev/isxander/yacl/gui/YACLScreen.java b/src/client/java/dev/isxander/yacl/gui/YACLScreen.java
index e700009..1fbc769 100644
--- a/src/client/java/dev/isxander/yacl/gui/YACLScreen.java
+++ b/src/client/java/dev/isxander/yacl/gui/YACLScreen.java
@@ -13,6 +13,7 @@ import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.tooltip.TooltipBackgroundRenderer;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import org.joml.Matrix4f;
@@ -160,9 +161,9 @@ public class YACLScreen extends Screen {
boolean pendingChanges = pendingChanges();
undoButton.active = pendingChanges;
- finishedSaveButton.setMessage(pendingChanges ? Text.translatable("yacl.gui.save") : Text.translatable("gui.done"));
+ finishedSaveButton.setMessage(pendingChanges ? Text.translatable("yacl.gui.save") : ScreenTexts.DONE);
finishedSaveButton.setTooltip(pendingChanges ? Text.translatable("yacl.gui.save.tooltip") : Text.translatable("yacl.gui.finished.tooltip"));
- cancelResetButton.setMessage(pendingChanges ? Text.translatable("gui.cancel") : Text.translatable("controls.reset"));
+ cancelResetButton.setMessage(pendingChanges ? ScreenTexts.CANCEL : Text.translatable("controls.reset"));
cancelResetButton.setTooltip(pendingChanges ? Text.translatable("yacl.gui.cancel.tooltip") : Text.translatable("yacl.gui.reset.tooltip"));
}
diff --git a/src/client/java/dev/isxander/yacl/gui/controllers/BooleanController.java b/src/client/java/dev/isxander/yacl/gui/controllers/BooleanController.java
index 7037ff5..b696831 100644
--- a/src/client/java/dev/isxander/yacl/gui/controllers/BooleanController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/BooleanController.java
@@ -6,6 +6,7 @@ import dev.isxander.yacl.api.utils.Dimension;
import dev.isxander.yacl.gui.AbstractWidget;
import dev.isxander.yacl.gui.YACLScreen;
import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import org.lwjgl.glfw.GLFW;
@@ -19,8 +20,8 @@ public class BooleanController implements Controller<Boolean> {
public static final Function<Boolean, Text> ON_OFF_FORMATTER = (state) ->
state
- ? Text.translatable("options.on")
- : Text.translatable("options.off");
+ ? ScreenTexts.ON
+ : ScreenTexts.OFF;
public static final Function<Boolean, Text> TRUE_FALSE_FORMATTER = (state) ->
state
@@ -29,8 +30,8 @@ public class BooleanController implements Controller<Boolean> {
public static final Function<Boolean, Text> YES_NO_FORMATTER = (state) ->
state
- ? Text.translatable("gui.yes")
- : Text.translatable("gui.no");
+ ? ScreenTexts.YES
+ : ScreenTexts.NO;
private final Option<Boolean> option;
private final Function<Boolean, Text> valueFormatter;
diff --git a/src/client/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java b/src/client/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java
index c7f9e97..cebaba7 100644
--- a/src/client/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java
@@ -4,6 +4,7 @@ import dev.isxander.yacl.api.Controller;
import dev.isxander.yacl.api.utils.Dimension;
import dev.isxander.yacl.gui.AbstractWidget;
import dev.isxander.yacl.gui.YACLScreen;
+import dev.isxander.yacl.impl.utils.YACLConstants;
import net.minecraft.client.font.MultilineText;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
@@ -44,6 +45,9 @@ public abstract class ControllerWidget<T extends Controller<?>> extends Abstract
nameString = nameString.substring(0, Math.max(nameString.length() - (firstIter ? 2 : 5), 0)).trim();
nameString += "...";
+ if (nameString.equals("..."))
+ break;
+
firstIter = false;
}