From ff679311cd55b0542eb52778e132ad9eaa06b5da Mon Sep 17 00:00:00 2001 From: Surya Date: Fri, 28 May 2021 23:48:09 +0530 Subject: [PATCH] Add 'edit' functionality, improve ui, fix modularity, sort positions based on last modified, store more metadata --- .../mods/SaveCoordinatesClient.java | 7 +- .../me/bionicbeanie/mods/api/IFileStore.java | 6 +- .../java/me/bionicbeanie/mods/api/IGui.java | 13 +- .../bionicbeanie/mods/api/IViewHandler.java | 4 +- .../bionicbeanie/mods/api/IViewOperation.java | 5 + .../mods/gui/SaveCoordinatesGui.java | 22 ++- .../mods/gui/view/DefaultViewHandler.java | 130 ++++++++++++------ .../mods/gui/view/DeleteOperation.java | 18 +++ .../mods/gui/view/ListViewHandler.java | 87 +++++++----- .../mods/gui/view/PingOperation.java | 23 ++++ .../mods/gui/view/SaveOperation.java | 54 ++++++++ .../mods/gui/view/ShowDetailOperation.java | 19 +++ .../mods/gui/view/ViewHandlerBase.java | 21 ++- .../mods/gui/view/ViewOperationBase.java | 26 ++++ .../gui/view/ViewPositionOperationBase.java | 22 +++ .../me/bionicbeanie/mods/impl/FileStore.java | 67 ++++++--- .../me/bionicbeanie/mods/model/ModData.java | 8 ++ .../mods/model/PlayerPosition.java | 27 ++-- .../mods/model/PlayerRawPosition.java | 5 + .../mods/model/PositionMetadata.java | 35 +++-- .../mods/util/DimensionSpriteUtil.java | 5 +- 21 files changed, 470 insertions(+), 134 deletions(-) create mode 100644 src/main/java/me/bionicbeanie/mods/api/IViewOperation.java create mode 100644 src/main/java/me/bionicbeanie/mods/gui/view/DeleteOperation.java create mode 100644 src/main/java/me/bionicbeanie/mods/gui/view/PingOperation.java create mode 100644 src/main/java/me/bionicbeanie/mods/gui/view/SaveOperation.java create mode 100644 src/main/java/me/bionicbeanie/mods/gui/view/ShowDetailOperation.java create mode 100644 src/main/java/me/bionicbeanie/mods/gui/view/ViewOperationBase.java create mode 100644 src/main/java/me/bionicbeanie/mods/gui/view/ViewPositionOperationBase.java create mode 100644 src/main/java/me/bionicbeanie/mods/model/ModData.java diff --git a/src/main/java/me/bionicbeanie/mods/SaveCoordinatesClient.java b/src/main/java/me/bionicbeanie/mods/SaveCoordinatesClient.java index 33d6703..6bb780f 100644 --- a/src/main/java/me/bionicbeanie/mods/SaveCoordinatesClient.java +++ b/src/main/java/me/bionicbeanie/mods/SaveCoordinatesClient.java @@ -13,6 +13,7 @@ import me.bionicbeanie.mods.gui.view.DefaultViewHandler; import me.bionicbeanie.mods.gui.view.ListViewHandler; import me.bionicbeanie.mods.impl.FileStore; import me.bionicbeanie.mods.impl.PlayerLocator; +import me.bionicbeanie.mods.model.PlayerPosition; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; @@ -50,11 +51,11 @@ public class SaveCoordinatesClient implements ClientModInitializer { private IGui CreateModGui(MinecraftClient client) { IGui gui = new SaveCoordinatesGui(); IFileStore fileStore = new FileStore(client.runDirectory.getAbsolutePath()); - IViewHandler saveHandler = new DefaultViewHandler(fileStore, locator, client, gui); - IViewHandler listHandler = new ListViewHandler(fileStore, gui, client); + IViewHandler defaultHandler = new DefaultViewHandler(fileStore, locator, client, gui); + IViewHandler listHandler = new ListViewHandler(fileStore, gui, client); IScreenController screenController = new ScreenController(client); - gui.init(saveHandler, listHandler, screenController); + gui.init(defaultHandler, listHandler, screenController); return gui; } diff --git a/src/main/java/me/bionicbeanie/mods/api/IFileStore.java b/src/main/java/me/bionicbeanie/mods/api/IFileStore.java index 49f752f..c22d8b7 100644 --- a/src/main/java/me/bionicbeanie/mods/api/IFileStore.java +++ b/src/main/java/me/bionicbeanie/mods/api/IFileStore.java @@ -7,8 +7,12 @@ import me.bionicbeanie.mods.model.PlayerPosition; public interface IFileStore { - public void save(PlayerPosition position) throws IOException; + public String getDefaultWorld() throws IOException; + public void setDefaultWorld(String defaultWorldName) throws IOException; + + public void save(PlayerPosition position) throws IOException; + public void delete(String id) throws IOException; public List list() throws IOException; diff --git a/src/main/java/me/bionicbeanie/mods/api/IGui.java b/src/main/java/me/bionicbeanie/mods/api/IGui.java index 1faf88c..0f8241a 100644 --- a/src/main/java/me/bionicbeanie/mods/api/IGui.java +++ b/src/main/java/me/bionicbeanie/mods/api/IGui.java @@ -1,13 +1,18 @@ package me.bionicbeanie.mods.api; +import me.bionicbeanie.mods.model.PlayerPosition; + public interface IGui { - public void init(IViewHandler saveHandler, IViewHandler listHandler, IScreenController screenController); - + public void init(IViewHandler saveHandler, IViewHandler listHandler, + IScreenController screenController); + public void showDefaultView(); + public void setDefaultViewState(PlayerPosition position); + public void showListView(); - + public void close(); - + } diff --git a/src/main/java/me/bionicbeanie/mods/api/IViewHandler.java b/src/main/java/me/bionicbeanie/mods/api/IViewHandler.java index 2cb3a4f..96ebf14 100644 --- a/src/main/java/me/bionicbeanie/mods/api/IViewHandler.java +++ b/src/main/java/me/bionicbeanie/mods/api/IViewHandler.java @@ -1,7 +1,9 @@ package me.bionicbeanie.mods.api; -public interface IViewHandler { +public interface IViewHandler { + void setState(T state); + void clearState(); void placeWidgets(IRootGridPanel rootPanel); } diff --git a/src/main/java/me/bionicbeanie/mods/api/IViewOperation.java b/src/main/java/me/bionicbeanie/mods/api/IViewOperation.java new file mode 100644 index 0000000..0429878 --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/api/IViewOperation.java @@ -0,0 +1,5 @@ +package me.bionicbeanie.mods.api; + +public interface IViewOperation extends Runnable { + +} diff --git a/src/main/java/me/bionicbeanie/mods/gui/SaveCoordinatesGui.java b/src/main/java/me/bionicbeanie/mods/gui/SaveCoordinatesGui.java index 8f9daa9..04d9f22 100644 --- a/src/main/java/me/bionicbeanie/mods/gui/SaveCoordinatesGui.java +++ b/src/main/java/me/bionicbeanie/mods/gui/SaveCoordinatesGui.java @@ -3,20 +3,22 @@ package me.bionicbeanie.mods.gui; import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription; import me.bionicbeanie.mods.api.IGui; import me.bionicbeanie.mods.api.IViewHandler; +import me.bionicbeanie.mods.model.PlayerPosition; import me.bionicbeanie.mods.api.IRootGridPanel; import me.bionicbeanie.mods.api.IScreenController; public class SaveCoordinatesGui extends LightweightGuiDescription implements IGui { private IRootGridPanel rootGridPanel; - private IViewHandler saveHandler; - private IViewHandler listHandler; + private IViewHandler defaultHandler; + private IViewHandler listHandler; private IScreenController screenController; @Override - public void init(IViewHandler saveHandler, IViewHandler listHandler, IScreenController screenController) { + public void init(IViewHandler saveHandler, IViewHandler listHandler, + IScreenController screenController) { this.rootGridPanel = createRootPanel(); - this.saveHandler = saveHandler; + this.defaultHandler = saveHandler; this.listHandler = listHandler; this.screenController = screenController; @@ -25,7 +27,12 @@ public class SaveCoordinatesGui extends LightweightGuiDescription implements IGu @Override public void showDefaultView() { - showView(saveHandler); + showView(defaultHandler); + } + + @Override + public void setDefaultViewState(PlayerPosition position) { + defaultHandler.setState(position); } @Override @@ -44,15 +51,16 @@ public class SaveCoordinatesGui extends LightweightGuiDescription implements IGu private IRootGridPanel createRootPanel() { RootGridPanel panel = new RootGridPanel(18); - panel.setSize(10 * 18, 10 * 18); + panel.setSize(15 * 18, 10 * 18); setRootPanel(panel); return panel; } - private void showView(IViewHandler handler) { + private void showView(IViewHandler handler) { rootGridPanel.reset(); handler.placeWidgets(rootGridPanel); rootGridPanel.validate(this); } + } diff --git a/src/main/java/me/bionicbeanie/mods/gui/view/DefaultViewHandler.java b/src/main/java/me/bionicbeanie/mods/gui/view/DefaultViewHandler.java index 8eacb06..82ce041 100644 --- a/src/main/java/me/bionicbeanie/mods/gui/view/DefaultViewHandler.java +++ b/src/main/java/me/bionicbeanie/mods/gui/view/DefaultViewHandler.java @@ -1,8 +1,5 @@ package me.bionicbeanie.mods.gui.view; -import java.io.IOException; -import java.util.UUID; - import io.github.cottonmc.cotton.gui.widget.WButton; import io.github.cottonmc.cotton.gui.widget.WLabel; import io.github.cottonmc.cotton.gui.widget.WText; @@ -18,7 +15,7 @@ import me.bionicbeanie.mods.util.DimensionSpriteUtil; import net.minecraft.client.MinecraftClient; import net.minecraft.text.LiteralText; -public class DefaultViewHandler extends ViewHandlerBase { +public class DefaultViewHandler extends ViewHandlerBase { private IPlayerLocator locator; @@ -28,37 +25,64 @@ public class DefaultViewHandler extends ViewHandlerBase { } @Override - public void placeWidgets(IRootGridPanel root) { + public void placeWidgets(IRootGridPanel root, PlayerPosition existingPosition) { - PlayerRawPosition rawPosition = locator.locate(client); + PlayerRawPosition rawPosition = existingPosition == null ? locator.locate(client) : existingPosition; + + WWidget xLabel = CreateLabelForCoorindate("X"); + WWidget yLabel = CreateLabelForCoorindate("Y"); + WWidget zLabel = CreateLabelForCoorindate("Z"); - WWidget xLabel= CreateLabelForCoorindate("X"); - WWidget yLabel= CreateLabelForCoorindate("Y"); - WWidget zLabel= CreateLabelForCoorindate("Z"); - WWidget xText = CreateWidgetForCoordinate(rawPosition.getX()); WWidget yText = CreateWidgetForCoordinate(rawPosition.getY()); WWidget zText = CreateWidgetForCoordinate(rawPosition.getZ()); - root.add(xLabel, 1, 1, 2, 1); - root.add(yLabel, 1, 2, 2, 1); - root.add(zLabel, 1, 3, 2, 1); - - root.add(xText, 2, 1, 2, 1); - root.add(yText, 2, 2, 2, 1); - root.add(zText, 2, 3, 2, 1); + root.add(xLabel, 2, 1, 2, 1); + root.add(yLabel, 2, 2, 2, 1); + root.add(zLabel, 2, 3, 2, 1); + + root.add(xText, 3, 1, 2, 1); + root.add(yText, 3, 2, 2, 1); + root.add(zText, 3, 3, 2, 1); WWidget icon = DimensionSpriteUtil.CreateWorldIcon(rawPosition.getWorldDimension()); - root.add(icon, 6, 1, 2, 2); + root.add(icon, 8, 1, 2, 2); - WTextField name = CreateNameField(); - root.add(name, 0, 6, 8, 1); + String defaultWorld = getDefaultWorld(existingPosition); + WTextField world = CreateWorldField(defaultWorld); + root.add(world, 0, 4, 4, 1); - WWidget save = CreateSaveButton(rawPosition, name); - root.add(save, 9, 6, 2, 1); + WTextField location = CreateLocationField(existingPosition); + root.add(location, 5, 4, 7, 1); + + WTextField notes = CreateNotesField(existingPosition); + root.add(notes, 0, 6, 12, 1); + + WWidget save = CreateSaveButton(rawPosition, location, notes, world, existingPosition); + root.add(save, 13, 6, 2, 1); WWidget list = CreateListButton(); - root.add(list, 9, 8, 2, 1); + root.add(list, 13, 9, 2, 1); + + WWidget ping = CreatePingButton(rawPosition); + root.add(ping, 13, 1, 2, 1); + + WWidget close = CreateCloseButton(); + root.add(close, 0, 9, 2, 1); + } + + private String getDefaultWorld(PlayerPosition existingPosition) { + if (existingPosition != null && existingPosition.getPositionMetadata().getWorldName() != null) { + return existingPosition.getPositionMetadata().getWorldName(); + } + + try { + return fileStore.getDefaultWorld(); + } catch (Exception e) { + e.printStackTrace(); + } + + return ""; } private WWidget CreateLabelForCoorindate(String label) { @@ -69,31 +93,57 @@ public class DefaultViewHandler extends ViewHandlerBase { return new WText(new LiteralText(String.valueOf(l)), 0x3939ac); } - private WTextField CreateNameField() { - return new WTextField(new LiteralText("location name")); + private WTextField CreateLocationField(PlayerPosition existingPosition) { + WTextField location = new WTextField(new LiteralText("location name")); + + if (existingPosition != null) { + location.setText(existingPosition.getLocationName()); + } + + location.setMaxLength(20); + + return location; } - private WWidget CreateSaveButton(PlayerRawPosition rawPosition, WTextField textField) { - WButton button = new WButton(new LiteralText("save")); - button.setOnClick(new Runnable() { - @Override - public void run() { - try { - String id = UUID.randomUUID().toString(); - fileStore.save(new PlayerPosition(id, rawPosition, textField.getText(), null)); - } catch (IOException e) { - e.printStackTrace(); - } + private WTextField CreateNotesField(PlayerPosition existingPosition) { + WTextField notes = new WTextField(new LiteralText("additional notes")); - gui.close(); - } - }); + if (existingPosition != null && existingPosition.getPositionMetadata() != null) { + notes.setText(existingPosition.getPositionMetadata().getNotes()); + } + + return notes; + } + + private WTextField CreateWorldField(String defaultWorld) { + WTextField world = new WTextField(new LiteralText("world name")); + world.setMaxLength(7); + world.setText(defaultWorld); + return world; + } + + private WWidget CreateSaveButton(PlayerRawPosition rawPosition, WTextField location, WTextField notes, + WTextField world, PlayerPosition existingPosition) { + WButton button = new WButton(new LiteralText("SAVE")); + button.setOnClick(new SaveOperation(fileStore, gui, rawPosition, world, location, notes, existingPosition)); return button; } private WWidget CreateListButton() { - WButton button = new WButton(new LiteralText("list")); + WButton button = new WButton(new LiteralText("LIST")); button.setOnClick(gui::showListView); return button; } + + private WWidget CreatePingButton(PlayerRawPosition rawPosition) { + WButton button = new WButton(new LiteralText("PING")); + button.setOnClick(new PingOperation(fileStore, gui, rawPosition)); + return button; + } + + private WWidget CreateCloseButton() { + WButton button = new WButton(new LiteralText("CLOSE")); + button.setOnClick(gui::close); + return button; + } } diff --git a/src/main/java/me/bionicbeanie/mods/gui/view/DeleteOperation.java b/src/main/java/me/bionicbeanie/mods/gui/view/DeleteOperation.java new file mode 100644 index 0000000..063e87d --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/gui/view/DeleteOperation.java @@ -0,0 +1,18 @@ +package me.bionicbeanie.mods.gui.view; + +import me.bionicbeanie.mods.api.IFileStore; +import me.bionicbeanie.mods.api.IGui; +import me.bionicbeanie.mods.model.PlayerPosition; + +public class DeleteOperation extends ViewPositionOperationBase { + + public DeleteOperation(IFileStore fileStore, IGui gui, PlayerPosition position) { + super(fileStore, gui, position); + } + + @Override + protected void executeOperation(IFileStore fileStore, IGui gui, PlayerPosition position) throws Exception { + fileStore.delete(position.getId()); + gui.showListView(); + } +} diff --git a/src/main/java/me/bionicbeanie/mods/gui/view/ListViewHandler.java b/src/main/java/me/bionicbeanie/mods/gui/view/ListViewHandler.java index 92c9f5d..36d8887 100644 --- a/src/main/java/me/bionicbeanie/mods/gui/view/ListViewHandler.java +++ b/src/main/java/me/bionicbeanie/mods/gui/view/ListViewHandler.java @@ -1,6 +1,7 @@ package me.bionicbeanie.mods.gui.view; import java.io.IOException; +import java.util.Collections; import java.util.List; import java.util.function.BiConsumer; @@ -18,34 +19,53 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.text.LiteralText; import net.minecraft.util.Identifier; -public class ListViewHandler extends ViewHandlerBase { +public class ListViewHandler extends ViewHandlerBase { public ListViewHandler(IFileStore fileStore, IGui gui, MinecraftClient client) { super(fileStore, gui, client); } @Override - public void placeWidgets(IRootGridPanel root) { + public void placeWidgets(IRootGridPanel root, Void nullState) { - BiConsumer configurator = (PlayerPosition position, - CoordinatesListItemPanel panel) -> { + List positions = getPositions(fileStore); + WListPanel listPanel = createListPane(positions); + + WButton backButton = createBackButton(); + + root.add(listPanel, 0, 0, 15, 9); + root.add(backButton, 0, 9, 2, 1); + } + + private WButton createBackButton() { + WButton backButton = new WButton(new LiteralText("BACK")); + backButton.setOnClick(gui::showDefaultView); + return backButton; + } + + private WListPanel createListPane(List positions) { + BiConsumer configurator = (position, panel) -> { panel.setPosition(position, fileStore, gui); }; - List positions; - try { - positions = fileStore.list(); - } catch (IOException e) { - e.printStackTrace(); - return; - } - - WListPanel listPanel = new WListPanel<>(positions, + WListPanel panel = new WListPanel<>(positions, CoordinatesListItemPanel::new, configurator); - listPanel.setListItemHeight(2 * 18); + panel.setListItemHeight(2 * 18); - root.add(listPanel, 0, 0, 11, 11); + return panel; + } + + private List getPositions(IFileStore fileStore) { + try { + List positions = fileStore.list(); + Collections.sort(positions, (p1, p2) -> p2.getPositionMetadata().getLastModified() + .compareTo(p1.getPositionMetadata().getLastModified())); + return positions; + } catch (IOException e) { + e.printStackTrace(); + return Collections.emptyList(); + } } public static class CoordinatesListItemPanel extends WPlainPanel { @@ -54,44 +74,49 @@ public class ListViewHandler extends ViewHandlerBase { private WLabel location; private WSprite icon; private WButton deleteButton; + private WButton pingButton; + private WButton detailButton; + private WLabel world; public CoordinatesListItemPanel() { this.coordinates = new WLabel("Foo"); this.location = new WLabel("Foo"); + this.world = new WLabel("Foo"); this.icon = new WSprite(new Identifier("minecraft:textures/item/ender_eye.png")); this.deleteButton = new WButton(new LiteralText("x")); + this.pingButton = new WButton(new LiteralText("!")); + this.detailButton = new WButton(new LiteralText("+")); this.add(icon, 0, 0, 1 * 9, 1 * 9); - this.add(location, 1 * 18, 0, 4 * 18, 1 * 18); + this.add(world, 1 * 18, 0, 3 * 18, 1 * 18); + this.add(location, 4 * 18, 0, 4 * 18, 1 * 18); this.add(coordinates, 1 * 18, 1 * 18, 9 * 18, 1 * 18); - this.add(deleteButton, 9 * 18, 0, 1 * 18, 1 * 18); + this.add(deleteButton, 13 * 18, 0, 1 * 18, 1 * 18); + this.add(pingButton, 12 * 18, 0, 1 * 18, 1 * 18); + this.add(detailButton, 11 * 18, 0, 1 * 18, 1 * 18); this.icon.setSize(1 * 15, 1 * 15); + this.world.setSize(3 * 18, 1 * 18); this.location.setSize(9 * 18, 1 * 18); this.coordinates.setSize(2 * 18, 9 * 18); this.deleteButton.setSize(1 * 18, 1 * 18); - this.setSize(9 * 18, 2 * 18); + this.pingButton.setSize(1 * 18, 1 * 18); + this.detailButton.setSize(1 * 18, 1 * 18); + + this.setSize(15 * 18, 2 * 18); } public void setPosition(PlayerPosition position, IFileStore fileStore, IGui gui) { this.icon.setImage(DimensionSpriteUtil.CreateWorldIconIdentifier(position.getWorldDimension())); this.location.setText(new LiteralText(position.getLocationName())); this.location.setColor(0x3939ac); + this.world.setText(new LiteralText("[" + position.getPositionMetadata().getWorldName() + "]")); + this.world.setColor(0xb80000); this.coordinates .setText(new LiteralText(position.getX() + ", " + position.getY() + ", " + position.getZ())); - this.deleteButton.setOnClick(new Runnable() { - - @Override - public void run() { - try { - fileStore.delete(position.getId()); - gui.showListView(); - } catch (IOException e) { - e.printStackTrace(); - } - } - }); + this.deleteButton.setOnClick(new DeleteOperation(fileStore, gui, position)); + this.pingButton.setOnClick(new PingOperation(fileStore, gui, position)); + this.detailButton.setOnClick(new ShowDetailOperation(fileStore, gui, position)); } } - } diff --git a/src/main/java/me/bionicbeanie/mods/gui/view/PingOperation.java b/src/main/java/me/bionicbeanie/mods/gui/view/PingOperation.java new file mode 100644 index 0000000..0c69121 --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/gui/view/PingOperation.java @@ -0,0 +1,23 @@ +package me.bionicbeanie.mods.gui.view; + +import me.bionicbeanie.mods.api.IFileStore; +import me.bionicbeanie.mods.api.IGui; +import me.bionicbeanie.mods.model.PlayerRawPosition; +import net.minecraft.client.MinecraftClient; + +public class PingOperation extends ViewOperationBase{ + + private PlayerRawPosition position; + + public PingOperation(IFileStore fileStore, IGui gui, PlayerRawPosition position) { + super(fileStore, gui); + + this.position = position; + } + + @SuppressWarnings("resource") + @Override + protected void executeOperation(IFileStore fileStore, IGui gui) throws Exception { + MinecraftClient.getInstance().player.sendChatMessage(position.toString()); + } +} diff --git a/src/main/java/me/bionicbeanie/mods/gui/view/SaveOperation.java b/src/main/java/me/bionicbeanie/mods/gui/view/SaveOperation.java new file mode 100644 index 0000000..961b35d --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/gui/view/SaveOperation.java @@ -0,0 +1,54 @@ +package me.bionicbeanie.mods.gui.view; + +import java.util.UUID; + +import io.github.cottonmc.cotton.gui.widget.WTextField; +import me.bionicbeanie.mods.api.IFileStore; +import me.bionicbeanie.mods.api.IGui; +import me.bionicbeanie.mods.model.PlayerPosition; +import me.bionicbeanie.mods.model.PlayerRawPosition; +import me.bionicbeanie.mods.model.PositionMetadata; + +public class SaveOperation extends ViewOperationBase { + + private PlayerRawPosition rawPosition; + private WTextField location, notes; + private WTextField world; + private PlayerPosition existingPosition; + + public SaveOperation(IFileStore fileStore, IGui gui, PlayerRawPosition rawPosition, WTextField world, + WTextField location, WTextField notes, PlayerPosition existingPosition) { + super(fileStore, gui); + this.rawPosition = rawPosition; + this.existingPosition = existingPosition; + this.world = world; + this.location = location; + this.notes = notes; + } + + @Override + protected void executeOperation(IFileStore fileStore, IGui gui) throws Exception { + + String id = existingPosition == null ? UUID.randomUUID().toString() : existingPosition.getId(); + PositionMetadata metadata = CreateMetadata(existingPosition); + + PlayerPosition position = new PlayerPosition(id, rawPosition, this.location.getText(), metadata); + + fileStore.save(position); + fileStore.setDefaultWorld(position.getPositionMetadata().getWorldName()); + gui.showListView(); + gui.setDefaultViewState(null); + } + + private PositionMetadata CreateMetadata(PlayerPosition existingPosition) { + if(existingPosition == null) { + return new PositionMetadata(this.world.getText(), this.notes.getText()); + } + + existingPosition.getPositionMetadata().setWorldName(this.world.getText()); + existingPosition.getPositionMetadata().setNotes(this.notes.getText()); + existingPosition.getPositionMetadata().updateLastModified(); + + return existingPosition.getPositionMetadata(); + } +} diff --git a/src/main/java/me/bionicbeanie/mods/gui/view/ShowDetailOperation.java b/src/main/java/me/bionicbeanie/mods/gui/view/ShowDetailOperation.java new file mode 100644 index 0000000..eb62b8e --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/gui/view/ShowDetailOperation.java @@ -0,0 +1,19 @@ +package me.bionicbeanie.mods.gui.view; + +import me.bionicbeanie.mods.api.IFileStore; +import me.bionicbeanie.mods.api.IGui; +import me.bionicbeanie.mods.model.PlayerPosition; + +public class ShowDetailOperation extends ViewPositionOperationBase { + + public ShowDetailOperation(IFileStore fileStore, IGui gui, PlayerPosition position) { + super(fileStore, gui, position); + } + + @Override + protected void executeOperation(IFileStore fileStore, IGui gui, PlayerPosition position) throws Exception { + gui.setDefaultViewState(position); + gui.showDefaultView(); + } + +} diff --git a/src/main/java/me/bionicbeanie/mods/gui/view/ViewHandlerBase.java b/src/main/java/me/bionicbeanie/mods/gui/view/ViewHandlerBase.java index f96a3ae..89542fd 100644 --- a/src/main/java/me/bionicbeanie/mods/gui/view/ViewHandlerBase.java +++ b/src/main/java/me/bionicbeanie/mods/gui/view/ViewHandlerBase.java @@ -3,15 +3,17 @@ package me.bionicbeanie.mods.gui.view; import io.github.cottonmc.cotton.gui.widget.WWidget; import me.bionicbeanie.mods.api.IFileStore; import me.bionicbeanie.mods.api.IGui; +import me.bionicbeanie.mods.api.IRootGridPanel; import me.bionicbeanie.mods.api.IViewHandler; import net.minecraft.client.MinecraftClient; -public abstract class ViewHandlerBase implements IViewHandler { +public abstract class ViewHandlerBase implements IViewHandler { protected IFileStore fileStore; protected IGui gui; protected MinecraftClient client; protected WWidget panel; + private T state; protected ViewHandlerBase(IFileStore fileStore, IGui gui, MinecraftClient client) { this.fileStore = fileStore; @@ -19,4 +21,21 @@ public abstract class ViewHandlerBase implements IViewHandler { this.client = client; } + protected abstract void placeWidgets(IRootGridPanel rootPanel, T state); + + @Override + public void clearState() { + state = null; + } + + @Override + public void setState(T state) { + this.state = state; + } + + @Override + public void placeWidgets(IRootGridPanel rootPanel) { + placeWidgets(rootPanel, state); + } + } diff --git a/src/main/java/me/bionicbeanie/mods/gui/view/ViewOperationBase.java b/src/main/java/me/bionicbeanie/mods/gui/view/ViewOperationBase.java new file mode 100644 index 0000000..676645e --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/gui/view/ViewOperationBase.java @@ -0,0 +1,26 @@ +package me.bionicbeanie.mods.gui.view; + +import me.bionicbeanie.mods.api.IFileStore; +import me.bionicbeanie.mods.api.IGui; + +public abstract class ViewOperationBase implements Runnable { + + private IFileStore fileStore; + private IGui gui; + + public ViewOperationBase(IFileStore fileStore, IGui gui) { + this.fileStore = fileStore; + this.gui = gui; + } + + @Override + public void run() { + try { + executeOperation(fileStore, gui); + } catch (Exception e) { + e.printStackTrace(); + } + } + + protected abstract void executeOperation(IFileStore fileStore, IGui gui) throws Exception; +} diff --git a/src/main/java/me/bionicbeanie/mods/gui/view/ViewPositionOperationBase.java b/src/main/java/me/bionicbeanie/mods/gui/view/ViewPositionOperationBase.java new file mode 100644 index 0000000..23c64d5 --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/gui/view/ViewPositionOperationBase.java @@ -0,0 +1,22 @@ +package me.bionicbeanie.mods.gui.view; + +import me.bionicbeanie.mods.api.IFileStore; +import me.bionicbeanie.mods.api.IGui; +import me.bionicbeanie.mods.model.PlayerPosition; + +public abstract class ViewPositionOperationBase extends ViewOperationBase{ + + private PlayerPosition position; + + public ViewPositionOperationBase(IFileStore fileStore, IGui gui, PlayerPosition position) { + super(fileStore, gui); + this.position = position; + } + + @Override + protected void executeOperation(IFileStore fileStore, IGui gui) throws Exception { + executeOperation(fileStore, gui, position); + } + + protected abstract void executeOperation(IFileStore fileStore, IGui gui, PlayerPosition position) throws Exception; +} diff --git a/src/main/java/me/bionicbeanie/mods/impl/FileStore.java b/src/main/java/me/bionicbeanie/mods/impl/FileStore.java index 7d0541c..aeb6eee 100644 --- a/src/main/java/me/bionicbeanie/mods/impl/FileStore.java +++ b/src/main/java/me/bionicbeanie/mods/impl/FileStore.java @@ -15,6 +15,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import me.bionicbeanie.mods.api.IFileStore; +import me.bionicbeanie.mods.model.ModData; import me.bionicbeanie.mods.model.PlayerPosition; public class FileStore implements IFileStore { @@ -26,12 +27,9 @@ public class FileStore implements IFileStore { private Gson gson; public FileStore(String baseDir) { - this.gson = new GsonBuilder() - .setPrettyPrinting() - .setLenient() - .create(); + this.gson = new GsonBuilder().setPrettyPrinting().setLenient().create(); this.saveFilePath = Paths.get(baseDir, DEFAULT_DIR, DEFAULT_FILE); - + try { Files.createDirectories(Paths.get(baseDir, DEFAULT_DIR)); Files.createFile(this.saveFilePath); @@ -43,15 +41,28 @@ public class FileStore implements IFileStore { } @Override - public List list() throws IOException { - List lines = Files.readAllLines(saveFilePath); - PlayerPosition[] positions = gson.fromJson(String.join("", lines), PlayerPosition[].class); + public String getDefaultWorld() throws IOException { + ModData data = load(); + + return data.defaultWorldName; + } + @Override + public void setDefaultWorld(String defaultWorldName) throws IOException { + ModData data = load(); + data.defaultWorldName = defaultWorldName; + + dump(data); + } + + @Override + public List list() throws IOException { + ModData data = load(); List playerPositionList = new LinkedList<>(); - if (positions != null) { - for (int i = 0; i < positions.length; ++i) { - playerPositionList.add(positions[i]); + if (data.positions != null) { + for (int i = 0; i < data.positions.length; ++i) { + playerPositionList.add(data.positions[i]); } } @@ -60,25 +71,45 @@ public class FileStore implements IFileStore { @Override public void save(PlayerPosition position) throws IOException { - List playerPositions = list(); + playerPositions.removeIf(p -> StringUtils.equalsIgnoreCase(position.getId(), p.getId())); playerPositions.add(position); - saveAll(playerPositions); + savePositions(playerPositions); } @Override public void delete(String id) throws IOException { - List playerPositions = list(); playerPositions.removeIf(p -> StringUtils.equalsIgnoreCase(id, p.getId())); - - saveAll(playerPositions); + savePositions(playerPositions); } - private void saveAll(List playerPositions) throws IOException { - String serialized = gson.toJson(playerPositions.toArray()); + private void dump(ModData data) throws IOException { + String serialized = gson.toJson(data); Files.write(saveFilePath, serialized.getBytes(), StandardOpenOption.TRUNCATE_EXISTING); } + private void savePositions(List playerPositions) throws IOException { + ModData data = load(); + data.positions = playerPositions.toArray(new PlayerPosition[playerPositions.size()]); + dump(data); + } + + private ModData load() throws IOException { + List lines = Files.readAllLines(saveFilePath); + try { + return gson.fromJson(String.join("", lines), ModData.class); + } catch (Exception e) { + // Fallback for old versions + ModData data = new ModData(); + data.defaultWorldName = ""; + data.positions = gson.fromJson(String.join("", lines), PlayerPosition[].class); + + dump(data); + + return data; + } + } + } diff --git a/src/main/java/me/bionicbeanie/mods/model/ModData.java b/src/main/java/me/bionicbeanie/mods/model/ModData.java new file mode 100644 index 0000000..144c016 --- /dev/null +++ b/src/main/java/me/bionicbeanie/mods/model/ModData.java @@ -0,0 +1,8 @@ +package me.bionicbeanie.mods.model; + +public class ModData { + + public String defaultWorldName; + + public PlayerPosition[] positions; +} diff --git a/src/main/java/me/bionicbeanie/mods/model/PlayerPosition.java b/src/main/java/me/bionicbeanie/mods/model/PlayerPosition.java index 2d1876a..0b98386 100644 --- a/src/main/java/me/bionicbeanie/mods/model/PlayerPosition.java +++ b/src/main/java/me/bionicbeanie/mods/model/PlayerPosition.java @@ -1,35 +1,18 @@ package me.bionicbeanie.mods.model; -public class PlayerPosition { +public class PlayerPosition extends PlayerRawPosition { - private PlayerRawPosition rawPosition; private String id, locationName; private PositionMetadata positionMetadata; public PlayerPosition(String id, PlayerRawPosition rawPosition, String locationName, PositionMetadata positionMetadata) { + super(rawPosition.getX(), rawPosition.getY(), rawPosition.getZ(), rawPosition.getWorldDimension()); this.id = id; - this.rawPosition = rawPosition; this.positionMetadata = positionMetadata; this.locationName = locationName; } - public long getX() { - return rawPosition.getX(); - } - - public long getY() { - return rawPosition.getY(); - } - - public long getZ() { - return rawPosition.getZ(); - } - - public String getWorldDimension() { - return rawPosition.getWorldDimension(); - } - public String getLocationName() { return locationName; } @@ -41,4 +24,10 @@ public class PlayerPosition { public String getId() { return id; } + + @Override + public String toString() { + return this.locationName + " in [ " + this.getWorldDimension() + " ] at [ " + this.getX() + ", " + this.getY() + + ", " + this.getZ() + " ]"; + } } diff --git a/src/main/java/me/bionicbeanie/mods/model/PlayerRawPosition.java b/src/main/java/me/bionicbeanie/mods/model/PlayerRawPosition.java index ea2eaa3..5b896d9 100644 --- a/src/main/java/me/bionicbeanie/mods/model/PlayerRawPosition.java +++ b/src/main/java/me/bionicbeanie/mods/model/PlayerRawPosition.java @@ -27,4 +27,9 @@ public class PlayerRawPosition { return worldDimension; } + @Override + public String toString() { + return "I'm in [ " + worldDimension + " ] at [ " + x + ", " + y + ", " + z + " ]"; + } + } diff --git a/src/main/java/me/bionicbeanie/mods/model/PositionMetadata.java b/src/main/java/me/bionicbeanie/mods/model/PositionMetadata.java index 000949b..110b3c4 100644 --- a/src/main/java/me/bionicbeanie/mods/model/PositionMetadata.java +++ b/src/main/java/me/bionicbeanie/mods/model/PositionMetadata.java @@ -1,25 +1,44 @@ package me.bionicbeanie.mods.model; -import java.util.Date; +import java.time.LocalDateTime; public class PositionMetadata { private String worldName, notes; - private Date created, lastModified; - + private LocalDateTime created, lastModified; + + public PositionMetadata(String worldName, String notes) { + this.worldName = worldName; + this.notes = notes; + this.created = LocalDateTime.now(); + this.lastModified = this.created; + } + public String getWorldName() { return worldName; } - + + public void setWorldName(String worldName) { + this.worldName = worldName; + } + public String getNotes() { return notes; } - - public Date getCreated() { + + public void setNotes(String notes) { + this.notes = notes; + } + + public LocalDateTime getCreated() { return created; } - - public Date getLastModified() { + + public LocalDateTime getLastModified() { return lastModified; } + + public void updateLastModified() { + this.lastModified = LocalDateTime.now(); + } } diff --git a/src/main/java/me/bionicbeanie/mods/util/DimensionSpriteUtil.java b/src/main/java/me/bionicbeanie/mods/util/DimensionSpriteUtil.java index e4a270c..56c2138 100644 --- a/src/main/java/me/bionicbeanie/mods/util/DimensionSpriteUtil.java +++ b/src/main/java/me/bionicbeanie/mods/util/DimensionSpriteUtil.java @@ -13,7 +13,10 @@ public class DimensionSpriteUtil { public static Identifier CreateWorldIconIdentifier(String dimension) { String dimensionItem = "netherite_ingot"; - if (dimension.contains("overworld")) { + if(dimension == null) { + dimensionItem = "barrier"; + } + else if (dimension.contains("overworld")) { dimensionItem = "totem_of_undying"; } else if (dimension.contains("end")) { dimensionItem = "ender_eye";