This repository has been archived by the owner on Jun 3, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add
YACLOptionListWidgetMixin
and YACLStringControllerMixin
- Loading branch information
1 parent
e38a969
commit b059917
Showing
12 changed files
with
272 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
...hub/steveplays28/blendium/client/compat/yacl/extension/YACLOptionListWidgetExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package io.github.steveplays28.blendium.client.compat.yacl.extension; | ||
|
||
import io.github.steveplays28.blendium.client.compat.yacl.option.MapOption; | ||
|
||
public interface YACLOptionListWidgetExtension { | ||
void blendium$setMapOption(MapOption<?, ?> mapOption); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
178 changes: 178 additions & 0 deletions
178
src/main/java/io/github/steveplays28/blendium/mixin/yacl/YACLOptionListWidgetMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
package io.github.steveplays28.blendium.mixin.yacl; | ||
|
||
import com.llamalad7.mixinextras.injector.WrapWithCondition; | ||
import com.llamalad7.mixinextras.sugar.Local; | ||
import com.llamalad7.mixinextras.sugar.ref.LocalRef; | ||
import dev.isxander.yacl3.api.ConfigCategory; | ||
import dev.isxander.yacl3.api.ListOption; | ||
import dev.isxander.yacl3.api.OptionGroup; | ||
import dev.isxander.yacl3.api.utils.Dimension; | ||
import dev.isxander.yacl3.gui.*; | ||
import dev.isxander.yacl3.impl.utils.YACLConstants; | ||
import io.github.steveplays28.blendium.client.compat.yacl.extension.YACLOptionListWidgetExtension; | ||
import io.github.steveplays28.blendium.client.compat.yacl.option.MapOption; | ||
import io.github.steveplays28.blendium.client.compat.yacl.option.MapOptionEntry; | ||
import io.github.steveplays28.blendium.mixin.yacl.accessor.OptionListWidgetGroupSeparatorEntryAccessor; | ||
import io.github.steveplays28.blendium.mixin.yacl.accessor.YACLOptionListWidgetAccessor; | ||
import net.fabricmc.api.EnvType; | ||
import net.fabricmc.api.Environment; | ||
import net.minecraft.client.MinecraftClient; | ||
import net.minecraft.client.font.MultilineText; | ||
import net.minecraft.client.gui.screen.Screen; | ||
import net.minecraft.client.gui.widget.EntryListWidget; | ||
import net.minecraft.text.Text; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.spongepowered.asm.mixin.*; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Inject; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
|
||
import java.util.function.Consumer; | ||
|
||
@Environment(EnvType.CLIENT) | ||
@Mixin(value = OptionListWidget.class, remap = false) | ||
public abstract class YACLOptionListWidgetMixin extends ElementListWidgetExt<OptionListWidget.Entry> { | ||
public YACLOptionListWidgetMixin(MinecraftClient client, int x, int y, int width, int height, boolean smoothScrolling) { | ||
super(client, x, y, width, height, smoothScrolling); | ||
} | ||
|
||
@Shadow | ||
public abstract void addEntryBelow(OptionListWidget.Entry below, OptionListWidget.Entry entry); | ||
|
||
@Shadow | ||
@Final | ||
private YACLScreen yaclScreen; | ||
|
||
@Shadow | ||
public abstract Dimension<Integer> getDefaultEntryDimension(); | ||
|
||
@Inject(method = "<init>", at = @At(value = "TAIL")) | ||
private void blendium$constructorInject(YACLScreen screen, ConfigCategory category, MinecraftClient client, int x, int y, int width, int height, Consumer<DescriptionWithName> hoverEvent, CallbackInfo ci) { | ||
for (OptionGroup group : category.groups()) { | ||
if (group instanceof MapOption<?, ?> mapOption) { | ||
mapOption.addRefreshListener(() -> refreshMapEntries(mapOption, category)); | ||
} | ||
} | ||
} | ||
|
||
@WrapWithCondition(method = "refreshOptions", at = @At(value = "INVOKE", target = "Ldev/isxander/yacl3/gui/OptionListWidget;addEntry(Lnet/minecraft/client/gui/widget/EntryListWidget$Entry;)I")) | ||
private boolean blendium$refreshOptionsAddMapSupport(OptionListWidget instance, EntryListWidget.Entry<?> entry, @Local OptionGroup group, @Local LocalRef<OptionListWidget.GroupSeparatorEntry> groupSeparatorEntry) { | ||
if (group instanceof MapOption<?, ?> mapOption) { | ||
try { | ||
var listGroupSeparatorEntryConstructor = OptionListWidget.ListGroupSeparatorEntry.class.getDeclaredConstructors()[0]; | ||
listGroupSeparatorEntryConstructor.setAccessible(true); | ||
var listGroupSeparatorEntry = (OptionListWidget.Entry) listGroupSeparatorEntryConstructor.newInstance(null, yaclScreen); | ||
((YACLOptionListWidgetExtension) listGroupSeparatorEntry).blendium$setMapOption(mapOption); | ||
|
||
addEntry(listGroupSeparatorEntry); | ||
} catch (Exception ex) { | ||
// TODO: Add exception logging | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
@Unique | ||
private void refreshMapEntries(MapOption<?, ?> mapOption, ConfigCategory category) { | ||
// Find group separator for group | ||
OptionListWidget.ListGroupSeparatorEntry groupSeparator = super.children().stream().filter( | ||
entry -> entry instanceof OptionListWidget.ListGroupSeparatorEntry listGroupSeparatorEntry && ((OptionListWidgetGroupSeparatorEntryAccessor) listGroupSeparatorEntry).getGroup() == mapOption).map( | ||
OptionListWidget.ListGroupSeparatorEntry.class::cast).findAny().orElse(null); | ||
|
||
if (groupSeparator == null) { | ||
YACLConstants.LOGGER.warn("Can't find group separator to refresh map option entries for map option " + mapOption.name()); | ||
return; | ||
} | ||
|
||
var groupSeparatorChildEntries = ((OptionListWidgetGroupSeparatorEntryAccessor) groupSeparator).getChildEntries(); | ||
for (OptionListWidget.Entry entry : groupSeparatorChildEntries) | ||
super.removeEntry(entry); | ||
groupSeparatorChildEntries.clear(); | ||
|
||
var parentInstance = (OptionListWidget) (Object) this; | ||
|
||
// If no entries, below loop won't run where addEntryBelow() reaches viewable children | ||
if (mapOption.options().isEmpty()) { | ||
OptionListWidget.EmptyListLabel emptyListLabel = parentInstance.new EmptyListLabel(groupSeparator, category); | ||
|
||
addEntryBelow(groupSeparator, emptyListLabel); | ||
groupSeparatorChildEntries.add(emptyListLabel); | ||
|
||
return; | ||
} | ||
|
||
OptionListWidget.Entry lastEntry = groupSeparator; | ||
for (MapOptionEntry<?, ?> mapOptionEntry : mapOption.options()) { | ||
OptionListWidget.OptionEntry optionEntry = parentInstance.new OptionEntry(mapOptionEntry, category, mapOption, groupSeparator, | ||
mapOptionEntry.controller().provideWidget(yaclScreen, getDefaultEntryDimension()) | ||
); | ||
|
||
addEntryBelow(lastEntry, optionEntry); | ||
groupSeparatorChildEntries.add(optionEntry); | ||
lastEntry = optionEntry; | ||
} | ||
} | ||
|
||
@Mixin(value = OptionListWidget.ListGroupSeparatorEntry.class, remap = false) | ||
public abstract static class YACLOptionListWidgetListGroupSeparatorEntryMixin extends OptionListWidget.GroupSeparatorEntry implements YACLOptionListWidgetExtension { | ||
@Mutable | ||
@Shadow | ||
@Final | ||
private TextScaledButtonWidget resetListButton; | ||
|
||
@Shadow | ||
public abstract void setExpanded(boolean expanded); | ||
|
||
@Shadow | ||
protected abstract void updateExpandMinimizeText(); | ||
|
||
@Shadow | ||
protected abstract void minimizeIfUnavailable(); | ||
|
||
@Mutable | ||
@Shadow | ||
@Final | ||
private TooltipButtonWidget addListButton; | ||
|
||
@Unique | ||
private MapOption<?, ?> blendium$mapOption; | ||
|
||
private YACLOptionListWidgetListGroupSeparatorEntryMixin(ListOption<?> group, Screen screen, @NotNull OptionListWidget outer) { | ||
outer.super(group, screen); | ||
} | ||
|
||
@SuppressWarnings("UnnecessaryUnicodeEscape") | ||
@Inject(method = "<init>", at = @At(value = "RETURN")) | ||
private void blendium$constructorInject(OptionListWidget this$0, ListOption<?> group, Screen screen, CallbackInfo ci) { | ||
this.resetListButton = new TextScaledButtonWidget(screen, this$0.getRowRight(), -20, -50, 20, 2f, Text.literal("\u21BB"), | ||
button -> blendium$mapOption.requestSetDefault() | ||
); | ||
blendium$mapOption.addListener((opt, val) -> this.resetListButton.active = !opt.isPendingValueDefault() && opt.available()); | ||
this.resetListButton.active = !blendium$mapOption.isPendingValueDefault() && blendium$mapOption.available(); | ||
|
||
this.addListButton = new TooltipButtonWidget(((YACLOptionListWidgetAccessor) this$0).getYaclScreen(), resetListButton.getX() - 20, | ||
-50, 20, 20, Text.literal("+"), Text.translatable("yacl.list.add_top"), btn -> { | ||
blendium$mapOption.insertNewEntry(); | ||
setExpanded(true); | ||
} | ||
); | ||
|
||
updateExpandMinimizeText(); | ||
minimizeIfUnavailable(); | ||
} | ||
|
||
@Inject(method = "updateExpandMinimizeText", at = @At(value = "TAIL")) | ||
private void blendium$updateExpandMinimizeTextInject(CallbackInfo ci) { | ||
expandMinimizeButton.active = blendium$mapOption == null || blendium$mapOption.available(); | ||
if (addListButton != null) | ||
addListButton.active = expandMinimizeButton.active && blendium$mapOption.numberOfEntries() < blendium$mapOption.maximumNumberOfEntries(); | ||
} | ||
|
||
@Override | ||
public void blendium$setMapOption(MapOption<?, ?> mapOption) { | ||
blendium$mapOption = mapOption; | ||
} | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
src/main/java/io/github/steveplays28/blendium/mixin/yacl/YACLStringControllerMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package io.github.steveplays28.blendium.mixin.yacl; | ||
|
||
import dev.isxander.yacl3.api.Option; | ||
import dev.isxander.yacl3.gui.controllers.string.StringController; | ||
import net.fabricmc.api.EnvType; | ||
import net.fabricmc.api.Environment; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Overwrite; | ||
import org.spongepowered.asm.mixin.Pseudo; | ||
import org.spongepowered.asm.mixin.Shadow; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Inject; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; | ||
|
||
import java.util.Map; | ||
|
||
@Pseudo | ||
@Environment(EnvType.CLIENT) | ||
@Mixin(value = StringController.class, remap = false) | ||
public abstract class YACLStringControllerMixin { | ||
@Shadow | ||
public abstract Option<String> option(); | ||
|
||
// @Inject(method = "getString", at = @At(value = "HEAD"), cancellable = true) | ||
// private void blendium$getStringInject(@NotNull CallbackInfoReturnable<String> cir) { | ||
// var optionValue = option().pendingValue(); | ||
// | ||
//// if ((Object) optionValue instanceof Map.Entry<?, ?>) { | ||
// var e = option().pendingValue(); | ||
// cir.setReturnValue(((Map.Entry<?, ?>) (Object) optionValue).getKey().toString()); | ||
//// } | ||
// } | ||
|
||
@Overwrite | ||
public String getString() { | ||
return ((Map.Entry<?, ?>) (Object) option().pendingValue()).getKey().toString(); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
...teveplays28/blendium/mixin/yacl/accessor/OptionListWidgetGroupSeparatorEntryAccessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package io.github.steveplays28.blendium.mixin.yacl.accessor; | ||
|
||
import dev.isxander.yacl3.api.OptionGroup; | ||
import dev.isxander.yacl3.gui.OptionListWidget; | ||
import net.fabricmc.api.EnvType; | ||
import net.fabricmc.api.Environment; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.gen.Accessor; | ||
|
||
import java.util.List; | ||
|
||
@Environment(EnvType.CLIENT) | ||
@Mixin(value = OptionListWidget.GroupSeparatorEntry.class, remap = false) | ||
public interface OptionListWidgetGroupSeparatorEntryAccessor { | ||
@Accessor | ||
OptionGroup getGroup(); | ||
|
||
@Accessor | ||
List<OptionListWidget.Entry> getChildEntries(); | ||
} |
15 changes: 15 additions & 0 deletions
15
...ava/io/github/steveplays28/blendium/mixin/yacl/accessor/YACLOptionListWidgetAccessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package io.github.steveplays28.blendium.mixin.yacl.accessor; | ||
|
||
import dev.isxander.yacl3.gui.OptionListWidget; | ||
import dev.isxander.yacl3.gui.YACLScreen; | ||
import net.fabricmc.api.EnvType; | ||
import net.fabricmc.api.Environment; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.gen.Accessor; | ||
|
||
@Environment(EnvType.CLIENT) | ||
@Mixin(OptionListWidget.class) | ||
public interface YACLOptionListWidgetAccessor { | ||
@Accessor | ||
YACLScreen getYaclScreen(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters