|
@@ -3,33 +3,58 @@ package me.shedaniel.clothconfig2.gui;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Maps;
|
|
import com.google.common.collect.Maps;
|
|
import com.mojang.blaze3d.systems.RenderSystem;
|
|
import com.mojang.blaze3d.systems.RenderSystem;
|
|
|
|
+import me.shedaniel.clothconfig2.ClothConfigInitializer;
|
|
import me.shedaniel.clothconfig2.api.*;
|
|
import me.shedaniel.clothconfig2.api.*;
|
|
import me.shedaniel.math.Rectangle;
|
|
import me.shedaniel.math.Rectangle;
|
|
import net.minecraft.class_5348;
|
|
import net.minecraft.class_5348;
|
|
import net.minecraft.client.MinecraftClient;
|
|
import net.minecraft.client.MinecraftClient;
|
|
import net.minecraft.client.gui.Element;
|
|
import net.minecraft.client.gui.Element;
|
|
import net.minecraft.client.gui.screen.Screen;
|
|
import net.minecraft.client.gui.screen.Screen;
|
|
-import net.minecraft.client.gui.widget.AbstractPressableButtonWidget;
|
|
|
|
|
|
+import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
|
import net.minecraft.client.gui.widget.ButtonWidget;
|
|
import net.minecraft.client.gui.widget.ButtonWidget;
|
|
import net.minecraft.client.render.BufferBuilder;
|
|
import net.minecraft.client.render.BufferBuilder;
|
|
import net.minecraft.client.render.Tessellator;
|
|
import net.minecraft.client.render.Tessellator;
|
|
|
|
+import net.minecraft.client.render.VertexConsumerProvider;
|
|
import net.minecraft.client.render.VertexFormats;
|
|
import net.minecraft.client.render.VertexFormats;
|
|
|
|
+import net.minecraft.client.sound.PositionedSoundInstance;
|
|
import net.minecraft.client.util.NarratorManager;
|
|
import net.minecraft.client.util.NarratorManager;
|
|
import net.minecraft.client.util.math.MatrixStack;
|
|
import net.minecraft.client.util.math.MatrixStack;
|
|
|
|
+import net.minecraft.sound.SoundEvents;
|
|
import net.minecraft.text.LiteralText;
|
|
import net.minecraft.text.LiteralText;
|
|
|
|
+import net.minecraft.text.MutableText;
|
|
import net.minecraft.text.Text;
|
|
import net.minecraft.text.Text;
|
|
import net.minecraft.text.TranslatableText;
|
|
import net.minecraft.text.TranslatableText;
|
|
import net.minecraft.util.Formatting;
|
|
import net.minecraft.util.Formatting;
|
|
import net.minecraft.util.Identifier;
|
|
import net.minecraft.util.Identifier;
|
|
import net.minecraft.util.Pair;
|
|
import net.minecraft.util.Pair;
|
|
|
|
+import net.minecraft.util.math.MathHelper;
|
|
import net.minecraft.util.math.Matrix4f;
|
|
import net.minecraft.util.math.Matrix4f;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
+import org.jetbrains.annotations.ApiStatus;
|
|
|
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
|
|
-public class GlobalizedClothConfigScreen extends AbstractConfigScreen implements ReferenceBuildingConfigScreen {
|
|
|
|
|
|
+public class GlobalizedClothConfigScreen extends AbstractConfigScreen implements ReferenceBuildingConfigScreen, Expandable {
|
|
public ClothConfigScreen.ListWidget<AbstractConfigEntry<AbstractConfigEntry<?>>> listWidget;
|
|
public ClothConfigScreen.ListWidget<AbstractConfigEntry<AbstractConfigEntry<?>>> listWidget;
|
|
|
|
+ private AbstractButtonWidget cancelButton, exitButton;
|
|
private final LinkedHashMap<Text, List<AbstractConfigEntry<?>>> categorizedEntries = Maps.newLinkedHashMap();
|
|
private final LinkedHashMap<Text, List<AbstractConfigEntry<?>>> categorizedEntries = Maps.newLinkedHashMap();
|
|
|
|
+ private final ScrollingContainer sideScroller = new ScrollingContainer() {
|
|
|
|
+ @Override
|
|
|
|
+ public Rectangle getBounds() {
|
|
|
|
+ return new Rectangle(4, 4, getSideSliderPosition() - 14 - 4, height - 8);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public int getMaxScrollHeight() {
|
|
|
|
+ int i = 0;
|
|
|
|
+ for (Reference reference : references) {
|
|
|
|
+ if (i != 0) i += 3 * reference.getScale();
|
|
|
|
+ i += textRenderer.fontHeight * reference.getScale();
|
|
|
|
+ }
|
|
|
|
+ return i;
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ private Reference lastHoveredReference = null;
|
|
private final ScrollingContainer sideSlider = new ScrollingContainer() {
|
|
private final ScrollingContainer sideSlider = new ScrollingContainer() {
|
|
private Rectangle empty = new Rectangle();
|
|
private Rectangle empty = new Rectangle();
|
|
|
|
|
|
@@ -40,23 +65,23 @@ public class GlobalizedClothConfigScreen extends AbstractConfigScreen implements
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public int getMaxScrollHeight() {
|
|
public int getMaxScrollHeight() {
|
|
- return GlobalizedClothConfigScreen.this.sideExpandLimit.get();
|
|
|
|
|
|
+ return 1;
|
|
}
|
|
}
|
|
};
|
|
};
|
|
private final List<Reference> references = Lists.newArrayList();
|
|
private final List<Reference> references = Lists.newArrayList();
|
|
private final LazyResettable<Integer> sideExpandLimit = new LazyResettable<>(() -> {
|
|
private final LazyResettable<Integer> sideExpandLimit = new LazyResettable<>(() -> {
|
|
int max = 0;
|
|
int max = 0;
|
|
for (Reference reference : references) {
|
|
for (Reference reference : references) {
|
|
- Text category = reference.getText();
|
|
|
|
- int width = textRenderer.getWidth(new LiteralText(StringUtils.repeat(" ", reference.getIndent()) + "- ").append(category));
|
|
|
|
|
|
+ Text referenceText = reference.getText();
|
|
|
|
+ int width = textRenderer.getWidth(new LiteralText(StringUtils.repeat(" ", reference.getIndent()) + "- ").append(referenceText));
|
|
if (width > max) max = width;
|
|
if (width > max) max = width;
|
|
}
|
|
}
|
|
- return max + 8;
|
|
|
|
|
|
+ return Math.min(max + 8, width / 4);
|
|
});
|
|
});
|
|
private boolean requestingReferenceRebuilding = false;
|
|
private boolean requestingReferenceRebuilding = false;
|
|
|
|
|
|
- @Deprecated
|
|
|
|
- protected GlobalizedClothConfigScreen(Screen parent, Text title, Map<Text, List<Object>> entriesMap, Identifier backgroundLocation) {
|
|
|
|
|
|
+ @ApiStatus.Internal
|
|
|
|
+ public GlobalizedClothConfigScreen(Screen parent, Text title, Map<Text, List<Object>> entriesMap, Identifier backgroundLocation) {
|
|
super(parent, title, backgroundLocation);
|
|
super(parent, title, backgroundLocation);
|
|
entriesMap.forEach((categoryName, list) -> {
|
|
entriesMap.forEach((categoryName, list) -> {
|
|
List<AbstractConfigEntry<?>> entries = Lists.newArrayList();
|
|
List<AbstractConfigEntry<?>> entries = Lists.newArrayList();
|
|
@@ -72,6 +97,7 @@ public class GlobalizedClothConfigScreen extends AbstractConfigScreen implements
|
|
}
|
|
}
|
|
categorizedEntries.put(categoryName, entries);
|
|
categorizedEntries.put(categoryName, entries);
|
|
});
|
|
});
|
|
|
|
+ this.sideSlider.scrollTo(0, false);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -93,25 +119,17 @@ public class GlobalizedClothConfigScreen extends AbstractConfigScreen implements
|
|
buildReferences();
|
|
buildReferences();
|
|
this.children.add(listWidget = new ClothConfigScreen.ListWidget<>(this, client, width - 14, height, 30, height - 32, getBackgroundLocation()));
|
|
this.children.add(listWidget = new ClothConfigScreen.ListWidget<>(this, client, width - 14, height, 30, height - 32, getBackgroundLocation()));
|
|
this.listWidget.setLeftPos(14);
|
|
this.listWidget.setLeftPos(14);
|
|
- this.sideSlider.scrollTo(14, false);
|
|
|
|
this.categorizedEntries.forEach((category, entries) -> {
|
|
this.categorizedEntries.forEach((category, entries) -> {
|
|
if (!listWidget.children().isEmpty())
|
|
if (!listWidget.children().isEmpty())
|
|
this.listWidget.children().add((AbstractConfigEntry) new EmptyEntry(5));
|
|
this.listWidget.children().add((AbstractConfigEntry) new EmptyEntry(5));
|
|
this.listWidget.children().add((AbstractConfigEntry) new EmptyEntry(4));
|
|
this.listWidget.children().add((AbstractConfigEntry) new EmptyEntry(4));
|
|
- this.listWidget.children().add((AbstractConfigEntry) new TextEntry(category.shallowCopy().formatted(Formatting.BOLD)));
|
|
|
|
- this.listWidget.children().add((AbstractConfigEntry) new EmptyEntry(2));
|
|
|
|
|
|
+ this.listWidget.children().add((AbstractConfigEntry) new CategoryTextEntry(category, category.shallowCopy().formatted(Formatting.BOLD)));
|
|
|
|
+ this.listWidget.children().add((AbstractConfigEntry) new EmptyEntry(4));
|
|
this.listWidget.children().addAll((List) entries);
|
|
this.listWidget.children().addAll((List) entries);
|
|
});
|
|
});
|
|
int buttonWidths = Math.min(200, (width - 50 - 12) / 3);
|
|
int buttonWidths = Math.min(200, (width - 50 - 12) / 3);
|
|
- addButton(new ButtonWidget(width / 2 - buttonWidths - 3, height - 26, buttonWidths, 20, isEdited() ? new TranslatableText("text.cloth-config.cancel_discard") : new TranslatableText("gui.cancel"), widget -> {
|
|
|
|
- quit();
|
|
|
|
- }));
|
|
|
|
- addButton(new AbstractPressableButtonWidget(width / 2 + 3, height - 26, buttonWidths, 20, NarratorManager.EMPTY) {
|
|
|
|
- @Override
|
|
|
|
- public void onPress() {
|
|
|
|
- saveAll(true);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ addButton(cancelButton = new ButtonWidget(0, height - 26, buttonWidths, 20, isEdited() ? new TranslatableText("text.cloth-config.cancel_discard") : new TranslatableText("gui.cancel"), widget -> quit()));
|
|
|
|
+ addButton(exitButton = new ButtonWidget(0, height - 26, buttonWidths, 20, NarratorManager.EMPTY, button -> saveAll(true)) {
|
|
@Override
|
|
@Override
|
|
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
|
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
|
boolean hasErrors = false;
|
|
boolean hasErrors = false;
|
|
@@ -129,12 +147,13 @@ public class GlobalizedClothConfigScreen extends AbstractConfigScreen implements
|
|
super.render(matrices, mouseX, mouseY, delta);
|
|
super.render(matrices, mouseX, mouseY, delta);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
+ Optional.ofNullable(this.afterInitConsumer).ifPresent(consumer -> consumer.accept(this));
|
|
}
|
|
}
|
|
|
|
|
|
private void buildReferences() {
|
|
private void buildReferences() {
|
|
categorizedEntries.forEach((categoryText, entries) -> {
|
|
categorizedEntries.forEach((categoryText, entries) -> {
|
|
this.references.add(new CategoryReference(categoryText));
|
|
this.references.add(new CategoryReference(categoryText));
|
|
- for (AbstractConfigEntry<?> entry : entries) buildReferenceFor(entry, 0);
|
|
|
|
|
|
+ for (AbstractConfigEntry<?> entry : entries) buildReferenceFor(entry, 1);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -148,52 +167,155 @@ public class GlobalizedClothConfigScreen extends AbstractConfigScreen implements
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @SuppressWarnings("deprecation")
|
|
@Override
|
|
@Override
|
|
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
|
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
|
|
|
+ this.lastHoveredReference = null;
|
|
if (requestingReferenceRebuilding) {
|
|
if (requestingReferenceRebuilding) {
|
|
this.references.clear();
|
|
this.references.clear();
|
|
buildReferences();
|
|
buildReferences();
|
|
requestingReferenceRebuilding = false;
|
|
requestingReferenceRebuilding = false;
|
|
}
|
|
}
|
|
|
|
+ int sliderPosition = getSideSliderPosition();
|
|
|
|
+ ScissorsHandler.INSTANCE.scissor(new Rectangle(sliderPosition, 0, width - sliderPosition, height));
|
|
if (isTransparentBackground()) {
|
|
if (isTransparentBackground()) {
|
|
- fillGradient(matrices, 0, 0, this.width, this.height, -1072689136, -804253680);
|
|
|
|
|
|
+ fillGradient(matrices, 14, 0, width, height, -1072689136, -804253680);
|
|
} else {
|
|
} else {
|
|
renderBackgroundTexture(0);
|
|
renderBackgroundTexture(0);
|
|
|
|
+ overlayBackground(matrices, new Rectangle(14, 0, width, height), 64, 64, 64, 255, 255);
|
|
}
|
|
}
|
|
|
|
+ listWidget.width = width - sliderPosition;
|
|
|
|
+ listWidget.setLeftPos(sliderPosition);
|
|
listWidget.render(matrices, mouseX, mouseY, delta);
|
|
listWidget.render(matrices, mouseX, mouseY, delta);
|
|
ScissorsHandler.INSTANCE.scissor(new Rectangle(listWidget.left, listWidget.top, listWidget.width, listWidget.bottom - listWidget.top));
|
|
ScissorsHandler.INSTANCE.scissor(new Rectangle(listWidget.left, listWidget.top, listWidget.width, listWidget.bottom - listWidget.top));
|
|
for (AbstractConfigEntry<?> child : listWidget.children())
|
|
for (AbstractConfigEntry<?> child : listWidget.children())
|
|
child.lateRender(matrices, mouseX, mouseY, delta);
|
|
child.lateRender(matrices, mouseX, mouseY, delta);
|
|
ScissorsHandler.INSTANCE.removeLastScissor();
|
|
ScissorsHandler.INSTANCE.removeLastScissor();
|
|
- drawCenteredText(matrices, client.textRenderer, title, width / 2, 12, -1);
|
|
|
|
|
|
+ textRenderer.drawWithShadow(matrices, title, sliderPosition + (width - sliderPosition) / 2f - textRenderer.getWidth(title) / 2f, 12, -1);
|
|
|
|
+ ScissorsHandler.INSTANCE.removeLastScissor();
|
|
|
|
+ cancelButton.x = sliderPosition + (width - sliderPosition) / 2 - cancelButton.getWidth() - 3;
|
|
|
|
+ exitButton.x = sliderPosition + (width - sliderPosition) / 2 + 3;
|
|
super.render(matrices, mouseX, mouseY, delta);
|
|
super.render(matrices, mouseX, mouseY, delta);
|
|
|
|
+ sideSlider.updatePosition(delta);
|
|
|
|
+ sideScroller.updatePosition(delta);
|
|
if (isTransparentBackground()) {
|
|
if (isTransparentBackground()) {
|
|
-// fillGradient(matrices, 0, 0, (int) sideSlider.scrollAmount, height, -1072689136, -804253680);
|
|
|
|
|
|
+ fillGradient(matrices, 0, 0, sliderPosition, height, -1240461296, -972025840);
|
|
|
|
+ fillGradient(matrices, 0, 0, sliderPosition - 14, height, 1744830464, 1744830464);
|
|
} else {
|
|
} else {
|
|
-// overlayBackground(matrices, new Rectangle(0, 0, (int) sideSlider.scrollAmount, height), 64, 64, 64, 255, 255);
|
|
|
|
|
|
+ Tessellator tessellator = Tessellator.getInstance();
|
|
|
|
+ BufferBuilder buffer = tessellator.getBuffer();
|
|
|
|
+ client.getTextureManager().bindTexture(getBackgroundLocation());
|
|
|
|
+ RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
|
|
|
+ float f = 32.0F;
|
|
|
|
+ buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
|
|
|
|
+ buffer.vertex(sliderPosition - 14, height, 0.0D).texture(0, height / 32.0F).color(68, 68, 68, 255).next();
|
|
|
|
+ buffer.vertex(sliderPosition, height, 0.0D).texture(14 / 32.0F, height / 32.0F).color(68, 68, 68, 255).next();
|
|
|
|
+ buffer.vertex(sliderPosition, 0, 0.0D).texture(14 / 32.0F, 0).color(68, 68, 68, 255).next();
|
|
|
|
+ buffer.vertex(sliderPosition - 14, 0, 0.0D).texture(0, 0).color(68, 68, 68, 255).next();
|
|
|
|
+ tessellator.draw();
|
|
|
|
+
|
|
|
|
+ buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
|
|
|
|
+ buffer.vertex(0, height, 0.0D).texture(0, (height + (int) sideScroller.scrollAmount) / 32.0F).color(32, 32, 32, 255).next();
|
|
|
|
+ buffer.vertex(sliderPosition - 14, height, 0.0D).texture((sliderPosition - 14) / 32.0F, (height + (int) sideScroller.scrollAmount) / 32.0F).color(32, 32, 32, 255).next();
|
|
|
|
+ buffer.vertex(sliderPosition - 14, 0, 0.0D).texture((sliderPosition - 14) / 32.0F, ((int) sideScroller.scrollAmount) / 32.0F).color(32, 32, 32, 255).next();
|
|
|
|
+ buffer.vertex(0, 0, 0.0D).texture(0, ((int) sideScroller.scrollAmount) / 32.0F).color(32, 32, 32, 255).next();
|
|
|
|
+ tessellator.draw();
|
|
}
|
|
}
|
|
- sideSlider.updatePosition(delta);
|
|
|
|
{
|
|
{
|
|
Matrix4f matrix = matrices.peek().getModel();
|
|
Matrix4f matrix = matrices.peek().getModel();
|
|
|
|
+ RenderSystem.disableTexture();
|
|
RenderSystem.enableBlend();
|
|
RenderSystem.enableBlend();
|
|
- RenderSystem.blendFuncSeparate(770, 771, 0, 1);
|
|
|
|
RenderSystem.disableAlphaTest();
|
|
RenderSystem.disableAlphaTest();
|
|
|
|
+ RenderSystem.defaultBlendFunc();
|
|
RenderSystem.shadeModel(7425);
|
|
RenderSystem.shadeModel(7425);
|
|
- RenderSystem.disableTexture();
|
|
|
|
Tessellator tessellator = Tessellator.getInstance();
|
|
Tessellator tessellator = Tessellator.getInstance();
|
|
BufferBuilder buffer = tessellator.getBuffer();
|
|
BufferBuilder buffer = tessellator.getBuffer();
|
|
- buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
|
|
|
|
- int shadeColor = isTransparentBackground() ? 120 : 255;
|
|
|
|
- buffer.vertex(matrix, (int) sideSlider.scrollAmount + 4, height, 100.0F).texture(0, 1f).color(0, 0, 0, shadeColor).next();
|
|
|
|
- buffer.vertex(matrix, (int) sideSlider.scrollAmount, height, 100.0F).texture(1f, 1f).color(0, 0, 0, shadeColor).next();
|
|
|
|
- buffer.vertex(matrix, (int) sideSlider.scrollAmount, 0, 100.0F).texture(1f, 0).color(0, 0, 0, shadeColor).next();
|
|
|
|
- buffer.vertex(matrix, (int) sideSlider.scrollAmount + 4, 0, 100.0F).texture(0, 0).color(0, 0, 0, shadeColor).next();
|
|
|
|
|
|
+ int shadeColor = isTransparentBackground() ? 120 : 160;
|
|
|
|
+ buffer.begin(7, VertexFormats.POSITION_COLOR);
|
|
|
|
+ buffer.vertex(matrix, sliderPosition + 4, 0, 100.0F).color(0, 0, 0, 0).next();
|
|
|
|
+ buffer.vertex(matrix, sliderPosition, 0, 100.0F).color(0, 0, 0, shadeColor).next();
|
|
|
|
+ buffer.vertex(matrix, sliderPosition, height, 100.0F).color(0, 0, 0, shadeColor).next();
|
|
|
|
+ buffer.vertex(matrix, sliderPosition + 4, height, 100.0F).color(0, 0, 0, 0).next();
|
|
|
|
+ tessellator.draw();
|
|
|
|
+ shadeColor /= 2;
|
|
|
|
+ buffer.begin(7, VertexFormats.POSITION_COLOR);
|
|
|
|
+ buffer.vertex(matrix, sliderPosition - 14, 0, 100.0F).color(0, 0, 0, shadeColor).next();
|
|
|
|
+ buffer.vertex(matrix, sliderPosition - 14 - 4, 0, 100.0F).color(0, 0, 0, 0).next();
|
|
|
|
+ buffer.vertex(matrix, sliderPosition - 14 - 4, height, 100.0F).color(0, 0, 0, 0).next();
|
|
|
|
+ buffer.vertex(matrix, sliderPosition - 14, height, 100.0F).color(0, 0, 0, shadeColor).next();
|
|
tessellator.draw();
|
|
tessellator.draw();
|
|
- RenderSystem.enableTexture();
|
|
|
|
RenderSystem.shadeModel(7424);
|
|
RenderSystem.shadeModel(7424);
|
|
- RenderSystem.enableAlphaTest();
|
|
|
|
RenderSystem.disableBlend();
|
|
RenderSystem.disableBlend();
|
|
|
|
+ RenderSystem.enableAlphaTest();
|
|
|
|
+ RenderSystem.enableTexture();
|
|
}
|
|
}
|
|
|
|
+ Rectangle slideArrowBounds = new Rectangle(sliderPosition - 14, 0, 14, height);
|
|
|
|
+ {
|
|
|
|
+ RenderSystem.enableAlphaTest();
|
|
|
|
+ VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());
|
|
|
|
+ textRenderer.drawLayer(">", sliderPosition - 7 - textRenderer.getStringWidth(">") / 2f, height / 2, (slideArrowBounds.contains(mouseX, mouseY) ? 16777120 : 16777215) | MathHelper.clamp(MathHelper.ceil((1 - sideSlider.scrollAmount) * 255.0F), 0, 255) << 24, false, matrices.peek().getModel(), immediate, false, 0, 15728880);
|
|
|
|
+ textRenderer.drawLayer("<", sliderPosition - 7 - textRenderer.getStringWidth("<") / 2f, height / 2, (slideArrowBounds.contains(mouseX, mouseY) ? 16777120 : 16777215) | MathHelper.clamp(MathHelper.ceil(sideSlider.scrollAmount * 255.0F), 0, 255) << 24, false, matrices.peek().getModel(), immediate, false, 0, 15728880);
|
|
|
|
+ immediate.draw();
|
|
|
|
+
|
|
|
|
+ Rectangle scrollerBounds = sideScroller.getBounds();
|
|
|
|
+ if (!scrollerBounds.isEmpty()) {
|
|
|
|
+ ScissorsHandler.INSTANCE.scissor(new Rectangle(0, 0, sliderPosition - 14, height));
|
|
|
|
+ int scrollOffset = (int) (scrollerBounds.y - sideScroller.scrollAmount);
|
|
|
|
+ for (Reference reference : references) {
|
|
|
|
+ matrices.push();
|
|
|
|
+ matrices.scale(reference.getScale(), reference.getScale(), reference.getScale());
|
|
|
|
+ MutableText text = new LiteralText(StringUtils.repeat(" ", reference.getIndent()) + "- ").append(reference.getText());
|
|
|
|
+ if (lastHoveredReference == null && new Rectangle(scrollerBounds.x, (int) (scrollOffset - 4 * reference.getScale()), (int) (textRenderer.getWidth(text) * reference.getScale()), (int) ((textRenderer.fontHeight + 4) * reference.getScale())).contains(mouseX, mouseY))
|
|
|
|
+ lastHoveredReference = reference;
|
|
|
|
+ textRenderer.draw(matrices, text, scrollerBounds.x, scrollOffset, lastHoveredReference == reference ? 16769544 : 16777215);
|
|
|
|
+ matrices.pop();
|
|
|
|
+ scrollOffset += (textRenderer.fontHeight + 3) * reference.getScale();
|
|
|
|
+ }
|
|
|
|
+ ScissorsHandler.INSTANCE.removeLastScissor();
|
|
|
|
+ sideScroller.renderScrollBar();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
|
|
|
+ Rectangle slideBounds = new Rectangle(0, 0, getSideSliderPosition() - 14, height);
|
|
|
|
+ if (button == 0 && slideBounds.contains(mouseX, mouseY) && lastHoveredReference != null) {
|
|
|
|
+ client.getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
|
|
|
+ lastHoveredReference.go();
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ Rectangle slideArrowBounds = new Rectangle(getSideSliderPosition() - 14, 0, 14, height);
|
|
|
|
+ if (button == 0 && slideArrowBounds.contains(mouseX, mouseY)) {
|
|
|
|
+ setExpanded(!isExpanded());
|
|
|
|
+ client.getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ return super.mouseClicked(mouseX, mouseY, button);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public boolean isExpanded() {
|
|
|
|
+ return sideSlider.scrollTarget == 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void setExpanded(boolean expanded) {
|
|
|
|
+ this.sideSlider.scrollTo(expanded ? 1 : 0, true, 2000);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
|
|
|
|
+ Rectangle slideBounds = new Rectangle(0, 0, getSideSliderPosition() - 14, height);
|
|
|
|
+ if (slideBounds.contains(mouseX, mouseY)) {
|
|
|
|
+ sideScroller.offset(ClothConfigInitializer.getScrollStep() * -amount, true);
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ return super.mouseScrolled(mouseX, mouseY, amount);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private int getSideSliderPosition() {
|
|
|
|
+ return (int) (sideSlider.scrollAmount * sideExpandLimit.get() + 14);
|
|
}
|
|
}
|
|
|
|
|
|
private static class EmptyEntry extends AbstractConfigListEntry<Object> {
|
|
private static class EmptyEntry extends AbstractConfigListEntry<Object> {
|
|
@@ -231,11 +353,13 @@ public class GlobalizedClothConfigScreen extends AbstractConfigScreen implements
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private static class TextEntry extends AbstractConfigListEntry<Object> {
|
|
|
|
|
|
+ private static class CategoryTextEntry extends AbstractConfigListEntry<Object> {
|
|
|
|
+ private final Text category;
|
|
private final Text text;
|
|
private final Text text;
|
|
|
|
|
|
- public TextEntry(Text text) {
|
|
|
|
|
|
+ public CategoryTextEntry(Text category, Text text) {
|
|
super(new LiteralText(UUID.randomUUID().toString()), false);
|
|
super(new LiteralText(UUID.randomUUID().toString()), false);
|
|
|
|
+ this.category = category;
|
|
this.text = text;
|
|
this.text = text;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -284,13 +408,15 @@ public class GlobalizedClothConfigScreen extends AbstractConfigScreen implements
|
|
Text getText();
|
|
Text getText();
|
|
|
|
|
|
float getScale();
|
|
float getScale();
|
|
|
|
+
|
|
|
|
+ void go();
|
|
}
|
|
}
|
|
|
|
|
|
- private static class CategoryReference implements Reference {
|
|
|
|
|
|
+ private class CategoryReference implements Reference {
|
|
private Text category;
|
|
private Text category;
|
|
|
|
|
|
public CategoryReference(Text category) {
|
|
public CategoryReference(Text category) {
|
|
- this.category = category.shallowCopy().formatted(Formatting.BOLD);
|
|
|
|
|
|
+ this.category = category;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -302,9 +428,21 @@ public class GlobalizedClothConfigScreen extends AbstractConfigScreen implements
|
|
public float getScale() {
|
|
public float getScale() {
|
|
return 1.0F;
|
|
return 1.0F;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void go() {
|
|
|
|
+ int i = 0;
|
|
|
|
+ for (AbstractConfigEntry<?> child : listWidget.children()) {
|
|
|
|
+ if (child instanceof CategoryTextEntry && ((CategoryTextEntry) child).category == category) {
|
|
|
|
+ listWidget.scrollTo(i, true);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ i += child.getItemHeight();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- private static class ConfigEntryReference implements Reference {
|
|
|
|
|
|
+ private class ConfigEntryReference implements Reference {
|
|
private AbstractConfigEntry<?> entry;
|
|
private AbstractConfigEntry<?> entry;
|
|
private int layer;
|
|
private int layer;
|
|
|
|
|
|
@@ -325,7 +463,40 @@ public class GlobalizedClothConfigScreen extends AbstractConfigScreen implements
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public float getScale() {
|
|
public float getScale() {
|
|
- return 0.5F;
|
|
|
|
|
|
+ return 1.0F;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void go() {
|
|
|
|
+ int[] i = {0};
|
|
|
|
+ for (AbstractConfigEntry<?> child : listWidget.children()) {
|
|
|
|
+ int i1 = i[0];
|
|
|
|
+ if (goChild(i, null, child)) return;
|
|
|
|
+ i[0] = i1 + child.getItemHeight();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private boolean goChild(int[] i, Integer expandedParent, AbstractConfigEntry<?> root) {
|
|
|
|
+ if (root == entry) {
|
|
|
|
+ listWidget.scrollTo(expandedParent == null ? i[0] : expandedParent, true);
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ int j = i[0];
|
|
|
|
+ i[0] += root.getInitialReferenceOffset();
|
|
|
|
+ boolean expanded = root instanceof Expandable && ((Expandable) root).isExpanded();
|
|
|
|
+ if (root instanceof Expandable) ((Expandable) root).setExpanded(true);
|
|
|
|
+ List<? extends Element> children = root.children();
|
|
|
|
+ if (root instanceof Expandable) ((Expandable) root).setExpanded(expanded);
|
|
|
|
+ for (Element child : children) {
|
|
|
|
+ if (child instanceof ReferenceProvider<?>) {
|
|
|
|
+ int i1 = i[0];
|
|
|
|
+ if (goChild(i, expandedParent != null ? expandedParent : root instanceof Expandable && !expanded ? j : null, ((ReferenceProvider<?>) child).provideReferenceEntry())) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ i[0] = i1 + ((ReferenceProvider<?>) child).provideReferenceEntry().getItemHeight();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|