Fix config view handler to support multiple configs, support mouse binds, add translation keys

This commit is contained in:
Surya 2021-06-04 23:32:53 +05:30
parent a558a2f53e
commit 069003d1ef
17 changed files with 609 additions and 230 deletions

View File

@ -0,0 +1,27 @@
package me.bionicbeanie.mods.savecoords;
import java.util.List;
import net.minecraft.client.util.InputUtil.Type;
import net.minecraft.text.Text;
public interface IKeyBinds {
public static String DEFAULT = "default";
public static String PING = "ping";
public List<IKeyBinding> getAllBinds();
public IKeyBinding getKeyBind(String name);
public void updateKeyBind(String name, Type type, int code);
public interface IKeyBinding{
public String getName();
public boolean wasPressed();
public Type getDefaultType();
public int getDefaultCode();
public Type getType();
public int getCode();
public Text getNameLocalizedText();
public Text getBoundKeyLocalizedText();
}
}

View File

@ -1,18 +1,30 @@
package me.bionicbeanie.mods.savecoords; package me.bionicbeanie.mods.savecoords;
import me.bionicbeanie.mods.savecoords.gui.impl.ModDI; import me.bionicbeanie.mods.savecoords.IKeyBinds.IKeyBinding;
import me.bionicbeanie.mods.savecoords.gui.impl.DIContainer;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
public class SaveCoordinatesClient implements ClientModInitializer { public class SaveCoordinatesClient implements ClientModInitializer {
private static IKeyBinding defaultKeyBinding = getKeyBinding(IKeyBinds.DEFAULT);
private static IKeyBinding pingKeyBinding = getKeyBinding(IKeyBinds.PING);
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
ClientTickEvents.END_CLIENT_TICK.register(client -> { ClientTickEvents.END_CLIENT_TICK.register(client -> {
while (ModDI.getKeyBindConfiguration().getDefaultKeyBinding().wasPressed()) { while(defaultKeyBinding.wasPressed()) {
ModDI.getModGui().open(); DIContainer.getModGui().open();
}
while(pingKeyBinding.wasPressed()) {
DIContainer.getPingPositionOperation().run();
} }
}); });
} }
private static IKeyBinding getKeyBinding(String name) {
return DIContainer.getKeyBinds().getKeyBind(name);
}
} }

View File

@ -0,0 +1,16 @@
package me.bionicbeanie.mods.savecoords;
public interface TranslationKeys {
public static String KEYBIND_DEFAULT = "key.savecoords.default";
public static String KEYBIND_PING = "key.savecoords.ping";
public static String CATEGORY_GENERIC = "category.savecoords.default";
public static String MENU_SAVE = "menu.savecoords.save";
public static String MENU_BACK = "menu.savecoords.back";
public static String MENU_RESET = "menu.savecoords.reset";
public static String MENU_CLOSE = "menu.savecoords.close";
public static String MENU_LIST = "menu.savecoords.list";
public static String MENU_CONF = "menu.savecoords.conf";
public static String MENU_LOCATION = "menu.savecoords.location";
public static String MENU_NOTES = "menu.savecoords.notes";
public static String MENU_WORLD_NAME = "menu.savecoords.world_name";
}

View File

@ -1,10 +0,0 @@
package me.bionicbeanie.mods.savecoords.gui;
import net.minecraft.client.options.KeyBinding;
public interface IKeyBindConfiguration {
KeyBinding getDefaultKeyBinding();
void setDefaultKeyBinding(int keyCode);
}

View File

