From 49a34e77aba33849b8f7296103f2b1e9b0568dfb Mon Sep 17 00:00:00 2001 From: bryce Date: Sun, 1 Dec 2024 15:41:56 +1300 Subject: [PATCH] Aperance Modifycation of the Client sorting out the 'Dashboard' and SettingsWindow creation of Kitset & MoC pages and BuildView model --- .../com/example/bricklog/model/Build.java | 45 ++++++ .../example/bricklog/view/GalleryLayout.java | 88 ++++++----- .../com/example/bricklog/view/KitsetPage.java | 14 ++ .../com/example/bricklog/view/MainLayout.java | 137 ++---------------- .../com/example/bricklog/view/MocPage.java | 14 ++ .../example/bricklog/view/SettingsWindow.java | 44 +++++- .../src/main/java/css/dark-theme.css | 19 +++ BrickLog-Client/src/main/java/css/gallery.css | 22 +++ .../com/example/bricklog/model/Build.class | Bin 0 -> 1288 bytes .../example/bricklog/view/GalleryLayout.class | Bin 5209 -> 6346 bytes .../example/bricklog/view/KitsetPage.class | Bin 0 -> 963 bytes .../example/bricklog/view/MainLayout.class | Bin 6321 -> 2159 bytes .../com/example/bricklog/view/MocPage.class | Bin 0 -> 951 bytes .../bricklog/view/SettingsWindow.class | Bin 5290 -> 5694 bytes .../target/classes/css/dark-theme.css | 19 +++ .../target/classes/css/gallery.css | 22 +++ 16 files changed, 251 insertions(+), 173 deletions(-) create mode 100644 BrickLog-Client/src/main/java/com/example/bricklog/model/Build.java create mode 100644 BrickLog-Client/src/main/java/com/example/bricklog/view/KitsetPage.java create mode 100644 BrickLog-Client/src/main/java/com/example/bricklog/view/MocPage.java create mode 100644 BrickLog-Client/src/main/java/css/gallery.css create mode 100644 BrickLog-Client/target/classes/com/example/bricklog/model/Build.class create mode 100644 BrickLog-Client/target/classes/com/example/bricklog/view/KitsetPage.class create mode 100644 BrickLog-Client/target/classes/com/example/bricklog/view/MocPage.class create mode 100644 BrickLog-Client/target/classes/css/gallery.css diff --git a/BrickLog-Client/src/main/java/com/example/bricklog/model/Build.java b/BrickLog-Client/src/main/java/com/example/bricklog/model/Build.java new file mode 100644 index 0000000..eb5609b --- /dev/null +++ b/BrickLog-Client/src/main/java/com/example/bricklog/model/Build.java @@ -0,0 +1,45 @@ +package com.example.bricklog.model; + +public class Build { + private String name; + private String imageUrl; + private String type; // "Kitset" or "MoC" + + // Constructor + public Build(String name, String imageUrl, String type) { + this.name = name; + this.imageUrl = imageUrl; + this.type = type; + } + + // Getters and setters + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + // Override toString for display purposes + @Override + public String toString() { + return String.format("Build{name='%s', type='%s', imageUrl='%s'}", name, type, imageUrl); + } +} diff --git a/BrickLog-Client/src/main/java/com/example/bricklog/view/GalleryLayout.java b/BrickLog-Client/src/main/java/com/example/bricklog/view/GalleryLayout.java index f7956f4..0da223f 100644 --- a/BrickLog-Client/src/main/java/com/example/bricklog/view/GalleryLayout.java +++ b/BrickLog-Client/src/main/java/com/example/bricklog/view/GalleryLayout.java @@ -1,5 +1,6 @@ package com.example.bricklog.view; +import com.example.bricklog.model.Build; import javafx.geometry.Insets; import javafx.scene.control.Label; import javafx.scene.control.ListView; @@ -12,23 +13,23 @@ import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; +import java.util.ArrayList; +import java.util.List; + public class GalleryLayout extends BorderPane { private final GridPane gridView; private final ListView listView; private boolean isGridView; public GalleryLayout() { - // Create a ToggleGroup for the layout options ToggleGroup toggleGroup = new ToggleGroup(); - // Create toggle buttons for layout options ToggleButton gridButton = new ToggleButton("Grid"); ToggleButton listButton = new ToggleButton("List"); - + gridButton.setToggleGroup(toggleGroup); listButton.setToggleGroup(toggleGroup); - - // Set the default selected button + gridButton.setSelected(true); isGridView = true; @@ -37,24 +38,18 @@ public class GalleryLayout extends BorderPane { toggleBox.setPadding(new Insets(10)); this.setTop(toggleBox); - // Create both views gridView = createGridView(); listView = createListView(); - // Start with the grid view isGridView = true; this.setCenter(gridView); - // Add listener to the toggle group to switch layouts - toggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> { - if (newValue == gridButton) { - isGridView = true; // Update the variable - toggleLayout(isGridView); // Use the variable - } else if (newValue == listButton) { - isGridView = false; // Update the variable - toggleLayout(isGridView); // Use the variable - } - }); + toggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> { + isGridView = newValue == gridButton; + toggleLayout(isGridView); + }); + + this.getStylesheets().add(getClass().getResource("/css/gallery.css").toExternalForm()); } private GridPane createGridView() { @@ -63,51 +58,50 @@ public class GalleryLayout extends BorderPane { grid.setHgap(10); grid.setVgap(10); - // Example data - replace with your actual data retrieval logic - String[] buildTypes = {"Kitset", "MoC", "Kitset", "MoC"}; - String[] imageUrls = { - "path/to/image1.jpg", - "path/to/image2.jpg", - "path/to/image3.jpg", - "path/to/image4.jpg" - }; + List builds = loadData(); + + for (int i = 0; i < builds.size(); i++) { + Build build = builds.get(i); - for (int i = 0; i < buildTypes.length; i++) { VBox vbox = new VBox(); - ImageView imageView = new ImageView(new Image(imageUrls[i])); + ImageView imageView = new ImageView(); + try { + imageView.setImage(new Image(build.getImageUrl())); + } catch (Exception e) { + imageView.setImage(new Image("path/to/placeholder.jpg")); + } + imageView.setFitWidth(150); imageView.setFitHeight(150); imageView.setPreserveRatio(true); - vbox.getChildren().addAll(imageView, new Label(buildTypes[i])); - grid.add(vbox, i % 3, i / 3); // Adjust to layout items in a grid + vbox.getChildren().addAll(imageView, new Label(build.getType())); + grid.add(vbox, i % 3, i / 3); } return grid; } private ListView createListView() { ListView list = new ListView<>(); - - // Example data - replace with your actual data retrieval logic - String[] details = { - "Build 1: Builder Name, 100 Pieces, 20x30x10 cm, Kitset", - "Build 2: Builder Name, 150 Pieces, 25x35x15 cm, MoC", - // Add more entries as needed... - }; + List builds = loadData(); - list.getItems().addAll(details); + for (Build build : builds) { + list.getItems().add(String.format( + "Name: %s, Type: %s, Image: %s", + build.getName(), build.getType(), build.getImageUrl() + )); + } return list; } -// Method to toggle layout and print the current state -private void toggleLayout(boolean isGrid) { - if (isGrid) { - System.out.println("Current layout: Grid View"); - this.setCenter(gridView); - } else { - System.out.println("Current layout: List View"); - this.setCenter(listView); + private List loadData() { + List builds = new ArrayList<>(); + builds.add(new Build("Build 1", "path/to/image1.jpg", "Kitset")); + builds.add(new Build("Build 2", "path/to/image2.jpg", "MoC")); + return builds; + } + + private void toggleLayout(boolean isGrid) { + this.setCenter(isGrid ? gridView : listView); } } -} - diff --git a/BrickLog-Client/src/main/java/com/example/bricklog/view/KitsetPage.java b/BrickLog-Client/src/main/java/com/example/bricklog/view/KitsetPage.java new file mode 100644 index 0000000..dde91ed --- /dev/null +++ b/BrickLog-Client/src/main/java/com/example/bricklog/view/KitsetPage.java @@ -0,0 +1,14 @@ +package com.example.bricklog.view; + +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.layout.VBox; + +public class KitsetPage extends VBox { + public KitsetPage() { + TableView table = new TableView<>(); + TableColumn column = new TableColumn<>("Kitset Name"); + table.getColumns().add(column); + getChildren().add(table); + } +} diff --git a/BrickLog-Client/src/main/java/com/example/bricklog/view/MainLayout.java b/BrickLog-Client/src/main/java/com/example/bricklog/view/MainLayout.java index 0df9e16..eae820f 100644 --- a/BrickLog-Client/src/main/java/com/example/bricklog/view/MainLayout.java +++ b/BrickLog-Client/src/main/java/com/example/bricklog/view/MainLayout.java @@ -1,137 +1,32 @@ package com.example.bricklog.view; -import javafx.geometry.Insets; -import javafx.geometry.Pos; import javafx.scene.control.Button; -import javafx.scene.control.ButtonType; -import javafx.scene.control.Dialog; import javafx.scene.control.Label; -import javafx.scene.control.TextField; import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; -import javafx.scene.layout.VBox; -// import javafx.scene.layout.StackPane; public class MainLayout extends BorderPane { - private VBox menu; // makes menu accessible for updates - public MainLayout() { - - // Title & Coppyright - Label title = new Label("BRICK LOG Client"); - title.setStyle("-fx-font-size: 24px; -fx-font-weight: bold;"); - - Label copyright = new Label("built by Bryce © 2024"); - copyright.setStyle("-fx-font-size: 14px;"); - - VBox titleBox = new VBox(title, copyright); - titleBox.setAlignment(Pos.CENTER); - titleBox.setPadding(new Insets(10)); - - // Set title at the top - VBox topContainer = new VBox(titleBox); - this.setTop(topContainer); - - menu = new VBox(); - menu.setSpacing(10); - menu.setPadding(new Insets(10)); - menu.setStyle("-fx-background-color: #f0f0f0;"); // Optional: Background color for the menu - - // Search Bar - TextField searchField = new TextField(); - searchField.setPromptText("Search..."); - - // Set up the menu - menu = new VBox(); - menu.setSpacing(10); - menu.setPadding(new Insets(10)); - menu.setStyle("-fx-background-color: #f0f0f0;"); // Optional: Background color for the menu - - // Add the Gallery menu item - Label galleryLabel = new Label("Gallery"); - galleryLabel.setStyle("-fx-font-weight: bold; cursor: hand;"); // Make it look interactive - galleryLabel.setOnMouseClicked(event -> switchToGalleryLayout()); // Switch layout on click - - Label settingsLabel = new Label("Settings"); - settingsLabel.setStyle("-fx-font-weight: bold; cursor: hand;"); - settingsLabel.setOnMouseClicked(event -> switchToSettingsLayout()); - - // Add menu items - menu.getChildren().addAll(new Label("Menu"), galleryLabel, settingsLabel); - this.setLeft(menu); // Set the menu on the left side - - // Set up the '+' button - Button addButton = new Button("+"); - addButton.setStyle("-fx-font-size: 24px; -fx-background-color: lightblue;"); - - // Set up the action for the '+' button to show the add dialog - addButton.setOnAction(e -> showAddDialog()); - - // Create an HBox to hold the button and align it to the bottom right - HBox buttonContainer = new HBox(addButton); - buttonContainer.setAlignment(Pos.BOTTOM_RIGHT); - buttonContainer.setPadding(new Insets(10)); // Optional padding - - // Add the buttonContainer to the bottom of the layout - this.setBottom(buttonContainer); - - // Optionally, set the center to another pane or leave it empty - // this.setCenter(someOtherPane); + setTop(createMenuBar()); + setCenter(createDashboard()); } - private void showAddDialog() { - Dialog dialog = new Dialog<>(); - dialog.setTitle("Add Build"); - - // Create the dialog layout - GridPane grid = new GridPane(); - grid.setHgap(10); - grid.setVgap(10); - grid.setPadding(new Insets(20)); - - TextField nameField = new TextField(); - nameField.setPromptText("Build Name"); - TextField builderField = new TextField(); - builderField.setPromptText("Builder Name"); - // Add more fields as needed... - - grid.add(new Label("Name:"), 0, 0); - grid.add(nameField, 1, 0); - grid.add(new Label("Builder:"), 0, 1); - grid.add(builderField, 1, 1); - // Add more fields to the grid as needed... - - dialog.getDialogPane().setContent(grid); - - // Add buttons for adding and canceling - dialog.getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL); - - // Show dialog and handle button events - dialog.setResultConverter(button -> { - if (button == ButtonType.OK) { - // Insert data into the database and handle image upload - String name = nameField.getText(); - String builder = builderField.getText(); - // Handle database insert... - System.out.println("Name: " + name + ", Builder: " + builder); // Debugging line - } - return null; - }); - - dialog.showAndWait(); + private HBox createMenuBar() { + HBox menuBar = new HBox(); + Button dashboardButton = new Button("Dashboard"); + dashboardButton.setOnAction(e -> setCenter(createDashboard())); + menuBar.getChildren().add(dashboardButton); + return menuBar; } - // This method is essential for switching to the GalleryLayout - private void switchToGalleryLayout() { - // Create an instance of GalleryLayout - GalleryLayout galleryLayout = new GalleryLayout(); - - // Set the center of the MainLayout to the GalleryLayout - this.setCenter(galleryLayout); - } - private void switchToSettingsLayout() { - SettingsWindow settingsLayout = new SettingsWindow(); - this.setCenter(settingsLayout); + + private GridPane createDashboard() { + GridPane dashboard = new GridPane(); + dashboard.add(new Label("Number of Kitsets:"), 0, 0); + dashboard.add(new Label("..."), 1, 0); // Placeholder for data + dashboard.add(new Label("Number of MoCs:"), 0, 1); + dashboard.add(new Label("..."), 1, 1); // Placeholder for data + return dashboard; } } diff --git a/BrickLog-Client/src/main/java/com/example/bricklog/view/MocPage.java b/BrickLog-Client/src/main/java/com/example/bricklog/view/MocPage.java new file mode 100644 index 0000000..2da9bfc --- /dev/null +++ b/BrickLog-Client/src/main/java/com/example/bricklog/view/MocPage.java @@ -0,0 +1,14 @@ +package com.example.bricklog.view; + +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.layout.VBox; + +public class MocPage extends VBox { + public MocPage() { + TableView table = new TableView<>(); + TableColumn column = new TableColumn<>("MoC Name"); + table.getColumns().add(column); + getChildren().add(table); + } +} diff --git a/BrickLog-Client/src/main/java/com/example/bricklog/view/SettingsWindow.java b/BrickLog-Client/src/main/java/com/example/bricklog/view/SettingsWindow.java index eb7b340..e5b9295 100644 --- a/BrickLog-Client/src/main/java/com/example/bricklog/view/SettingsWindow.java +++ b/BrickLog-Client/src/main/java/com/example/bricklog/view/SettingsWindow.java @@ -99,8 +99,14 @@ public class SettingsWindow extends BorderPane { // Method to connect to the server private void connectToServer(String ipAddress) { - boolean isConnected = simulateServerConnection(ipAddress); // Replace with real connection logic - + if (!isValidIPAddress(ipAddress)) { + connectionStatus.setText("Invalid IP Address"); + connectionStatus.setStyle("-fx-background-color: orange; -fx-padding: 5;"); + return; + } + + boolean isConnected = simulateServerConnection(ipAddress); + if (isConnected) { connectionStatus.setText("Connected"); connectionStatus.setStyle("-fx-background-color: lightgreen; -fx-padding: 5;"); @@ -109,10 +115,38 @@ public class SettingsWindow extends BorderPane { connectionStatus.setStyle("-fx-background-color: lightpink; -fx-padding: 5;"); } } - + + // Utility method to validate IP addresses + private boolean isValidIPAddress(String ipAddress) { + return ipAddress.matches( + "^((25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)$" + ); + } + + // DEMO PURPOSES ONLY [Commented out when in production] // Simulated connection logic for demonstration purposes private boolean simulateServerConnection(String ipAddress) { - // Here, add logic for real server connection. For now, a simple placeholder: - return !ipAddress.isEmpty() && ipAddress.equals("127.0.0.1"); + if (ipAddress == null || ipAddress.isEmpty()) { + return false; // IP address is invalid + } + + + // Simulate connection by checking for a specific IP pattern (e.g., localhost) + return ipAddress.equals("127.0.0.1") || ipAddress.startsWith("192.168."); } + + /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //PRODUCTION _ UNCOMmENT When Needed for true Server Connectivity + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + private boolean simulateServerConnection(String ipAddress) { + int port = 12345; // Replace with your server's port + try (Socket socket = new Socket()) { + socket.connect(new InetSocketAddress(ipAddress, port), 3000); // 3-second timeout + return true; // Connection successful + } catch (IOException e) { + return false; // Connection failed + } + } + ====================================================================================================== */ + } diff --git a/BrickLog-Client/src/main/java/css/dark-theme.css b/BrickLog-Client/src/main/java/css/dark-theme.css index e69de29..fb92c3d 100644 --- a/BrickLog-Client/src/main/java/css/dark-theme.css +++ b/BrickLog-Client/src/main/java/css/dark-theme.css @@ -0,0 +1,19 @@ +.root { + -fx-background-color: #161616; + background-color: #161616; /* Compatibility fix */ +} + +.label.title { + -fx-text-fill: #B22222; + -fx-effect: dropshadow(gaussian, white, 2, 0, 0, 0); +} + +.table-view { + -fx-font-size: 14px; + font-size: 14px;/* Compatibility fix */ + -fx-text-fill: #E0FFFF; +} + +.caption { + -fx-text-fill: #C0C0C0; +} diff --git a/BrickLog-Client/src/main/java/css/gallery.css b/BrickLog-Client/src/main/java/css/gallery.css new file mode 100644 index 0000000..9252c64 --- /dev/null +++ b/BrickLog-Client/src/main/java/css/gallery.css @@ -0,0 +1,22 @@ +.toggle-button { + -fx-background-color: #444; + -fx-text-fill: white; + -fx-padding: 5 10; + -fx-border-radius: 5; + -fx-background-radius: 5; +} + +.toggle-button:selected { + -fx-background-color: #666; +} + +.grid-pane { + -fx-background-color: #f0f0f0; + -fx-padding: 10; + -fx-hgap: 15; + -fx-vgap: 15; +} + +.list-view { + -fx-background-color: #f9f9f9; +} diff --git a/BrickLog-Client/target/classes/com/example/bricklog/model/Build.class b/BrickLog-Client/target/classes/com/example/bricklog/model/Build.class new file mode 100644 index 0000000000000000000000000000000000000000..82b95c6491e0b2e2a09fdba506f562d1ee2e8e59 GIT binary patch literal 1288 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 delta 2328 zcmZuyX>=Ra75+vVX~yy-wq;w6oTUml!ImB5H955pZHQT7BAb8`QMGBCu|3G+$dZu8 z#%761Nug;uP#8){7YJSAHr)~+a*0Vop)C;FLRkxiLR*$@(DeuB^c?8-Mv9N2Jx6-; z=DYWP@80j-E1m3kzPbA3J4cTLI2->~;F55Ltyk9DuXz23H@xF^-P&yLtPJqA*4`Iv#*lxu=jc2md7Qmuvfe4Zr-gHd@xZXmR_->HDu5&LCG7|=A@n#*ku}W zr?5CN1(t;BaeYdUr1W$$60>qqsETjOO#5&RY7~4%6n8>hW*<^z zw}R{K`_+~H>(J=K9(+#25`135%I2tWDfG3(y&H!gppJmB-=yISqSQ(jah_>iVvbs4 z0>4FrEpV-bZ#K;2m?aEf)NmWtP!1Zl=8U|Nn=&reEi)sMxn09Pe3@)X!|ES1Q=>T} zEn!V_OH_z=>2$>28Nj~HnqGL#uL`UVDC;u7R!&ZLKLc#_9%o5>n^3AG<{+!tS3 zpM(nMR<`F-^pH$`2N*pyY-g25`*mM;U`fo7lQ=Wf(Hn9$MlLj@PZ({Xj`sG@R?`?U@@=8c_UW$n>5lf$ z$V6M{RL{&y=qkl_{!eVrqS&74uAb?R9w(MP=ED&j(@;1rq*f{QfMrau7&&F;*{I5> zVdS@N@i9!7q3l&Hych zJJA{*$8x5e6^yC0ieLR7t|-fLxHxWRUNE!llOm~ zQgx5*u3oR;cld*X-`g9j*UESmui4|(FT3!Hy`|>DI=tb7gg%;^nLi&p zmsR7h6lx%yHgf$bJ)bx73jWS!wlDIp@-;;>nO&3oVfd##LXeq>o-0S68nDe-XgCQke0C0dd%Zz# z9d0P%#`5##pjR&9)}W_|FL{n3oNx!d#t)+qo#U5|{HMaR*0ZgN4>2?r$qA8M67fP|D_FM5!W!7?53m{+eoQZoh|1|DenwRfG z;BGwRf3%3l!r^;yZV`jCs1?u?WoQc_F(K|n>4_#adB8YlWfzZ4;RBe!8T`W*=>%{(uzu-;0MMTK_H~a(tLh!#YN*m1p diff --git a/BrickLog-Client/target/classes/com/example/bricklog/view/KitsetPage.class b/BrickLog-Client/target/classes/com/example/bricklog/view/KitsetPage.class new file mode 100644 index 0000000000000000000000000000000000000000..06ded9c8995fccf1b7a09daa5e1fe35593b3e872 GIT binary patch literal 963 zcma)5T~8B16g|_HZo6HqR;dVz1p)g3?2B(DBuZjTSiuCd2H&>ZaT(n1klkr5zr|nS z3yqTa1N>3OJ6+IJq48yB=iYnHJ@;dN{QUMEz;kRF$S|z>vS;(5*EUxD2^n+2tm( zC|a07-av_AX#(xbNX0U=-+G;pyOhj?iK2m947HmBcV*b`MFreuD5c_R`(BSS&7z_+ z-DQ}oI~q^&qQE{>v510p!`19_7OJ?JL}0CZA+kf*Ofx6fqN_RZ!9g$tNRBUsJ_W{)c65$?Qho#WodSIlSdu6d57R{Hye z09m307KjKaAcrC>+PNx9WVf(E8@fWCT1t*5Sf!gqzBQ~r&fB7(Hvd$QUIMCqP1gniMDoiqcDZ!66McAy8yU3niuZwY^{kS<6T=ftTpB zw13Pr%=7^|eWp&om4uA~bojHETXO`)=9XjfW7+gIq!>nD@k73QWO!BK2*VCGjG}aF!hOLV!O->CaxDJ|Lvkv= z&5$a|n#drDZXNHSD+7ie9Xf6>+^D*O`=TtIW|6xL!&7z6HY&p1;uV{E&6={x?QQN_Y91}7{JP~aOq$ohw4h;>;qFy!XE1_p4Py-V zVma|6yWr_MJ9eGR>n04;d zR5PWi>s8z)NgNU|#xpgp1TkEKE{9niA7GAXCg?Vt#j0;fhji1X>Jm3a*$5u$_z)kF z;~rsNx9plL$Z?`WS5?}!2;zChM#U5Ep@QACJipL`Pw=URM+{>TP*)r4_za(uK6#DQ z5CdqV@`~aY^4~LPjWbye#Wfa5J`g2oqIM>%kP3#8xOto@qMJ^}aE!|+;FE|bv3`8#wtND zH#e8Y8nw|0RhA`hp5)YSjJS)p^j5(IhP2Hal^P#^NbR>1hCGM-2O=TiF)&hE8_|m< z44F;YbgN?7Qkv}T+&*&(4Tip=l)mS?{GcrSx~zE_Y~wo(FBu*vi%{v7b13(PVFqQ9 zA>ZXyU%JOSc0lCzG&)NR|C~P~k!Kh@l(jc*O1a-WC9DmWVj*VUoKlfpSL0@$o;g)RfdBW2` zr()s)l$QabVK;gZVztCf>4FK-!x$w_(!~R$=#Sn48a0}&AwhpY|MUsc)6*?vTDYmc z*%k)=pp69X(U>JSpohlb`JmhVCWdH551nxz!+|Y5Em7dtlujkgpJHU^1n-)s$n9hw zoM5~>JN*Xl11-$Vv|!BsiH{R_IrDoEKqVWX`hZ(VQ`#(UQ|LQn-ybB*g+Zf)Y3l0> z%u~uN22sFcDmS5?o~Vf5sNe*}T0X@B74fAxbBd=s+2RS7lF1gHh0_(9raIHF)NU%i z8%#SD4iSDJVA536Ak{KSH9n$CbP1zDl>=ecc9lq6WGKSeH9Ns(ArP<6&w{>QA(>qU=R2H0|~P$;Q#;t literal 6321 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 a)f#c8*uefF#3r$sTyjR(B3eWnLjMH`wZBpT diff --git a/BrickLog-Client/target/classes/com/example/bricklog/view/MocPage.class b/BrickLog-Client/target/classes/com/example/bricklog/view/MocPage.class new file mode 100644 index 0000000000000000000000000000000000000000..e354b8f5c601e74a4ada64dcc32a3f134152f4c4 GIT binary patch literal 951 zcmah{+iuf95IviuapJfX0u7}=Nm~lJwDk*bsVYGv#Dmi!6&aN`+gaQ#wzsmKkbVna z!Am2k#0T(Eh}k$r3bf(HAKAboQv z_-C^xy|<3fH53?DPMx9iabzYQkGL5)=W>vm_A5DJDDH_!r27o{M$={}bY-9G$fImv z0YwcJhP9b$Pey4h1M{8Z2Hd7jI&_pZ++wKToY|_bFzU)cuXod{r+EU4&772?=(N?V0dDnuGmx*n-dZAV;(UqSt8;G zgV5#iL>7jsB|RswomeO~Q)eMP5k!8|`tQ~{3=65MBvG#h&6f9%{FGXxu}EEpjXAlQ zc9dP4rFMRHMeoI&YPIOSNqlBS`-JyqPFdFUn!@X$^dmWlJ^os#!Hww!@2cHloy5=6 z<%2AVgCc!3dVL|U^6#|9C|yE79>cIMv3Oiv8sko{eSv%1->{Oy`_={4+S%_{D##Ng zuu4Ec2?dm4(6!Z2A-{oby3GxW)H85w;wilhif!Q;wWgEAb2N}cll(QZS*-OZ)+Qe# I9FX1l4ax)fxc~qF literal 0 HcmV?d00001 diff --git a/BrickLog-Client/target/classes/com/example/bricklog/view/SettingsWindow.class b/BrickLog-Client/target/classes/com/example/bricklog/view/SettingsWindow.class index 39254c2c2ef58ad47bc4516adaf603421f4fac73..db565f1ceeff5af71145d3cd792d5578e4844ced 100644 GIT binary patch delta 1127 zcma)4TTB#Z6#mYPIJ2{}>#_)fAS^DFU6x(hZ24hd!c7?@tm(HxF zR1MJ=AAIwFFp~7OCWaS@#@_xYXC+lcFDNq83|;a$E{p8Jw7p#PTLvBA=F0p&sj&UJvl2svuCnsXY(_I z(I<7hNeGVTk4koEd?Hlgiy@<-Hy%IueEeB!`p}GBIFe7trwh4)JrF9`>>@K5lGb@E zon}u1p`Jklgm+C`7q>mTf;!$Oct#8Pd}g|sN$dDfJZkjP$Ks4Jxv1ky!hvTZkyOu9 z-SM8O<0(EKnqtvEb)02#YS`6XF&uq55k2Z?XC+G z%yDkIJ({x|C*x?;L1-72Z-*H62Pi5g{Ev}m9#!gcEckN?zbwHY3;tHZA4?M3BBPaSFGo8GFHXUS({5SiVByVR_2Ei1 zSxpsGFVzGTIdpNZW?#z&{s!@#2VN6#mY=O>Q#YJepS5i<6sY{PScJ>I*cJH{(+jK9?J3a`)Uo8?}8M8SJ`Sx;)H>-dDv zQaCyle3dcBAq~IqTf?e6rXubR*XO( z120C=hB34wix9>UM;=$0v1#pKOk;*CmcU)y1MyrJ?&ARqKV(#cvVwMM=JGmjaNEh? z5LXIEA7ARxc{rn