How to use List<MyObject> in YACL screen? #21
Answered
by
Lortseam
Jack-Works
asked this question in
Help
|
Can you give an example of how to do this? I want to have a config screen in YACL for a list of my custom serializable objects. My config look like this: public class Config extends me.lortseam.completeconfig.data.Config {
public Config() {
super("modid");
}
@ConfigEntry
private boolean enabled = true;
@ConfigEntry
@ConfigEntry.BoundedInteger(min = 10, max = 10000)
@ConfigEntry.Slider
private int delay = 300;
@ConfigEntry
private List<Item> items = List.of();
@ConfigSerializable
public static class Item implements ConfigGroup {
public Item() {
}
public Item(boolean enabled, String match, String reply, int delay) {
this.enabled = enabled;
this.match = match;
this.reply = reply;
this.delay = delay;
}
@ConfigEntry
public boolean enabled = true;
@ConfigEntry
public String match = "";
}
}I tried to write a lot but I cannot make it work. Here is my GUI part, I found it very inconvenient (I need to draw UI manually) and buggy (when I click the item, it does not save). import java.util.List;
import com.google.common.reflect.TypeToken;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import dev.isxander.yacl3.api.Controller;
import dev.isxander.yacl3.api.Option;
import dev.isxander.yacl3.api.OptionDescription;
import dev.isxander.yacl3.api.utils.Dimension;
import dev.isxander.yacl3.gui.AbstractWidget;
import dev.isxander.yacl3.gui.YACLScreen;
import dev.isxander.yacl3.gui.controllers.BooleanController;
import dev.isxander.yacl3.gui.controllers.BooleanController.BooleanControllerElement;
import dev.isxander.yacl3.gui.controllers.slider.IntegerSliderController;
import dev.isxander.yacl3.gui.controllers.slider.SliderControllerElement;
import dev.isxander.yacl3.gui.controllers.string.StringController;
import dev.isxander.yacl3.gui.controllers.string.StringControllerElement;
import dev.jackworks.modid.Config;
import dev.jackworks.modid.Main;
import dev.jackworks.modid.Config.Item;
import me.lortseam.completeconfig.data.Entry;
import me.lortseam.completeconfig.gui.GuiProvider;
import me.lortseam.completeconfig.gui.yacl.ControllerFunction;
import me.lortseam.completeconfig.gui.yacl.YaclScreenBuilder;
import me.lortseam.completeconfig.gui.yacl.controller.ListController;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.ParentElement;
import net.minecraft.text.Text;
@Environment(EnvType.CLIENT)
public class YaclScreen {
private YaclScreenBuilder configScreenBuilder = new YaclScreenBuilder();
public ConfigScreenFactory<?> getModConfigScreenFactory() {
GuiProvider<ControllerFunction<?>> provider = GuiProvider.create((Entry<List<Item>> entry) -> {
return (Option<List<Config.Item>> listOption) -> () -> new ItemListController(listOption);
},
new TypeToken<List<Config.Item>>() {
}.getType());
configScreenBuilder.registerProvider(provider);
return parent -> configScreenBuilder.build(parent, Main.config);
}
public static class ItemListController extends ListController<Config.Item> {
public ItemListController(Option<List<Config.Item>> listOption) {
super(option -> () -> new ItemController(option), new Config.Item());
}
}
public static class MyWidget extends AbstractWidget implements ParentElement {
private final BooleanControllerElement enabled;
private final StringControllerElement match;
private Element focused;
private boolean isDragging = false;
public MyWidget(ItemController controller, YACLScreen screen, Dimension<Integer> dim,
BooleanControllerElement enabled, StringControllerElement match) {
super(dim.withHeight(
enabled.getDimension().height() + match.getDimension().height()));
this.enabled = enabled;
this.match = match;
}
@Override
public void render(DrawContext graphics, int mouseX, int mouseY, float delta) {
Integer heightA = enabled.getDimension().height();
Integer heightB = match.getDimension().height();
enabled.setDimension(getDimension().withHeight(heightA));
match.setDimension(getDimension().moved(0, heightA).withHeight(heightB));
enabled.render(graphics, mouseX, mouseY, delta);
match.render(graphics, mouseX, mouseY, delta);
}
@Override
public List<? extends Element> children() {
return List.of(enabled, match);
}
@Override
public boolean isDragging() {
return isDragging;
}
@Override
public void setDragging(boolean var1) {
isDragging = var1;
}
@Override
public Element getFocused() {
return focused;
}
@Override
public void setFocused(Element var1) {
focused = var1;
}
}
public static class ItemController implements Controller<Config.Item> {
private final Option<Config.Item> object;
public Option<Boolean> enabledOption;
public Option<String> matchOption;
public ItemController(Option<Config.Item> object) {
this.object = object;
enabledOption = Option.<Boolean>createBuilder()
.name(Text.of("Enabled"))
.description(OptionDescription.EMPTY)
.binding(true, () -> {
return object.binding().getValue().enabled;
},
(Boolean newVal) -> {
var old = object.pendingValue();
object.requestSet(new Config.Item(newVal, old.match));
})
.controller((var option) -> () -> {
return new BooleanController(option,
BooleanController.ON_OFF_FORMATTER, false);})
.build();
matchOption = Option.<String>createBuilder()
.name(Text.of("Match"))
.description(OptionDescription.EMPTY)
.binding("", () -> object.binding().getValue().match,
(String newVal) -> {
var old = object.pendingValue();
object.requestSet(new Config.Item(old.enabled, newVal));
})
.controller((var option) -> () -> new StringController(option))
.build();
}
@Override
public Option<Config.Item> option() {
return object;
}
@Override
public Text formatValue() {
return Text.of("formatValue");
}
@Override
public AbstractWidget provideWidget(YACLScreen screen, Dimension<Integer> widgetDimension) {
return new MyWidget(this, screen, widgetDimension,
new BooleanControllerElement((BooleanController) enabledOption.controller(), screen,
widgetDimension),
new StringControllerElement((StringController) matchOption.controller(), screen, widgetDimension,
false));
}
}
} |
Answered by
Lortseam
Aug 30, 2023
Replies: 1 comment 2 replies
|
I'm afraid there is no easier way to do this. Regarding the saving issue, I would recommend to ask for help in the YACL respository, as that does not depend on CompleteConfig. |
2 replies
Answer selected by
Jack-Works
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm afraid there is no easier way to do this. Regarding the saving issue, I would recommend to ask for help in the YACL respository, as that does not depend on CompleteConfig.