262 lines
9.8 KiB
Java
262 lines
9.8 KiB
Java
package net.minecraft.client.gui.screens.worldselection;
|
|
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Maps;
|
|
import com.google.common.collect.Sets;
|
|
import java.util.Comparator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
import java.util.function.Consumer;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.ChatFormatting;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.gui.GuiGraphics;
|
|
import net.minecraft.client.gui.components.AbstractWidget;
|
|
import net.minecraft.client.gui.components.Button;
|
|
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
|
import net.minecraft.client.gui.components.CycleButton;
|
|
import net.minecraft.client.gui.components.EditBox;
|
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
|
import net.minecraft.client.gui.layouts.HeaderAndFooterLayout;
|
|
import net.minecraft.client.gui.layouts.LinearLayout;
|
|
import net.minecraft.client.gui.narration.NarratableEntry;
|
|
import net.minecraft.client.gui.screens.Screen;
|
|
import net.minecraft.client.gui.screens.worldselection.EditGameRulesScreen.CategoryRuleEntry.1;
|
|
import net.minecraft.network.chat.CommonComponents;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.util.FormattedCharSequence;
|
|
import net.minecraft.world.level.GameRules;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class EditGameRulesScreen extends Screen {
|
|
private static final Component TITLE = Component.translatable("editGamerule.title");
|
|
private static final int SPACING = 8;
|
|
final HeaderAndFooterLayout layout = new HeaderAndFooterLayout(this);
|
|
private final Consumer<Optional<GameRules>> exitCallback;
|
|
private final Set<EditGameRulesScreen.RuleEntry> invalidEntries = Sets.<EditGameRulesScreen.RuleEntry>newHashSet();
|
|
private final GameRules gameRules;
|
|
@Nullable
|
|
private EditGameRulesScreen.RuleList ruleList;
|
|
@Nullable
|
|
private Button doneButton;
|
|
|
|
public EditGameRulesScreen(GameRules gameRules, Consumer<Optional<GameRules>> exitCallback) {
|
|
super(TITLE);
|
|
this.gameRules = gameRules;
|
|
this.exitCallback = exitCallback;
|
|
}
|
|
|
|
@Override
|
|
protected void init() {
|
|
this.layout.addTitleHeader(TITLE, this.font);
|
|
this.ruleList = this.layout.addToContents(new EditGameRulesScreen.RuleList(this.gameRules));
|
|
LinearLayout linearLayout = this.layout.addToFooter(LinearLayout.horizontal().spacing(8));
|
|
this.doneButton = linearLayout.addChild(Button.builder(CommonComponents.GUI_DONE, button -> this.exitCallback.accept(Optional.of(this.gameRules))).build());
|
|
linearLayout.addChild(Button.builder(CommonComponents.GUI_CANCEL, button -> this.onClose()).build());
|
|
this.layout.visitWidgets(guiEventListener -> {
|
|
AbstractWidget var10000 = this.addRenderableWidget(guiEventListener);
|
|
});
|
|
this.repositionElements();
|
|
}
|
|
|
|
@Override
|
|
protected void repositionElements() {
|
|
this.layout.arrangeElements();
|
|
if (this.ruleList != null) {
|
|
this.ruleList.updateSize(this.width, this.layout);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onClose() {
|
|
this.exitCallback.accept(Optional.empty());
|
|
}
|
|
|
|
private void updateDoneButton() {
|
|
if (this.doneButton != null) {
|
|
this.doneButton.active = this.invalidEntries.isEmpty();
|
|
}
|
|
}
|
|
|
|
void markInvalid(EditGameRulesScreen.RuleEntry ruleEntry) {
|
|
this.invalidEntries.add(ruleEntry);
|
|
this.updateDoneButton();
|
|
}
|
|
|
|
void clearInvalid(EditGameRulesScreen.RuleEntry ruleEntry) {
|
|
this.invalidEntries.remove(ruleEntry);
|
|
this.updateDoneButton();
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class BooleanRuleEntry extends EditGameRulesScreen.GameRuleEntry {
|
|
private final CycleButton<Boolean> checkbox;
|
|
|
|
public BooleanRuleEntry(final Component label, final List<FormattedCharSequence> tooltip, final String description, final GameRules.BooleanValue value) {
|
|
super(tooltip, label);
|
|
this.checkbox = CycleButton.onOffBuilder(value.get())
|
|
.displayOnlyValue()
|
|
.withCustomNarration(cycleButton -> cycleButton.createDefaultNarrationMessage().append("\n").append(description))
|
|
.create(10, 5, 44, 20, label, (cycleButton, boolean_) -> value.set(boolean_, null));
|
|
this.children.add(this.checkbox);
|
|
}
|
|
|
|
@Override
|
|
public void render(GuiGraphics guiGraphics, int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean hovering, float partialTick) {
|
|
this.renderLabel(guiGraphics, top, left);
|
|
this.checkbox.setX(left + width - 45);
|
|
this.checkbox.setY(top);
|
|
this.checkbox.render(guiGraphics, mouseX, mouseY, partialTick);
|
|
}
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class CategoryRuleEntry extends EditGameRulesScreen.RuleEntry {
|
|
final Component label;
|
|
|
|
public CategoryRuleEntry(final Component label) {
|
|
super(null);
|
|
this.label = label;
|
|
}
|
|
|
|
@Override
|
|
public void render(GuiGraphics guiGraphics, int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean hovering, float partialTick) {
|
|
guiGraphics.drawCenteredString(EditGameRulesScreen.this.minecraft.font, this.label, left + width / 2, top + 5, -1);
|
|
}
|
|
|
|
@Override
|
|
public List<? extends GuiEventListener> children() {
|
|
return ImmutableList.of();
|
|
}
|
|
|
|
@Override
|
|
public List<? extends NarratableEntry> narratables() {
|
|
return ImmutableList.of(new 1(this));
|
|
}
|
|
}
|
|
|
|
@FunctionalInterface
|
|
@Environment(EnvType.CLIENT)
|
|
interface EntryFactory<T extends GameRules.Value<T>> {
|
|
EditGameRulesScreen.RuleEntry create(Component component, List<FormattedCharSequence> list, String string, T value);
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public abstract class GameRuleEntry extends EditGameRulesScreen.RuleEntry {
|
|
private final List<FormattedCharSequence> label;
|
|
protected final List<AbstractWidget> children = Lists.<AbstractWidget>newArrayList();
|
|
|
|
public GameRuleEntry(@Nullable final List<FormattedCharSequence> tooltip, final Component label) {
|
|
super(tooltip);
|
|
this.label = EditGameRulesScreen.this.minecraft.font.split(label, 175);
|
|
}
|
|
|
|
@Override
|
|
public List<? extends GuiEventListener> children() {
|
|
return this.children;
|
|
}
|
|
|
|
@Override
|
|
public List<? extends NarratableEntry> narratables() {
|
|
return this.children;
|
|
}
|
|
|
|
protected void renderLabel(GuiGraphics guiGraphics, int x, int y) {
|
|
if (this.label.size() == 1) {
|
|
guiGraphics.drawString(EditGameRulesScreen.this.minecraft.font, (FormattedCharSequence)this.label.get(0), y, x + 5, -1);
|
|
} else if (this.label.size() >= 2) {
|
|
guiGraphics.drawString(EditGameRulesScreen.this.minecraft.font, (FormattedCharSequence)this.label.get(0), y, x, -1);
|
|
guiGraphics.drawString(EditGameRulesScreen.this.minecraft.font, (FormattedCharSequence)this.label.get(1), y, x + 10, -1);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class IntegerRuleEntry extends EditGameRulesScreen.GameRuleEntry {
|
|
private final EditBox input;
|
|
|
|
public IntegerRuleEntry(final Component label, final List<FormattedCharSequence> tooltip, final String description, final GameRules.IntegerValue value) {
|
|
super(tooltip, label);
|
|
this.input = new EditBox(EditGameRulesScreen.this.minecraft.font, 10, 5, 44, 20, label.copy().append("\n").append(description).append("\n"));
|
|
this.input.setValue(Integer.toString(value.get()));
|
|
this.input.setResponder(string -> {
|
|
if (value.tryDeserialize(string)) {
|
|
this.input.setTextColor(14737632);
|
|
EditGameRulesScreen.this.clearInvalid(this);
|
|
} else {
|
|
this.input.setTextColor(-65536);
|
|
EditGameRulesScreen.this.markInvalid(this);
|
|
}
|
|
});
|
|
this.children.add(this.input);
|
|
}
|
|
|
|
@Override
|
|
public void render(GuiGraphics guiGraphics, int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean hovering, float partialTick) {
|
|
this.renderLabel(guiGraphics, top, left);
|
|
this.input.setX(left + width - 45);
|
|
this.input.setY(top);
|
|
this.input.render(guiGraphics, mouseX, mouseY, partialTick);
|
|
}
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public abstract static class RuleEntry extends ContainerObjectSelectionList.Entry<EditGameRulesScreen.RuleEntry> {
|
|
@Nullable
|
|
final List<FormattedCharSequence> tooltip;
|
|
|
|
public RuleEntry(@Nullable List<FormattedCharSequence> tooltip) {
|
|
this.tooltip = tooltip;
|
|
}
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class RuleList extends ContainerObjectSelectionList<EditGameRulesScreen.RuleEntry> {
|
|
private static final int ITEM_HEIGHT = 24;
|
|
|
|
public RuleList(final GameRules gameRules) {
|
|
super(
|
|
Minecraft.getInstance(),
|
|
EditGameRulesScreen.this.width,
|
|
EditGameRulesScreen.this.layout.getContentHeight(),
|
|
EditGameRulesScreen.this.layout.getHeaderHeight(),
|
|
24
|
|
);
|
|
Map<GameRules.Category, Map<GameRules.Key<?>, EditGameRulesScreen.RuleEntry>> map = Maps.<GameRules.Category, Map<GameRules.Key<?>, EditGameRulesScreen.RuleEntry>>newHashMap();
|
|
gameRules.visitGameRuleTypes(
|
|
new net.minecraft.client.gui.screens.worldselection.EditGameRulesScreen.RuleList.1(this, EditGameRulesScreen.this, gameRules, map)
|
|
);
|
|
map.entrySet()
|
|
.stream()
|
|
.sorted(java.util.Map.Entry.comparingByKey())
|
|
.forEach(
|
|
entry -> {
|
|
this.addEntry(
|
|
EditGameRulesScreen.this.new CategoryRuleEntry(
|
|
Component.translatable(((GameRules.Category)entry.getKey()).getDescriptionId()).withStyle(ChatFormatting.BOLD, ChatFormatting.YELLOW)
|
|
)
|
|
);
|
|
((Map)entry.getValue())
|
|
.entrySet()
|
|
.stream()
|
|
.sorted(java.util.Map.Entry.comparingByKey(Comparator.comparing(GameRules.Key::getId)))
|
|
.forEach(entryx -> this.addEntry((EditGameRulesScreen.RuleEntry)entryx.getValue()));
|
|
}
|
|
);
|
|
}
|
|
|
|
@Override
|
|
public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
|
|
super.renderWidget(guiGraphics, mouseX, mouseY, partialTick);
|
|
EditGameRulesScreen.RuleEntry ruleEntry = this.getHovered();
|
|
if (ruleEntry != null && ruleEntry.tooltip != null) {
|
|
EditGameRulesScreen.this.setTooltipForNextRenderPass(ruleEntry.tooltip);
|
|
}
|
|
}
|
|
}
|
|
}
|