diff --git a/src/main/java/nl/andrewlalis/crystalkeep/CrystalKeep.java b/src/main/java/nl/andrewlalis/crystalkeep/CrystalKeep.java index 8e63300..7431a08 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/CrystalKeep.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/CrystalKeep.java @@ -4,8 +4,11 @@ import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.stage.Stage; +import nl.andrewlalis.crystalkeep.control.MainViewController; import nl.andrewlalis.crystalkeep.model.Cluster; +import nl.andrewlalis.crystalkeep.model.Model; import nl.andrewlalis.crystalkeep.model.Shard; +import nl.andrewlalis.crystalkeep.model.serialization.ClusterLoader; import nl.andrewlalis.crystalkeep.model.serialization.ClusterSerializer; import nl.andrewlalis.crystalkeep.model.shards.LoginCredentialsShard; import nl.andrewlalis.crystalkeep.model.shards.TextShard; @@ -17,7 +20,7 @@ import java.time.LocalDateTime; import java.util.Arrays; public class CrystalKeep extends Application { - public static void main(String[] args) throws IOException { + public static void main(String[] args) { launch(args); } @@ -25,10 +28,28 @@ public class CrystalKeep extends Application { public void start(Stage stage) throws Exception { URL url = CrystalKeep.class.getClassLoader().getResource("ui/crystalkeep.fxml"); FXMLLoader loader = new FXMLLoader(url); + Model model = new Model(); + loader.setController(new MainViewController(model)); var scene = new Scene(loader.load()); stage.setScene(scene); stage.setTitle("CrystalKeep"); stage.sizeToScene(); + + ClusterLoader clusterLoader = new ClusterLoader(); + Cluster rootCluster; + try { + rootCluster = clusterLoader.loadDefault(); + System.out.println("Loaded existing root cluster."); + } catch (IOException e) { + rootCluster = new Cluster("Root"); + rootCluster.addShard(new TextShard(rootCluster, "Example Shard", LocalDateTime.now(), "Hello world!")); + clusterLoader.saveDefault(rootCluster); + System.out.println("Saved root cluster on first load."); + } + + model.setActiveCluster(rootCluster); + System.out.println(rootCluster); + stage.show(); } diff --git a/src/main/java/nl/andrewlalis/crystalkeep/control/ClusterTreeViewController.java b/src/main/java/nl/andrewlalis/crystalkeep/control/ClusterTreeViewController.java new file mode 100644 index 0000000..0b53e57 --- /dev/null +++ b/src/main/java/nl/andrewlalis/crystalkeep/control/ClusterTreeViewController.java @@ -0,0 +1,9 @@ +package nl.andrewlalis.crystalkeep.control; + +import javafx.fxml.FXML; +import javafx.scene.control.TreeView; + +public class ClusterTreeViewController { + @FXML + TreeView clusterTreeView; +} diff --git a/src/main/java/nl/andrewlalis/crystalkeep/control/MainViewController.java b/src/main/java/nl/andrewlalis/crystalkeep/control/MainViewController.java new file mode 100644 index 0000000..75de4d2 --- /dev/null +++ b/src/main/java/nl/andrewlalis/crystalkeep/control/MainViewController.java @@ -0,0 +1,26 @@ +package nl.andrewlalis.crystalkeep.control; + +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import nl.andrewlalis.crystalkeep.model.Model; +import nl.andrewlalis.crystalkeep.model.serialization.ClusterLoader; + +import java.io.IOException; + +public class MainViewController { + private final Model model; + + public MainViewController(Model model) { + this.model = model; + } + + @FXML + public void exit(ActionEvent event) { + System.out.println("Exiting..."); + try { + new ClusterLoader().saveDefault(model.getActiveCluster()); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/nl/andrewlalis/crystalkeep/control/ShardDetailController.java b/src/main/java/nl/andrewlalis/crystalkeep/control/ShardDetailController.java new file mode 100644 index 0000000..06f9cab --- /dev/null +++ b/src/main/java/nl/andrewlalis/crystalkeep/control/ShardDetailController.java @@ -0,0 +1,4 @@ +package nl.andrewlalis.crystalkeep.control; + +public class ShardDetailController { +} diff --git a/src/main/java/nl/andrewlalis/crystalkeep/model/Model.java b/src/main/java/nl/andrewlalis/crystalkeep/model/Model.java new file mode 100644 index 0000000..29a009a --- /dev/null +++ b/src/main/java/nl/andrewlalis/crystalkeep/model/Model.java @@ -0,0 +1,12 @@ +package nl.andrewlalis.crystalkeep.model; + +import lombok.Getter; + +@Getter +public class Model { + private Cluster activeCluster; + + public void setActiveCluster(Cluster activeCluster) { + this.activeCluster = activeCluster; + } +} diff --git a/src/main/java/nl/andrewlalis/crystalkeep/model/serialization/ClusterLoader.java b/src/main/java/nl/andrewlalis/crystalkeep/model/serialization/ClusterLoader.java new file mode 100644 index 0000000..4f5e55f --- /dev/null +++ b/src/main/java/nl/andrewlalis/crystalkeep/model/serialization/ClusterLoader.java @@ -0,0 +1,25 @@ +package nl.andrewlalis.crystalkeep.model.serialization; + +import nl.andrewlalis.crystalkeep.model.Cluster; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +public class ClusterLoader { + private static final Path CLUSTER_PATH = Path.of("clusters"); + private static final Path DEFAULT_CLUSTER = CLUSTER_PATH.resolve("default.cts"); + + public Cluster loadDefault() throws IOException { + InputStream is = new FileInputStream(DEFAULT_CLUSTER.toFile()); + return ClusterSerializer.clusterFromBytes(is, null); + } + + public void saveDefault(Cluster cluster) throws IOException { + Files.createDirectories(CLUSTER_PATH); + byte[] bytes = ClusterSerializer.toBytes(cluster); + Files.write(DEFAULT_CLUSTER, bytes); + } +} diff --git a/src/main/java/nl/andrewlalis/crystalkeep/model/serialization/ClusterSerializer.java b/src/main/java/nl/andrewlalis/crystalkeep/model/serialization/ClusterSerializer.java index 3c53750..fc89090 100644 --- a/src/main/java/nl/andrewlalis/crystalkeep/model/serialization/ClusterSerializer.java +++ b/src/main/java/nl/andrewlalis/crystalkeep/model/serialization/ClusterSerializer.java @@ -19,6 +19,10 @@ import java.util.Map; import static nl.andrewlalis.crystalkeep.model.serialization.ByteUtils.toInt; +/** + * This serializer class offers some methods for reading and writing clusters + * from and to byte arrays. + */ public class ClusterSerializer { private static final Map> serializers = new HashMap<>(); static { @@ -29,6 +33,7 @@ public class ClusterSerializer { /** * Serializes a cluster to a byte array, including all shards and nested * clusters. + * TODO: Use output stream instead of byte array. * @param cluster The cluster to serialize. * @return The byte array representing the cluster. * @throws IOException If an error occurs while writing the cluster. diff --git a/src/main/resources/ui/clusters_view.fxml b/src/main/resources/ui/clusters_view.fxml new file mode 100644 index 0000000..93bb4c6 --- /dev/null +++ b/src/main/resources/ui/clusters_view.fxml @@ -0,0 +1,18 @@ + + + + + + + + + +
+ +
+
diff --git a/src/main/resources/ui/crystalkeep.fxml b/src/main/resources/ui/crystalkeep.fxml index 39352a8..8cdbdea 100644 --- a/src/main/resources/ui/crystalkeep.fxml +++ b/src/main/resources/ui/crystalkeep.fxml @@ -1,10 +1,25 @@ - - + + + + + + + + + + + + + + + + + +
+ +
+
+
- - - - - diff --git a/src/main/resources/ui/shard_detail.fxml b/src/main/resources/ui/shard_detail.fxml new file mode 100644 index 0000000..787ff62 --- /dev/null +++ b/src/main/resources/ui/shard_detail.fxml @@ -0,0 +1,9 @@ + + + + + +