Skip to content

Commit

Permalink
im going insane (screens)
Browse files Browse the repository at this point in the history
  • Loading branch information
ix0rai committed May 14, 2024
1 parent e28411e commit 5f75de2
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 143 deletions.
14 changes: 7 additions & 7 deletions src/main/java/io/ix0rai/rainglow/config/DeferredSaveOption.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import java.util.function.Consumer;

public class DeferredSaveOption<T> extends Option<T> {
private T deferredValue;
public T deferredValue;

public DeferredSaveOption(String key, TooltipSupplier<T> tooltipSupplier, OptionTextGetter<T> textGetter, Option.ValueSet<T> values, T defaultValue, Consumer<T> updateCallback) {
this(key, tooltipSupplier, textGetter, values, values.codec(), defaultValue, updateCallback);
Expand Down Expand Up @@ -40,21 +40,21 @@ public void set(T value) {
}
}

public static Option<Boolean> createDeferredBoolean(String key, boolean defaultValue, Consumer<Boolean> updateCallback) {
public static DeferredSaveOption<Boolean> createDeferredBoolean(String key, String tooltip, boolean defaultValue, Consumer<Boolean> updateCallback) {
return new DeferredSaveOption<>(
"rainglow.config." + key,
Option.constantTooltip(Text.translatable("rainglow.config.tooltip." + key)),
Rainglow.translatableTextKey("config." + key),
Option.constantTooltip(tooltip == null ? Rainglow.translatableText("tooltip." + key) : Rainglow.translatableText(tooltip)),
(text, value) -> value ? CommonTexts.YES : CommonTexts.NO,
Option.BOOLEAN_VALUES,
BOOLEAN_VALUES,
defaultValue,
updateCallback
);
}

public static Option<Integer> createDeferredRangedInt(String key, int defaultValue, int min, int max, Consumer<Integer> updateCallback) {
public static DeferredSaveOption<Integer> createDeferredRangedInt(String key, String tooltip, int defaultValue, int min, int max, Consumer<Integer> updateCallback) {
return new DeferredSaveOption<>(
Rainglow.translatableTextKey("config." + key),
Option.constantTooltip(Rainglow.translatableText("tooltip." + key)),
Option.constantTooltip(tooltip == null ? Rainglow.translatableText("tooltip." + key) : Rainglow.translatableText(tooltip)),
(text, value) -> Rainglow.translatableText("value." + key, value),
new Option.IntRangeValueSet(min, max),
Codec.intRange(min, max),
Expand Down
266 changes: 135 additions & 131 deletions src/main/java/io/ix0rai/rainglow/config/RainglowConfigScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
import io.ix0rai.rainglow.data.RainglowMode;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.option.SimpleOptionsScreen;
import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.gui.widget.button.ButtonWidget;
import net.minecraft.client.gui.widget.button.CyclingButtonWidget;
import net.minecraft.client.gui.widget.layout.GridWidget;
import net.minecraft.client.gui.widget.layout.HeaderFooterLayoutWidget;
import net.minecraft.client.gui.widget.layout.LayoutSettings;
import net.minecraft.client.gui.widget.layout.LinearLayoutWidget;
import net.minecraft.client.gui.widget.text.TextWidget;
import net.minecraft.client.option.Option;
Expand All @@ -20,177 +24,177 @@
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// todo: now that config uses overrides, edit lock doesn't matter

public class RainglowConfigScreen extends SimpleOptionsScreen {
// private final SpruceOption modeOption;
// private final SpruceOption customOption;
// private final SpruceOption resetOption;
// private final SpruceOption saveOption;
public class RainglowConfigScreen extends Screen {
private static final Text TITLE = Rainglow.translatableText("config.title");

//private final SpruceOption colourRarityOption;
//private RainglowMode mode;
// colours to apply is saved in a variable so that it can be removed from the screen when cycling modes
// private SpruceLabelWidget coloursToApplyLabel;
private final Screen parent;
private final Map<RainglowEntity, DeferredSaveOption<Boolean>> toggles = new HashMap<>();
private final Map<RainglowEntity, DeferredSaveOption<Integer>> sliders = new HashMap<>();

private RainglowMode mode;
private boolean isConfirming;

public RainglowConfigScreen(@Nullable Screen parent) {
super(parent, MinecraftClient.getInstance().options, Rainglow.translatableText("config.title"),
new Option[]{
createEntityToggles().get(0),
createColourRaritySliders().get(0),
createEntityToggles().get(1),
createColourRaritySliders().get(1),
createEntityToggles().get(2),
createColourRaritySliders().get(2),
}
);



// // mode option cycles through available modes
// // it also updates the label to show which colours will be applied
// this.modeOption = new SpruceCyclingOption(Rainglow.translatableTextKey("config.mode"),
// amount -> {
// if (!Rainglow.CONFIG.isEditLocked(MinecraftClient.getInstance())) {
// mode = mode.cycle();
// this.remove(this.coloursToApplyLabel);
// this.coloursToApplyLabel = createColourListLabel(Rainglow.translatableTextKey("config.colours_to_apply"), this.mode, this.width / 2 - 125, this.height / 4 + 40);
// this.addDrawable(this.coloursToApplyLabel);
// } else {
// sendConfigLockedToast();
// }
// },
// option -> option.getDisplayText(mode.getText()),
// Rainglow.translatableText("tooltip.mode",
// List.of(RainglowMode.values())
// )
// );
//
// // opens a screen to toggle which colours are applied in custom mode
// this.customOption = SpruceSimpleActionOption.of(Rainglow.translatableTextKey("config.custom"),
// btn -> MinecraftClient.getInstance().setScreen(new CustomModeScreen(this))
// );
//
// // toggles whether entities are rainbow
// for (int i = 0; i < RainglowEntity.values().length; i ++) {
// RainglowEntity entity = RainglowEntity.values()[i];
//
// this.entityToggles[i] = createEntityToggle(
// entity,
// () -> Rainglow.CONFIG.isEntityEnabled(entity),
// enabled -> Rainglow.CONFIG.setEntityEnabled(entity, enabled)
// );
// }
//
// this.colourRarityOption = new SpruceIntegerInputOption(Rainglow.translatableTextKey("config.rarity"),
// Rainglow.CONFIG::getRarity,
// Rainglow.CONFIG::setRarity,
// Rainglow.translatableText("tooltip.rarity")
// );
//
// // resets the config to default values
// this.resetOption = SpruceSimpleActionOption.reset(btn -> {
// MinecraftClient client = MinecraftClient.getInstance();
// if (!Rainglow.CONFIG.isEditLocked(client)) {
// this.mode = RainglowMode.getDefault();
// this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
// } else {
// sendConfigLockedToast();
// }
// });
//
// // saves values to config file
// this.saveOption = SpruceSimpleActionOption.of(Rainglow.translatableTextKey("config.save"),
// buttonWidget -> {
// this.closeScreen();
// Rainglow.CONFIG.setMode(this.mode);
// Rainglow.CONFIG.save(true);
// }
// );
super(TITLE);
this.parent = parent;
this.mode = RainglowMode.get(Rainglow.CONFIG.mode.value());
}

private static List<Option<Boolean>> createEntityToggles() {
List<Option<Boolean>> toggles = new ArrayList<>();
@Override
public void init() {
HeaderFooterLayoutWidget headerFooterWidget = new HeaderFooterLayoutWidget(this, 61, 33);

if (!this.isConfirming) {
// header
LinearLayoutWidget linearLayoutWidget = headerFooterWidget.addToHeader(LinearLayoutWidget.createVertical().setSpacing(20));
linearLayoutWidget.add(new TextWidget(TITLE, this.textRenderer), LayoutSettings::alignHorizontallyCenter);
linearLayoutWidget.add(createModeButton());

// contents
GridWidget gridWidget = new GridWidget();
gridWidget.getDefaultSettings().setHorizontalPadding(4).setBottomPadding(4).alignHorizontallyCenter();
GridWidget.AdditionHelper miscAdditionHelper = gridWidget.createAdditionHelper(2);
for (RainglowEntity entity : RainglowEntity.values()) {
DeferredSaveOption<Boolean> entityToggle = createEntityToggle(entity);
miscAdditionHelper.add(entityToggle.createButton(MinecraftClient.getInstance().options));
entityToggle.set(entityToggle.deferredValue);

miscAdditionHelper.add(createColourRaritySlider(entity).createButton(MinecraftClient.getInstance().options));
}

headerFooterWidget.addToContents(gridWidget);

// footer
LinearLayoutWidget linearLayout = headerFooterWidget.addToFooter(LinearLayoutWidget.createHorizontal().setSpacing(8));
linearLayout.add(ButtonWidget.builder(CommonTexts.DONE, button -> this.closeScreen()).build());
linearLayout.add(ButtonWidget.builder(Rainglow.translatableText("config.save"), button -> {
this.save();
this.closeScreen(true);
}).build());
} else {
LinearLayoutWidget titleWidget = headerFooterWidget.addToHeader(LinearLayoutWidget.createVertical().setSpacing(20));
titleWidget.add(new TextWidget(this.title, this.textRenderer), LayoutSettings::alignHorizontallyCenter);

LinearLayoutWidget contentWidget = headerFooterWidget.addToContents(new LinearLayoutWidget(250, 100, LinearLayoutWidget.Orientation.VERTICAL).setSpacing(8));
contentWidget.add(new TextWidget(Rainglow.translatableText("config.unsaved_warning"), this.textRenderer), LayoutSettings::alignHorizontallyCenter);

LinearLayoutWidget buttons = new LinearLayoutWidget(250, 20, LinearLayoutWidget.Orientation.HORIZONTAL);
buttons.add(ButtonWidget.builder(Rainglow.translatableText("config.continue_editing"), (buttonWidget) -> {
this.isConfirming = false;
this.clearAndInit();
}).build());
buttons.add(ButtonWidget.builder(CommonTexts.YES, (buttonWidget) -> MinecraftClient.getInstance().setScreen(this.parent)).build());

for (RainglowEntity entity : RainglowEntity.values()) {
toggles.add(DeferredSaveOption.createDeferredBoolean(
"enable_" + entity.getId(),
Rainglow.CONFIG.isEntityEnabled(entity),
enabled -> Rainglow.CONFIG.setEntityEnabled(entity, enabled)
));
contentWidget.add(buttons, LayoutSettings::alignHorizontallyCenter);
}

return toggles;
headerFooterWidget.visitWidgets(this::addDrawableSelectableElement);
headerFooterWidget.arrangeElements();
}

private static List<Option<Integer>> createColourRaritySliders() {
List<Option<Integer>> sliders = new ArrayList<>();

for (RainglowEntity entity : RainglowEntity.values()) {
sliders.add(DeferredSaveOption.createDeferredRangedInt(
entity.getId() + "_rarity",
Rainglow.CONFIG.getRarity(entity),
0,
100,
rarity -> Rainglow.CONFIG.setRarity(entity, rarity)
));
}
private DeferredSaveOption<Boolean> createEntityToggle(RainglowEntity entity) {
return toggles.computeIfAbsent(entity, e -> DeferredSaveOption.createDeferredBoolean(
"enable_" + e.getId(),
"tooltip.entity_toggle",
Rainglow.CONFIG.isEntityEnabled(e),
enabled -> Rainglow.CONFIG.setEntityEnabled(e, enabled)
));
}

return sliders;
private DeferredSaveOption<Integer> createColourRaritySlider(RainglowEntity entity) {
return sliders.computeIfAbsent(entity, e -> DeferredSaveOption.createDeferredRangedInt(
e.getId() + "_rarity",
"tooltip.rarity",
Rainglow.CONFIG.getRarity(e),
0,
100,
rarity -> Rainglow.CONFIG.setRarity(e, rarity)
));
}

public CyclingButtonWidget<RainglowMode> createModeButton() {
return CyclingButtonWidget.builder(RainglowMode::getText)
.values(RainglowMode.values())
.initially(this.mode)
.tooltip(this::createColourListLabel)
.build(
0,
0,
300,
20,
Rainglow.translatableText("config.mode"),
(cyclingButtonWidget, mode) -> {
RainglowConfigScreen.this.mode = mode;
}
);
}

private void save() {
if (Rainglow.CONFIG.isEditLocked(MinecraftClient.getInstance())) {
sendConfigLockedToast();
} else {
for (Option<?> option : this.options) {
Collection<Option<?>> options = new ArrayList<>(this.sliders.values());
options.addAll(this.toggles.values());

for (Option<?> option : options) {
if (option instanceof DeferredSaveOption) {
((DeferredSaveOption<?>) option).save();
}
}
}
}

@Override
protected void method_31387() {
LinearLayoutWidget linearLayout = this.field_49503.addToFooter(LinearLayoutWidget.createHorizontal().setSpacing(8));
linearLayout.add(ButtonWidget.builder(CommonTexts.DONE, button -> this.closeScreen()).build());
linearLayout.add(ButtonWidget.builder(CommonTexts.YES, button -> {
this.save();
this.closeScreen();
}).build());
this.field_49503.visitWidgets(this::addDrawableSelectableElement);
this.repositionElements();
Rainglow.CONFIG.mode.setValue(this.mode.getId());
}
}

private TextWidget createColourListLabel(String translationKey, RainglowMode mode, int x, int y) {
private Tooltip createColourListLabel(RainglowMode mode) {
// creates a label and appends all the colours that will be applied in the given mode
StringBuilder text = new StringBuilder(Language.getInstance().get(translationKey));
StringBuilder text = new StringBuilder(Language.getInstance().get(Rainglow.translatableTextKey("config.colours_to_apply")));
int maxDisplayedColourCount = 16;
int maxColoursPerLine = 4;

for (int i = 0; i < mode.getColours().size(); i += 2) {
RainglowColour colour = mode.getColours().get(i);

for (int i = 0; i < mode.getColours().size(); i += maxColoursPerLine) {
if (i < maxDisplayedColourCount) {
String colour1 = Language.getInstance().get(Rainglow.translatableTextKey("colour." + colour.getId()));
String colour2 = "";
if (i + 1 <= mode.getColours().size() - 1) {
colour2 = Language.getInstance().get(Rainglow.translatableTextKey("colour." + mode.getColours().get(i + 1).getId()));
}
text.append("\n");

boolean appendComma = i + 2 < mode.getColours().size();
int coloursLeft = mode.getColours().size() - i;
int coloursToDisplay = Math.min(coloursLeft, maxColoursPerLine);

text.append("\n").append(colour1).append(colour2.isEmpty() ? "" : ", ").append(colour2).append(appendComma ? "," : "");
for (int j = 0; j < coloursToDisplay; j++) {
RainglowColour currentColour = mode.getColours().get(i + j);
text.append(Language.getInstance().get(Rainglow.translatableTextKey("colour." + currentColour.getId())));
if (j < coloursToDisplay - 1) {
text.append(", ");
}
}
} else {
text.append("\n... ").append(mode.getColours().size() - maxDisplayedColourCount).append(" ").append(Language.getInstance().get(Rainglow.translatableTextKey("config.more")));
}
}

// set colour to the mode's text colour
Style style = Style.EMPTY.withColor(mode.getText().getStyle().getColor());
return new TextWidget(Text.literal(text.toString()).setStyle(style), MinecraftClient.getInstance().textRenderer);
return Tooltip.create(Text.literal(text.toString()).setStyle(style));
}

@Override
public void closeScreen() {
this.closeScreen(false);
}

public void closeScreen(boolean saved) {
if (!saved) {
this.isConfirming = true;
this.clearAndInit();
} else {
MinecraftClient.getInstance().setScreen(this.parent);
}
}

private static void sendConfigLockedToast() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.ix0rai.rainglow.mixin.client.screen;

import com.llamalad7.mixinextras.sugar.Local;
import io.ix0rai.rainglow.config.DeferredSaveOption;
import net.minecraft.client.option.Option;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;

@Mixin(Option.CyclingValueSet.class)
public interface CyclingValueSetMixin {
@ModifyArg(
method = "method_42723",
remap = false,
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/gui/widget/button/CyclingButtonWidget$Builder;initially(Ljava/lang/Object;)Lnet/minecraft/client/gui/widget/button/CyclingButtonWidget$Builder;"
),
index = 0
)
private <T> T updateOptionValue(T value, @Local(argsOnly = true) Option<T> option) {
return option instanceof DeferredSaveOption<T> deferred ? deferred.deferredValue : value;
}
}
Loading

0 comments on commit 5f75de2

Please sign in to comment.