@ -1,15 +1,17 @@
package me.bionicbeanie.mods.savecoords.gui.impl; package me.bionicbeanie.mods.savecoords.gui.impl;
import java.util.function.Consumer; import java.util.function.BiConsumer;
import io.github.cottonmc.cotton.gui.GuiDescription; import io.github.cottonmc.cotton.gui.GuiDescription;
import me.bionicbeanie.mods.savecoords.gui.SaveCoordinatesScreen; import me.bionicbeanie.mods.savecoords.gui.SaveCoordinatesScreen;
import net.minecraft.client.util.InputUtil;
import net.minecraft.client.util.InputUtil.Type;
public class ConfigScreen extends SaveCoordinatesScreen{ public class ConfigScreen extends SaveCoordinatesScreen {
private Consumer<Integer> keyCodeConsumer; private BiConsumer<Type, Integer> keyCodeConsumer;
public ConfigScreen(GuiDescription description, Consumer<Integer> keyCodeConsumer) { public ConfigScreen(GuiDescription description, BiConsumer<Type, Integer> keyCodeConsumer) {
super(description); super(description);
this.keyCodeConsumer = keyCodeConsumer; this.keyCodeConsumer = keyCodeConsumer;
@ -17,7 +19,13 @@ public class ConfigScreen extends SaveCoordinatesScreen{
@Override @Override
public boolean keyReleased(int ch, int keyCode, int modifiers) { public boolean keyReleased(int ch, int keyCode, int modifiers) {
keyCodeConsumer.accept(ch); keyCodeConsumer.accept(InputUtil.Type.KEYSYM, ch);
return super.keyReleased(ch, keyCode, modifiers); return super.keyReleased(ch, keyCode, modifiers);
} }
@Override
public boolean mouseReleased(double mouseX, double mouseY, int mouseButton) {
keyCodeConsumer.accept(InputUtil.Type.MOUSE, mouseButton);
return super.mouseReleased(mouseX, mouseY, mouseButton);
}
} }

View File

@ -1,107 +1,287 @@
package me.bionicbeanie.mods.savecoords.gui.impl; package me.bionicbeanie.mods.savecoords.gui.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import io.github.cottonmc.cotton.gui.widget.WButton; import io.github.cottonmc.cotton.gui.widget.WButton;
import io.github.cottonmc.cotton.gui.widget.WLabel; import io.github.cottonmc.cotton.gui.widget.WLabel;
import io.github.cottonmc.cotton.gui.widget.WListPanel;
import io.github.cottonmc.cotton.gui.widget.WPlainPanel;
import me.bionicbeanie.mods.savecoords.IKeyBinds.IKeyBinding;
import me.bionicbeanie.mods.savecoords.TranslationKeys;
import me.bionicbeanie.mods.savecoords.gui.IRootPanel; import me.bionicbeanie.mods.savecoords.gui.IRootPanel;
import me.bionicbeanie.mods.savecoords.model.ConfigData;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.InputUtil; import net.minecraft.client.util.InputUtil.Type;
import net.minecraft.client.util.InputUtil.Key;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
class ConfigViewHandler extends ViewHandlerBase<ConfigData> { // TODO:
// Clean the mess below on order of event handling
// Remove `shouldNotUpdateBinding
private WButton keyBindingButton; class ConfigViewHandler extends ViewHandlerBase<List<IKeyBinding>> {
private ConfigItemPanel focussingConfig;
private WButton saveButton; private WButton saveButton;
private WButton backButton; private WButton backButton;
private boolean focussing = false;
private int newKeyBinding = -1;
private WButton resetButton; private WButton resetButton;
private boolean shouldNotUpdateBinding = false;
private ConfigListPanel listPanel;
public ConfigViewHandler() { public ConfigViewHandler() {
keyBindingButton = new WButton(); this.saveButton = new WButton(new TranslatableText(TranslationKeys.MENU_SAVE));
saveButton = new WButton(new LiteralText("SAVE")); this.backButton = new WButton(new TranslatableText(TranslationKeys.MENU_BACK));
backButton = new WButton(new LiteralText("BACK")); this.resetButton = new WButton(new TranslatableText(TranslationKeys.MENU_RESET));
resetButton = new WButton(new LiteralText("RESET"));
} }
@Override @Override
protected Supplier<ConfigData> setupView(IRootPanel rootGridPanel, ConfigData state) { protected Supplier<List<IKeyBinding>> setupView(IRootPanel rootGridPanel, List<IKeyBinding> binds) {
if (state == null) { listPanel = createListPanel(binds);
state = new ConfigData(); rootGridPanel.add(listPanel, 0, 0, 15, 9);
}
newKeyBinding = state.getDefaultKeyBindingCode(); rootGridPanel.add(resetButton, 10, 9, 2, 1);
focussing = false;
WLabel configLabel = new WLabel("Default Key Binding");
rootGridPanel.add(configLabel, 4, 3, 3, 1);
setConfigValue(state.getDefaultKeyBindingCode());
keyBindingButton.setOnClick(() -> {
focussing = !focussing;
if (focussing) {
keyBindingButton.setLabel(new LiteralText("_"));
}
});
resetButton.setOnClick(() -> {
focussing = true;
setConfigValue(new ConfigData().getDefaultKeyBindingCode());
focussing = false;
});
rootGridPanel.add(keyBindingButton, 4, 4, 3, 1);
rootGridPanel.add(saveButton, 13, 9, 2, 1); rootGridPanel.add(saveButton, 13, 9, 2, 1);
rootGridPanel.add(backButton, 0, 9, 2, 1); rootGridPanel.add(backButton, 0, 9, 2, 1);
rootGridPanel.add(resetButton, 8, 4, 2, 1);
this.resetButton.setOnClick(() -> {
this.shouldNotUpdateBinding = true;
this.reset();
});
return () -> { return () -> {
ConfigData data = new ConfigData(); return listPanel.getState();
data.setDefaultKeyBindingCode(newKeyBinding);
return data;
}; };
} }
private ConfigListPanel createListPanel(List<IKeyBinding> keyConfigs) {
BiConsumer<IKeyBinding, ConfigItemPanel> configurator = (conf, p) -> p.setInitialConfig(conf);
ConfigListPanel panel = createListPanel(keyConfigs, configurator);
panel.setListItemHeight(2 * 18);
return panel;
}
private ConfigListPanel createListPanel(List<IKeyBinding> keyConfigs,
BiConsumer<IKeyBinding, ConfigItemPanel> configurator) {
return new ConfigListPanel(keyConfigs, this::createConfigItemPanel, configurator);
}
private ConfigItemPanel createConfigItemPanel() {
ConfigItemPanel panel = new ConfigItemPanel();
panel.setOnFocus((k) -> {
if(focussingConfig != null) {
focussingConfig.reset();
}
this.focussingConfig = k;
});
return panel;
}
@Override @Override
protected Screen createScreen() { protected Screen createScreen() {
return new ConfigScreen(this, (k) -> { return new ConfigScreen(this, (t, c) -> {
if (focussing) {
setConfigValue(k); if(shouldNotUpdateBinding) {
focussing = false; shouldNotUpdateBinding = false;
return;
} }
if(this.focussingConfig == null) {
return;
}
this.registerKeybind(t, c);
}); });
} }
public void onBack(Runnable runnable) { void onBack(Runnable runnable) {
this.backButton.setOnClick(runnable); this.backButton.setOnClick(() -> {
runnable.run();
});
} }
public void onSave(Runnable runnable) { void onSave(Runnable runnable) {
this.saveButton.setOnClick(runnable); this.saveButton.setOnClick(() -> {
this.shouldNotUpdateBinding = true;
if(this.focussingConfig != null) {
this.focussingConfig.reset();
}
runnable.run();
});
} }
private void setConfigValue(Integer k) { private void registerKeybind(Type type, int code) {
newKeyBinding = k;
keyBindingButton.setLabel(new LiteralText(parseKeyName(k))); if(this.focussingConfig != null) {
focussingConfig.updateBinding(type, code);
focussingConfig = null;
} }
private String parseKeyName(Integer k) { return;
Key key = InputUtil.Type.KEYSYM.createFromCode(k);
String keyString = key.toString();
try {
return keyString.split("\\.")[2];
} catch (Exception e) {
e.printStackTrace();
} }
return keyString; private void reset() {
listPanel.reset();
focussingConfig = null;
}
private class ConfigListPanel extends WListPanel<IKeyBinding, ConfigItemPanel>{
public ConfigListPanel(List<IKeyBinding> data, Supplier<ConfigItemPanel> supplier,
BiConsumer<IKeyBinding, ConfigItemPanel> configurator) {
super(data, supplier, configurator);
}
List<IKeyBinding> getState(){
List<IKeyBinding> keyBinds = new ArrayList<>();
this.configured.forEach((k, p) -> {
keyBinds.add(new KeyData(p.getType(), p.getCode(), k));
});
return keyBinds;
}
void reset() {
this.configured.forEach((k, p) -> p.reset());
}
}
private class KeyData implements IKeyBinding{
private Type type;
private int code;
private IKeyBinding existingBinding;
KeyData(Type type, int code, IKeyBinding binding){
this.type = type;
this.code= code;
this.existingBinding= binding;
}
@Override
public String getName() {
return existingBinding.getName();
}
@Override
public boolean wasPressed() {
return existingBinding.wasPressed();
}
@Override
public Type getType() {
return type;
}
@Override
public int getCode() {
return code;
}
@Override
public Text getBoundKeyLocalizedText() {
return existingBinding.getBoundKeyLocalizedText();
}
@Override
public Text getNameLocalizedText() {
return existingBinding.getNameLocalizedText();
}
@Override
public Type getDefaultType() {
return existingBinding.getDefaultType();
}
@Override
public int getDefaultCode() {
return existingBinding.getDefaultCode();
}
}
private class ConfigItemPanel extends WPlainPanel {
private WButton configButton;
private WButton resetButton;
private WLabel configLabel;
private boolean focussing = false;
private Type defaultType;
private int defaultCode;
private Type type;
private int code;
ConfigItemPanel() {
this.configLabel = new WLabel("Foo");
this.configButton = new WButton();
this.resetButton = new WButton(new LiteralText("RESET"));
}
void setInitialConfig(IKeyBinding config) {
this.defaultType = config.getDefaultType();
this.defaultCode = config.getDefaultCode();
this.type = config.getType();
this.code = config.getCode();
this.configLabel.setText(config.getNameLocalizedText());
updateWidgetData(this.type, this.code);
this.resetButton.setOnClick(this::reset);
this.add(configLabel, 0, 0, 4 * 18, 1 * 9);
this.add(configButton, 5 * 18, 0, 4 * 18, 1 * 18);
this.add(resetButton, 11 * 18, 0, 3 * 18, 1 * 18);
}
void reset() {
focussing = false;
this.type = this.defaultType;
this.code = this.defaultCode;
updateWidgetData(this.defaultType, this.defaultCode);
}
void updateBinding(Type type, int code) {
if(!focussing) {
return;
}
this.type = type;
this.code = code;
focussing = false;
updateWidgetData(type, code);
}
void setOnFocus(Consumer<ConfigItemPanel> focussedConfigConsumer) {
this.configButton.setOnClick(() -> {
if(!focussing) {
focussing = true;
focussedConfigConsumer.accept(this);
}
updateWidgetData(this.type, this.code);
});
}
Type getType() {
return type;
}
int getCode() {
return code;
}
private void updateWidgetData(Type type, int code) {
if(focussing) {
this.configButton.setLabel(new LiteralText("_"));
return;
}
this.configButton.setLabel(type.createFromCode(code).getLocalizedText());
}
} }
} }

View File

@ -1,73 +1,75 @@
package me.bionicbeanie.mods.savecoords.gui.impl; package me.bionicbeanie.mods.savecoords.gui.impl;
import java.io.IOException;
import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import me.bionicbeanie.mods.savecoords.IFileStore; import me.bionicbeanie.mods.savecoords.IFileStore;
import me.bionicbeanie.mods.savecoords.IKeyBinds;
import me.bionicbeanie.mods.savecoords.IModGui; import me.bionicbeanie.mods.savecoords.IModGui;
import me.bionicbeanie.mods.savecoords.IPlayerLocator; import me.bionicbeanie.mods.savecoords.IPlayerLocator;
import me.bionicbeanie.mods.savecoords.gui.IKeyBindConfiguration;
import me.bionicbeanie.mods.savecoords.impl.Factory; import me.bionicbeanie.mods.savecoords.impl.Factory;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
//All of this works because single-threaded initialization!! Sed lyf :( //All of this works because single-threaded initialization!! Sed lyf :(
public class ModDI { public class DIContainer {
private static boolean initialized = false; private static boolean initialized = false;
private static IFileStore fileStore; private static IFileStore fileStore;
private static IKeyBindConfiguration keyBindConfiguration;
private static GuiController guiController; private static GuiController guiController;
private static IPlayerLocator playerLocator; private static IPlayerLocator playerLocator;
private static IModGui modGui; private static IModGui modGui;
private static IKeyBinds keyBinds;
private static ConfigScreenFactory<Screen> modMenuScreenFactory; private static ConfigScreenFactory<Screen> modMenuScreenFactory;
private static PingPositionOperation pingPositionOperation;
public static IKeyBindConfiguration getKeyBindConfiguration() {
initialize();
return keyBindConfiguration;
}
public static IModGui getModGui() { public static IModGui getModGui() {
initialize(); initialize();
return modGui; return modGui;
} }
public static ConfigScreenFactory<Screen> getModMenuScreenFactory(){ public static IKeyBinds getKeyBinds() {
if(modMenuScreenFactory == null) { initialize();
return keyBinds;
}
public static ConfigScreenFactory<Screen> getModMenuScreenFactory() {
initialize();
if (modMenuScreenFactory == null) {
modMenuScreenFactory = (parent) -> { modMenuScreenFactory = (parent) -> {
ConfigViewHandler handler = new ConfigViewHandler(); ConfigViewHandler handler = new ConfigViewHandler();
handler.onSave(() -> { handler.onSave(() -> {
new SaveConfigsOperation(keyBindConfiguration, handler::getState).run(); new SaveConfigsOperation(keyBinds, fileStore, handler::getState).run();
guiController.openScreen(parent); guiController.closeScreen();
}); });
handler.onBack(() -> guiController.openScreen(parent)); handler.onBack(() -> guiController.closeScreen());
try { return handler.createView(keyBinds.getAllBinds());
return handler.createView(fileStore.readConfigData());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}; };
} }
return modMenuScreenFactory; return modMenuScreenFactory;
} }
public static Runnable getPingPositionOperation() {
initialize();
return pingPositionOperation;
}
private static void initialize() { private static void initialize() {
if(!initialized) { if (!initialized) {
initialized = true; initialized = true;
MinecraftClient minecraftClient = MinecraftClient.getInstance(); MinecraftClient minecraftClient = MinecraftClient.getInstance();
fileStore = Factory.createFileStore(minecraftClient.runDirectory.getAbsolutePath()); fileStore = Factory.createFileStore(minecraftClient.runDirectory.getAbsolutePath());
keyBindConfiguration = Factory.createKeyBindConfiguration(fileStore);
guiController = new GuiController(minecraftClient); guiController = new GuiController(minecraftClient);
playerLocator = Factory.CreatePlayerLocator(minecraftClient); playerLocator = Factory.CreatePlayerLocator(minecraftClient);
modGui = new SaveCoordinatesGui(fileStore, playerLocator, keyBindConfiguration, guiController); keyBinds = Factory.CreateKeyBinds(fileStore);
modGui = new SaveCoordinatesGui(fileStore, playerLocator, keyBinds, guiController);
pingPositionOperation = new PingPositionOperation(fileStore, () -> playerLocator.locate());
} }
} }
} }

View File

@ -10,12 +10,14 @@ import io.github.cottonmc.cotton.gui.widget.WTextField;
import io.github.cottonmc.cotton.gui.widget.WWidget; import io.github.cottonmc.cotton.gui.widget.WWidget;
import me.bionicbeanie.mods.savecoords.IFileStore; import me.bionicbeanie.mods.savecoords.IFileStore;
import me.bionicbeanie.mods.savecoords.IPlayerLocator; import me.bionicbeanie.mods.savecoords.IPlayerLocator;
import me.bionicbeanie.mods.savecoords.TranslationKeys;
import me.bionicbeanie.mods.savecoords.gui.IRootPanel; import me.bionicbeanie.mods.savecoords.gui.IRootPanel;
import me.bionicbeanie.mods.savecoords.model.PlayerPosition; import me.bionicbeanie.mods.savecoords.model.PlayerPosition;
import me.bionicbeanie.mods.savecoords.model.PlayerRawPosition; import me.bionicbeanie.mods.savecoords.model.PlayerRawPosition;
import me.bionicbeanie.mods.savecoords.model.PositionMetadata; import me.bionicbeanie.mods.savecoords.model.PositionMetadata;
import me.bionicbeanie.mods.savecoords.util.ResourceUtils; import me.bionicbeanie.mods.savecoords.util.ResourceUtils;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText;
class DefaultViewHandler extends ViewHandlerBase<PlayerPosition> { class DefaultViewHandler extends ViewHandlerBase<PlayerPosition> {
@ -31,11 +33,11 @@ class DefaultViewHandler extends ViewHandlerBase<PlayerPosition> {
this.fileStore = fileStore; this.fileStore = fileStore;
this.locator = locator; this.locator = locator;
this.listButton = CreateButton("LIST"); this.listButton = CreateButton(TranslationKeys.MENU_LIST);
this.saveButton = CreateButton("SAVE"); this.saveButton = CreateButton(TranslationKeys.MENU_SAVE);
this.pingButton = CreatePingButton(); this.pingButton = CreatePingButton();
this.closeButton = CreateButton("CLOSE"); this.closeButton = CreateButton(TranslationKeys.MENU_CLOSE);
this.configButton = CreateButton("CONF"); this.configButton = CreateButton(TranslationKeys.MENU_CONF);
} }
@Override @Override
@ -151,7 +153,7 @@ class DefaultViewHandler extends ViewHandlerBase<PlayerPosition> {
} }
private WTextField CreateLocationField(PlayerPosition existingPosition) { private WTextField CreateLocationField(PlayerPosition existingPosition) {
WTextField location = new WTextField(new LiteralText("location name")); WTextField location = new WTextField(new TranslatableText(TranslationKeys.MENU_LOCATION));
if (existingPosition != null) { if (existingPosition != null) {
location.setText(existingPosition.getLocationName()); location.setText(existingPosition.getLocationName());
@ -163,7 +165,7 @@ class DefaultViewHandler extends ViewHandlerBase<PlayerPosition> {
} }
private WTextField CreateNotesField(PlayerPosition existingPosition) { private WTextField CreateNotesField(PlayerPosition existingPosition) {
WTextField notes = new WTextField(new LiteralText("additional notes")); WTextField notes = new WTextField(new TranslatableText(TranslationKeys.MENU_NOTES));
if (existingPosition != null && existingPosition.getPositionMetadata() != null) { if (existingPosition != null && existingPosition.getPositionMetadata() != null) {
notes.setText(existingPosition.getPositionMetadata().getNotes()); notes.setText(existingPosition.getPositionMetadata().getNotes());
@ -173,7 +175,7 @@ class DefaultViewHandler extends ViewHandlerBase<PlayerPosition> {
} }
private WTextField CreateWorldField(String defaultWorld) { private WTextField CreateWorldField(String defaultWorld) {
WTextField world = new WTextField(new LiteralText("world name")); WTextField world = new WTextField(new TranslatableText(TranslationKeys.MENU_WORLD_NAME));
world.setMaxLength(7); world.setMaxLength(7);
world.setText(defaultWorld); world.setText(defaultWorld);
return world; return world;
@ -185,7 +187,7 @@ class DefaultViewHandler extends ViewHandlerBase<PlayerPosition> {
return button; return button;
} }
private WButton CreateButton(String name) { private WButton CreateButton(String translationKey) {
return new WButton(new LiteralText(name)); return new WButton(new TranslatableText(translationKey));
} }
} }

View File

@ -13,11 +13,13 @@ import io.github.cottonmc.cotton.gui.widget.WListPanel;
import io.github.cottonmc.cotton.gui.widget.WPlainPanel; import io.github.cottonmc.cotton.gui.widget.WPlainPanel;
import io.github.cottonmc.cotton.gui.widget.WSprite; import io.github.cottonmc.cotton.gui.widget.WSprite;
import me.bionicbeanie.mods.savecoords.IFileStore; import me.bionicbeanie.mods.savecoords.IFileStore;
import me.bionicbeanie.mods.savecoords.TranslationKeys;
import me.bionicbeanie.mods.savecoords.gui.IRootPanel; import me.bionicbeanie.mods.savecoords.gui.IRootPanel;
import me.bionicbeanie.mods.savecoords.model.PlayerPosition; import me.bionicbeanie.mods.savecoords.model.PlayerPosition;
import me.bionicbeanie.mods.savecoords.model.PlayerRawPosition; import me.bionicbeanie.mods.savecoords.model.PlayerRawPosition;
import me.bionicbeanie.mods.savecoords.util.ResourceUtils; import me.bionicbeanie.mods.savecoords.util.ResourceUtils;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
class ListViewHandler extends ViewHandlerBase<Void> { class ListViewHandler extends ViewHandlerBase<Void> {
@ -54,19 +56,19 @@ class ListViewHandler extends ViewHandlerBase<Void> {
} }
private WButton createBackButton() { private WButton createBackButton() {
return new WButton(new LiteralText("BACK")); return new WButton(new TranslatableText(TranslationKeys.MENU_BACK));
} }
private WListPanel<PlayerPosition, CoordinatesListItemPanel> createListPane(List<PlayerPosition> positions) { private WListPanel<PlayerPosition, CoordinatesListItemPanel> createListPane(List<PlayerPosition> positions) {
BiConsumer<PlayerPosition, CoordinatesListItemPanel> configurator = (pos, p) -> p.setPosition(pos, fileStore); BiConsumer<PlayerPosition, CoordinatesListItemPanel> configurator = (pos, p) -> p.setPosition(pos, fileStore);
WListPanel<PlayerPosition, CoordinatesListItemPanel> panel = CreateListPanel(positions, configurator); WListPanel<PlayerPosition, CoordinatesListItemPanel> panel = createListPanel(positions, configurator);
panel.setListItemHeight(2 * 18); panel.setListItemHeight(2 * 18);
return panel; return panel;
} }
private WListPanel<PlayerPosition, CoordinatesListItemPanel> CreateListPanel(List<PlayerPosition> positions, private WListPanel<PlayerPosition, CoordinatesListItemPanel> createListPanel(List<PlayerPosition> positions,
BiConsumer<PlayerPosition, CoordinatesListItemPanel> config) { BiConsumer<PlayerPosition, CoordinatesListItemPanel> config) {
return new WListPanel<>(positions, this::createListPanel, config); return new WListPanel<>(positions, this::createListPanel, config);
} }

View File

@ -1,23 +1,44 @@
package me.bionicbeanie.mods.savecoords.gui.impl; package me.bionicbeanie.mods.savecoords.gui.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import me.bionicbeanie.mods.savecoords.IFileStore; import me.bionicbeanie.mods.savecoords.IFileStore;
import me.bionicbeanie.mods.savecoords.gui.IKeyBindConfiguration; import me.bionicbeanie.mods.savecoords.IKeyBinds;
import me.bionicbeanie.mods.savecoords.IKeyBinds.IKeyBinding;
import me.bionicbeanie.mods.savecoords.model.ConfigData; import me.bionicbeanie.mods.savecoords.model.ConfigData;
import me.bionicbeanie.mods.savecoords.model.ConfigData.Config;
public class SaveConfigsOperation extends ViewOperationBase<ConfigData>{ public class SaveConfigsOperation extends ViewOperationBase<List<IKeyBinding>>{
private IKeyBindConfiguration keyBindConfiguration; private IKeyBinds keyBinds;
public SaveConfigsOperation(IKeyBindConfiguration keyBindConfiguration, Supplier<ConfigData> stateSupplier) { public SaveConfigsOperation(IKeyBinds keyBinds, IFileStore fileStore, Supplier<List<IKeyBinding>> stateSupplier) {
super(null, stateSupplier); super(fileStore, stateSupplier);
this.keyBindConfiguration = keyBindConfiguration; this.keyBinds = keyBinds;
} }
@Override @Override
protected void executeOperation(IFileStore fileStore, ConfigData state) throws Exception { protected void executeOperation(IFileStore fileStore, List<IKeyBinding> state) throws Exception {
this.keyBindConfiguration.setDefaultKeyBinding(state.getDefaultKeyBindingCode());
ConfigData configData = new ConfigData();
List<Config> configsToWrite = new ArrayList<>();
for (IKeyBinding binding : state) {
Config config = new Config();
config.setName(binding.getName());
config.setType(binding.getType());
config.setCode(binding.getCode());
keyBinds.updateKeyBind(binding.getName(), binding.getType(), binding.getCode());
configsToWrite.add(config);
}
configData.setKeyConfigs(configsToWrite.toArray(new Config[] {}));
fileStore.writeConfigs(configData);
} }
} }

View File

@ -1,14 +1,14 @@
package me.bionicbeanie.mods.savecoords.gui.impl; package me.bionicbeanie.mods.savecoords.gui.impl;
import java.io.IOException; import java.util.List;
import me.bionicbeanie.mods.savecoords.IFileStore; import me.bionicbeanie.mods.savecoords.IFileStore;
import me.bionicbeanie.mods.savecoords.IKeyBinds;
import me.bionicbeanie.mods.savecoords.IKeyBinds.IKeyBinding;
import me.bionicbeanie.mods.savecoords.IModGui; import me.bionicbeanie.mods.savecoords.IModGui;
import me.bionicbeanie.mods.savecoords.IPlayerLocator; import me.bionicbeanie.mods.savecoords.IPlayerLocator;
import me.bionicbeanie.mods.savecoords.gui.IGuiController; import me.bionicbeanie.mods.savecoords.gui.IGuiController;
import me.bionicbeanie.mods.savecoords.gui.IKeyBindConfiguration;
import me.bionicbeanie.mods.savecoords.gui.IViewHandler; import me.bionicbeanie.mods.savecoords.gui.IViewHandler;
import me.bionicbeanie.mods.savecoords.model.ConfigData;
import me.bionicbeanie.mods.savecoords.model.PlayerPosition; import me.bionicbeanie.mods.savecoords.model.PlayerPosition;
import me.bionicbeanie.mods.savecoords.model.PlayerRawPosition; import me.bionicbeanie.mods.savecoords.model.PlayerRawPosition;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
@ -19,15 +19,14 @@ public class SaveCoordinatesGui implements IModGui {
private IFileStore fileStore; private IFileStore fileStore;
private IViewHandler<PlayerPosition> defaultHandler; private IViewHandler<PlayerPosition> defaultHandler;
private IViewHandler<Void> listHandler; private IViewHandler<Void> listHandler;
private IViewHandler<ConfigData> configHandler; private IViewHandler<List<IKeyBinding>> configHandler;
private IPlayerLocator locator; private IPlayerLocator locator;
private IKeyBindConfiguration keyBindConfiguration; private IKeyBinds keyBinds;
SaveCoordinatesGui(IFileStore fileStore, IPlayerLocator locator, IKeyBindConfiguration keyBindConfiguration, SaveCoordinatesGui(IFileStore fileStore, IPlayerLocator locator, IKeyBinds binds, IGuiController screenController) {
IGuiController screenController) {
this.screenController = screenController; this.screenController = screenController;
this.fileStore = fileStore; this.fileStore = fileStore;
this.keyBindConfiguration = keyBindConfiguration; this.keyBinds = binds;
this.locator = locator; this.locator = locator;
this.defaultHandler = CreateDefaultViewHandler(); this.defaultHandler = CreateDefaultViewHandler();
@ -42,13 +41,7 @@ public class SaveCoordinatesGui implements IModGui {
} }
private Screen createConfigScreen() { private Screen createConfigScreen() {
try { return this.configHandler.createView(keyBinds.getAllBinds());
return this.configHandler.createView(fileStore.readConfigData());
} catch (IOException e) {
e.printStackTrace();
}
return null;
} }
private IViewHandler<PlayerPosition> CreateDefaultViewHandler() { private IViewHandler<PlayerPosition> CreateDefaultViewHandler() {
@ -72,7 +65,7 @@ public class SaveCoordinatesGui implements IModGui {
return handler; return handler;
} }
private IViewHandler<ConfigData> CreateConfigHandler() { private IViewHandler<List<IKeyBinding>> CreateConfigHandler() {
ConfigViewHandler handler = new ConfigViewHandler(); ConfigViewHandler handler = new ConfigViewHandler();
handler.onBack(() -> showDefaultView(null)); handler.onBack(() -> showDefaultView(null));
@ -100,7 +93,7 @@ public class SaveCoordinatesGui implements IModGui {
} }
private void onSaveConfigs() { private void onSaveConfigs() {
new SaveConfigsOperation(keyBindConfiguration, configHandler::getState).run(); new SaveConfigsOperation(keyBinds, fileStore, configHandler::getState).run();
showDefaultView(null); showDefaultView(null);
} }

View File

@ -1,8 +1,8 @@
package me.bionicbeanie.mods.savecoords.impl; package me.bionicbeanie.mods.savecoords.impl;
import me.bionicbeanie.mods.savecoords.IFileStore; import me.bionicbeanie.mods.savecoords.IFileStore;
import me.bionicbeanie.mods.savecoords.IKeyBinds;
import me.bionicbeanie.mods.savecoords.IPlayerLocator; import me.bionicbeanie.mods.savecoords.IPlayerLocator;
import me.bionicbeanie.mods.savecoords.gui.IKeyBindConfiguration;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
public class Factory { public class Factory {
@ -15,7 +15,7 @@ public class Factory {
return new PlayerLocator(client); return new PlayerLocator(client);
} }
public static IKeyBindConfiguration createKeyBindConfiguration(IFileStore fileStore) { public static IKeyBinds CreateKeyBinds(IFileStore fileStore) {
return new KeyBindConfiguration(fileStore); return new KeyBinds(fileStore);
} }
} }

View File

@ -1,71 +0,0 @@
package me.bionicbeanie.mods.savecoords.impl;
import java.io.IOException;
import me.bionicbeanie.mods.savecoords.IFileStore;
import me.bionicbeanie.mods.savecoords.gui.IKeyBindConfiguration;
import me.bionicbeanie.mods.savecoords.model.ConfigData;
import net.minecraft.client.options.KeyBinding;
import net.minecraft.client.util.InputUtil;
class KeyBindConfiguration implements IKeyBindConfiguration {
private KeyBinding defaultKeyBinding;
private IFileStore fileStore;
KeyBindConfiguration(IFileStore fileStore) {
this.fileStore = fileStore;
try {
this.defaultKeyBinding = createDefaultKeyBinding(fileStore);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException();
}
}
@Override
public KeyBinding getDefaultKeyBinding() {
return defaultKeyBinding;
}
@Override
public void setDefaultKeyBinding(int keyCode) {
writeConfigs(keyCode);
defaultKeyBinding.setBoundKey(InputUtil.Type.KEYSYM.createFromCode(keyCode));
KeyBinding.updateKeysByCode();
}
private void writeConfigs(int keyCode) {
try {
ConfigData data = fileStore.readConfigData();
data.setDefaultKeyBindingCode(keyCode);
fileStore.writeConfigs(data);
}catch (Exception e) {
e.printStackTrace();
}
}
private KeyBinding createDefaultKeyBinding(IFileStore fileStore) throws IOException {
ConfigData configData = fileStore.readConfigData();
if (configData == null) {
configData = new ConfigData();
}
int keyBind = configData.getDefaultKeyBindingCode();
return createKeyBinding(keyBind);
}
private KeyBinding createKeyBinding(int keyBind) {
String translationKey = "key.savecoords.coords";
String category = "category.savecoords.generic";
KeyBinding keyBinding = new KeyBinding(translationKey, InputUtil.Type.KEYSYM, keyBind, category);
return keyBinding;
}
}

View File

@ -0,0 +1,145 @@
package me.bionicbeanie.mods.savecoords.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.lwjgl.glfw.GLFW;
import me.bionicbeanie.mods.savecoords.IFileStore;
import me.bionicbeanie.mods.savecoords.IKeyBinds;
import me.bionicbeanie.mods.savecoords.TranslationKeys;
import me.bionicbeanie.mods.savecoords.model.ConfigData;
import me.bionicbeanie.mods.savecoords.model.ConfigData.Config;
import net.minecraft.client.options.KeyBinding;
import net.minecraft.client.util.InputUtil;
import net.minecraft.client.util.InputUtil.Type;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
class KeyBinds implements IKeyBinds {
KeyBindingEx DEFAULT = new KeyBindingEx(IKeyBinds.DEFAULT, TranslationKeys.KEYBIND_DEFAULT, InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_H, TranslationKeys.CATEGORY_GENERIC);
KeyBindingEx PING = new KeyBindingEx(IKeyBinds.PING, TranslationKeys.KEYBIND_PING, InputUtil.Type.KEYSYM,
GLFW.GLFW_KEY_B, TranslationKeys.CATEGORY_GENERIC);
private IFileStore fileStore;
private Map<String, KeyBindingEx> keyBinds;
private List<IKeyBinding> unmodifiableList;
KeyBinds(IFileStore fileStore) {
this.fileStore = fileStore;
this.keyBinds = new HashMap<>();
add(DEFAULT);
add(PING);
initialize();
this.unmodifiableList = Collections.unmodifiableList(new ArrayList<>(keyBinds.values()));
}
private void add(KeyBindingEx keyBinding) {
keyBinds.put(keyBinding.getName(), keyBinding);
}
@Override
public List<IKeyBinding> getAllBinds() {
return unmodifiableList;
}
@Override
public IKeyBinding getKeyBind(String name) {
return keyBinds.get(name);
}
@Override
public void updateKeyBind(String name, Type type, int code) {
keyBinds.get(name).setBoundKey(type, code);
KeyBinding.updateKeysByCode();
}
static class KeyBindingEx extends KeyBinding implements IKeyBinding {
private Type defaultType;
private Type type;
private int defaultCode;
private int code;
private String name;
public KeyBindingEx(String name, String translationKey, Type type, int code, String category) {
super(translationKey, type, code, category);
this.type = this.defaultType = type;
this.code = this.defaultCode = code;
this.name = name;
}
@Override
public Type getType() {
return type;
}
@Override
public Type getDefaultType() {
return defaultType;
}
@Override
public int getDefaultCode() {
return defaultCode;
}
public void setBoundKey(Type type, int code) {
super.setBoundKey(type.createFromCode(code));
this.type = type;
this.code = code;
}
@Override
public int getCode() {
return code;
}
@Override
public String getName() {
return name;
}
@Override
public Text getNameLocalizedText() {
return new TranslatableText(getTranslationKey());
}
}
private void initialize() {
try {
ConfigData configData = fileStore.readConfigData();
Config[] configs = configData.getKeyConfigs();
if (configs == null) {
return;
}
for (int i = 0; i < configs.length; ++i) {
String name = configs[i].getName();
Type type = configs[i].getType();
int code = configs[i].getCode();
if (keyBinds.containsKey(name)) {
updateKeyBind(name, type, code);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -2,8 +2,13 @@ package me.bionicbeanie.mods.savecoords.model;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import net.minecraft.client.util.InputUtil.Type;
public class ConfigData { public class ConfigData {
private Config[] keyConfigs;
@Deprecated
private int defaultKeyBindingCode; private int defaultKeyBindingCode;
public ConfigData() { public ConfigData() {
@ -17,4 +22,37 @@ public class ConfigData {
public int getDefaultKeyBindingCode() { public int getDefaultKeyBindingCode() {
return defaultKeyBindingCode; return defaultKeyBindingCode;
} }
public Config[] getKeyConfigs() {
return keyConfigs;
}
public void setKeyConfigs(Config[] keyConfigs) {
this.keyConfigs = keyConfigs;
}
public static class Config{
private String name;
private Type type;
private int code;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
} }

View File

@ -3,12 +3,12 @@ package me.bionicbeanie.mods.savecoords.modmenu;
import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi; import com.terraformersmc.modmenu.api.ModMenuApi;
import me.bionicbeanie.mods.savecoords.gui.impl.ModDI; import me.bionicbeanie.mods.savecoords.gui.impl.DIContainer;
public class SaveCoordinatesModMenu implements ModMenuApi { public class SaveCoordinatesModMenu implements ModMenuApi {
@Override @Override
public ConfigScreenFactory<?> getModConfigScreenFactory() { public ConfigScreenFactory<?> getModConfigScreenFactory() {
return ModDI.getModMenuScreenFactory(); return DIContainer.getModMenuScreenFactory();
} }
} }

View File

@ -0,0 +1,14 @@
{
"key.savecoords.default": "Open GUI",
"key.savecoords.ping": "Beam Location",
"category.savecoords.default": "Generic",
"menu.savecoords.save": "SAVE",
"menu.savecoords.reset": "RESET",
"menu.savecoords.back": "BACK",
"menu.savecoords.close": "CLOSE",
"menu.savecoords.list": "LIST",
"menu.savecoords.conf": "CONF",
"menu.savecoords.location": "location name",
"menu.savecoords.notes": "additional notes",
"menu.savecoords.world_name": "world name"
}