Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import net.blay09.mods.balm.client.color.block.BalmBlockColorRegistrar;
import net.blay09.mods.balm.client.gui.screens.inventory.BalmMenuScreenRegistrar;
import net.blay09.mods.balm.client.platform.config.BalmConfigScreenRegistrar;
import net.blay09.mods.balm.client.platform.module.BalmClientModule;
import net.blay09.mods.balm.client.renderer.block.model.BalmBlockStateModelRegistrar;
import net.blay09.mods.balm.client.renderer.blockentity.BalmBlockEntityRendererRegistrar;
import net.blay09.mods.waystones.client.config.WaystonesConfigScreenFactory;
import net.blay09.mods.waystones.Waystones;
import net.blay09.mods.waystones.client.requirement.RequirementClientRegistry;
import net.blay09.mods.waystones.compat.Compat;
Expand Down Expand Up @@ -45,6 +47,11 @@ public void registerMenuScreens(BalmMenuScreenRegistrar screens) {
ModScreens.initialize(screens);
}

@Override
public void registerConfigScreen(BalmConfigScreenRegistrar configScreens) {
configScreens.register(WaystonesConfigScreenFactory::create);
}

@Override
public void initialize() {
ModClientEventHandlers.initialize();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package net.blay09.mods.waystones.client.config;

import net.blay09.mods.balm.client.platform.config.screen.BalmConfigScreenContext;
import net.blay09.mods.balm.client.platform.config.screen.BalmConfigScreenEditBox;
import net.blay09.mods.balm.client.platform.config.screen.BalmConfigScreenRowState;
import net.blay09.mods.balm.platform.config.schema.ConfiguredProperty;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.gui.components.AbstractContainerWidget;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.network.chat.Component;

import java.util.Collection;
import java.util.List;

final class MergedIntEditBoxes extends AbstractContainerWidget {
private static final int GAP = 8;

private final BalmConfigScreenEditBox<Integer> first;
private final BalmConfigScreenEditBox<Integer> second;
private final List<BalmConfigScreenEditBox<Integer>> children;

public MergedIntEditBoxes(BalmConfigScreenContext screenContext,
BalmConfigScreenRowState rowState,
ConfiguredProperty<Integer> firstProperty,
ConfiguredProperty<Integer> secondProperty) {
super(0, 0, Button.DEFAULT_WIDTH, Button.DEFAULT_HEIGHT, Component.empty());

final var state = rowState.getOrCreate(State::new);
first = new BalmConfigScreenEditBox<>(screenContext.font(), firstProperty, screenContext, state.firstRowState);
second = new BalmConfigScreenEditBox<>(screenContext.font(), secondProperty, screenContext, state.secondRowState);

children = List.of(first, second);
layoutChildren();
}

@Override
public void setX(int x) {
super.setX(x);
layoutChildren();
}

@Override
public void setY(int y) {
super.setY(y);
layoutChildren();
}

@Override
public void setWidth(int width) {
super.setWidth(width);
layoutChildren();
}

@Override
public void setHeight(int height) {
super.setHeight(height);
layoutChildren();
}

private void layoutChildren() {
final var editBoxWidth = Math.max(1, (width - GAP) / 2);
first.setPosition(getX(), getY());
first.setSize(editBoxWidth, height);
second.setPosition(getX() + editBoxWidth + GAP, getY());
second.setSize(width - editBoxWidth - GAP, height);
}

@Override
public List<? extends GuiEventListener> children() {
return children;
}

@Override
protected void extractWidgetRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float partialTick) {
first.active = active;
second.active = active;
first.visible = visible;
second.visible = visible;
first.extractRenderState(graphics, mouseX, mouseY, partialTick);
second.extractRenderState(graphics, mouseX, mouseY, partialTick);
}

@Override
protected int contentHeight() {
return height;
}

@Override
protected void updateWidgetNarration(NarrationElementOutput output) {
}

private static final class State {
private final BalmConfigScreenRowState firstRowState = new BalmConfigScreenRowState();
private final BalmConfigScreenRowState secondRowState = new BalmConfigScreenRowState();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package net.blay09.mods.waystones.client.config;

import net.blay09.mods.balm.client.platform.config.screen.list.BalmConfigListEditorContext;
import net.blay09.mods.balm.client.platform.config.screen.list.BalmConfigListEditorEntry;
import net.blay09.mods.balm.client.platform.config.screen.list.internal.BalmConfigListEditorValue;
import net.blay09.mods.shogi.common.util.ShogiExpressionHighlighter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import org.jspecify.annotations.Nullable;

import java.util.Objects;

public class WarpRequirementListEditorEntry extends BalmConfigListEditorEntry<String> {
private static final Component EDIT_LABEL = Component.translatable("gui.balm.configuration.edit");
private static final Component DELETE_LABEL = Component.translatable("gui.balm.configuration.delete");
private static final Component RESET_LABEL = Component.translatable("gui.balm.configuration.reset");

private final Button editButton;
private final Button deleteButton;
private final Button resetButton;

public WarpRequirementListEditorEntry(BalmConfigListEditorContext<String> context, BalmConfigListEditorValue<String> valueHolder) {
super(context, valueHolder);
editButton = Button.builder(EDIT_LABEL, this::onEditButton)
.size(ACTION_BUTTON_WIDTH, ACTION_BUTTON_HEIGHT)
.build();
deleteButton = Button.builder(DELETE_LABEL, this::onDeleteButton)
.size(ACTION_BUTTON_WIDTH, ACTION_BUTTON_HEIGHT)
.build();
resetButton = Button.builder(RESET_LABEL, this::onResetButton)
.size(ACTION_BUTTON_WIDTH, ACTION_BUTTON_HEIGHT)
.build();
addActionWidget(editButton);
addActionWidget(deleteButton);
addActionWidget(resetButton);
}

@Override
public void startEditing(@Nullable Object initialValue) {
final var value = initialValue != null ? String.valueOf(initialValue) : Objects.requireNonNullElse(valueHolder.value(), "");
openRuleEditor(value);
}

@Override
protected void extractEntryContent(GuiGraphicsExtractor graphics, int mouseX, int mouseY, boolean hovered, float partialTick) {
final var value = Objects.requireNonNullElse(valueHolder.value(), "");
final var textWidth = Math.max(1, getContentRightBeforeActions() - getContentLeftAfterDragHandle());
final var label = context.font().plainSubstrByWidth(value, textWidth);
graphics.text(context.font(),
ShogiExpressionHighlighter.highlightComponent(label),
getContentLeftAfterDragHandle(),
getContentY() + 5,
0xFFFFFFFF);
}

@Override
protected void updateActionWidgets() {
editButton.active = canEdit();
deleteButton.active = canDelete();
resetButton.visible = canReset();
resetButton.active = canReset();
}

private boolean canEdit() {
return true;
}

private void onEditButton(Button button) {
if (canEdit()) {
startEditing(null);
}
}

private boolean canDelete() {
return true;
}

private void onDeleteButton(Button button) {
if (canDelete()) {
context.delete(this);
}
}

private boolean canReset() {
return valueHolder.originalValue() != null && !Objects.equals(valueHolder.value(), valueHolder.originalValue());
}

private void onResetButton(Button button) {
if (canReset()) {
valueHolder.reset();
context.revalidate();
}
}

private void openRuleEditor(String value) {
final Screen parent = context instanceof Screen screen ? screen : null;
Minecraft.getInstance().gui.setScreen(new WarpRequirementRuleEditScreen(parent,
value,
newValue -> {
valueHolder.value(newValue);
context.revalidate();
context.commit();
}));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package net.blay09.mods.waystones.client.config;

import net.blay09.mods.shogi.client.gui.RuleEditBox;
import net.blay09.mods.waystones.config.WaystonesRules;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.StringWidget;
import net.minecraft.client.gui.layouts.FrameLayout;
import net.minecraft.client.gui.layouts.HeaderAndFooterLayout;
import net.minecraft.client.gui.layouts.LinearLayout;
import net.minecraft.client.gui.screens.ConfirmLinkScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.input.KeyEvent;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import org.jspecify.annotations.Nullable;

import java.util.function.Consumer;

public class WarpRequirementRuleEditScreen extends Screen {
private static final String HELP_URL = "https://mods.twelveiterations.com/minecraft/waystones/guides/warp-rules";
private static final Component TITLE = Component.translatable("waystones.configuration.rules.warpRequirements.edit");
private static final Component PLACEHOLDER = Component.translatable("waystones.configuration.rules.warpRequirements.placeholder");
private static final Component HELP_LABEL = Component.translatable("waystones.configuration.rules.warpRequirements.help");

private final @Nullable Screen parent;
private final String initialValue;
private final Consumer<String> valueConsumer;
private final HeaderAndFooterLayout layout = new HeaderAndFooterLayout(this, 28, 33);

private @Nullable RuleEditBox ruleEditBox;

public WarpRequirementRuleEditScreen(@Nullable Screen parent, String initialValue, Consumer<String> valueConsumer) {
super(TITLE);
this.parent = parent;
this.initialValue = initialValue;
this.valueConsumer = valueConsumer;
}

@Override
protected void init() {
final var header = layout.addToHeader(LinearLayout.vertical());
header.defaultCellSetting().alignHorizontallyCenter();
header.addChild(new StringWidget(title, font));

ruleEditBox = RuleEditBox.builder()
.setScope(WaystonesRules.scope)
.setPlaceholder(PLACEHOLDER)
.build(font, Math.max(1, width - 40), Math.max(1, height - layout.getHeaderHeight() - layout.getFooterHeight() - 20), title);
ruleEditBox.setCharacterLimit(2048);
ruleEditBox.setValue(initialValue);

layout.addToContents(new FrameLayout()).addChild(ruleEditBox);

final var footer = layout.addToFooter(LinearLayout.horizontal().spacing(8));
footer.addChild(Button.builder(HELP_LABEL, ConfirmLinkScreen.confirmLink(this, HELP_URL)).build());
footer.addChild(Button.builder(CommonComponents.GUI_DONE, _ -> saveAndClose()).build());
footer.addChild(Button.builder(CommonComponents.GUI_CANCEL, _ -> onClose()).build());
layout.visitWidgets(this::addRenderableWidget);
repositionElements();
setInitialFocus(ruleEditBox);
}

@Override
protected void repositionElements() {
layout.arrangeElements();
if (ruleEditBox != null) {
ruleEditBox.setX(20);
ruleEditBox.setY(layout.getHeaderHeight() + 10);
ruleEditBox.setWidth(Math.max(1, width - 40));
ruleEditBox.setHeight(Math.max(1, height - layout.getHeaderHeight() - layout.getFooterHeight() - 20));
}
}

@Override
public boolean keyPressed(KeyEvent event) {
if (event.isEscape()) {
onClose();
return true;
}

return super.keyPressed(event);
}

@Override
public void onClose() {
minecraft.gui.setScreen(parent);
}

private void saveAndClose() {
if (ruleEditBox != null) {
valueConsumer.accept(ruleEditBox.getValue());
}
onClose();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package net.blay09.mods.waystones.client.config;

import net.blay09.mods.balm.client.platform.config.screen.BalmConfigScreen;
import net.blay09.mods.balm.client.platform.config.screen.BalmConfigScreenLabeledEntry;
import net.blay09.mods.balm.client.platform.config.screen.list.BalmConfigListEditorScreen;
import net.blay09.mods.balm.platform.config.schema.ConfiguredProperty;
import net.blay09.mods.balm.platform.config.util.ConfigLocalization;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.Button;
import net.minecraft.network.chat.Component;
import org.jspecify.annotations.Nullable;

import java.util.List;
import java.util.Locale;

public class WarpRequirementsConfigEntry extends BalmConfigScreenLabeledEntry {

private final ConfiguredProperty<List<String>> property;

public WarpRequirementsConfigEntry(BalmConfigScreen screen, ConfiguredProperty<List<String>> property) {
super(screen,
Component.translatable(ConfigLocalization.forProperty(property)),
Component.translatable(ConfigLocalization.forPropertyTooltip(property)),
Button.builder(
Component.translatable("gui.balm.configuration.list.items", screen.bindingFor(property).get().size()),
_ -> Minecraft.getInstance().gui.setScreen(createListEditor(screen, property)))
.width(Button.DEFAULT_WIDTH)
.build());
this.property = property;
}

@Override
protected @Nullable Component getValidationError() {
return context.getValidationError(property);
}

private static BalmConfigListEditorScreen<String> createListEditor(BalmConfigScreen screen, ConfiguredProperty<List<String>> property) {
final var binding = screen.bindingFor(property);
return BalmConfigListEditorScreen.builder(screen, screen, binding)
.customizeEntries(WarpRequirementListEditorEntry::new)
.searchable((value, filter) -> value.toLowerCase(Locale.ROOT).contains(filter))
.build();
}
}
Loading