From 6dd11fb69fa5dff8aac3532c3d33e6fd7d0554cf Mon Sep 17 00:00:00 2001 From: Per Eric Trapnes Date: Wed, 13 May 2026 12:17:50 +0200 Subject: [PATCH] refactor cleaned up the controller and such in popup and desktop/login view --- .../gruppe42/Controller/PopupController.java | 78 ------ .../gruppe42/Controller/PopupsController.java | 81 ++++++ .../DesktopViewController.java | 12 +- .../ntnu/idi/idatt2003/gruppe42/Millions.java | 6 +- .../idi/idatt2003/gruppe42/View/Popup.java | 238 +++++------------- .../View/Views/Components/StockGraph.java | 17 +- .../gruppe42/View/Views/DesktopView.java | 200 ++++++--------- .../gruppe42/View/Views/StartView.java | 26 +- src/main/resources/css/apps.css | 4 +- 9 files changed, 253 insertions(+), 409 deletions(-) delete mode 100644 src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupController.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupsController.java diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupController.java deleted file mode 100644 index 1068503..0000000 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupController.java +++ /dev/null @@ -1,78 +0,0 @@ -package edu.ntnu.idi.idatt2003.gruppe42.Controller; - -import edu.ntnu.idi.idatt2003.gruppe42.Model.App; -import edu.ntnu.idi.idatt2003.gruppe42.View.Popup; -import java.util.List; -import javafx.scene.layout.Pane; - -/** - * Controller for managing popups in a pane. - * Handles adding, removing, and keeping popups within bounds. - */ -public final class PopupController { - /** List of managed popups. */ - private final List popups; - - /** - * Constructs a new popup controller. - * - * @param popups the list of popups to manage - */ - public PopupController(final List popups) { - this.popups = popups; - } - - /** - * Shows a popup of the specified type and brings it to the front. - * - * @param type the type of popup to show - * @return true if the request was processed - */ - public boolean show(final App type) { - if (type == null) { - return false; - } - popups.stream() - .filter(popup -> popup.getType().equals(type)) - .findFirst() - .ifPresent(popup -> { - popup.getRoot().setVisible(true); - popup.getRoot().autosize(); - bringToFront(popup); - }); - return true; - } - - /** - * Brings the specified popup to the front of all others. - * - * @param popup the popup to bring to front - */ - public void bringToFront(final Popup popup) { - if (popup.getRoot().getParent() instanceof Pane) { - popup.getRoot().toFront(); - } - } - - /** - * Returns the list of managed popups. - * - * @return the list of popups - */ - public List getPopups() { - return popups; - } - - /** - * Returns the popup of the specified type. - * - * @param type the type of popup to retrieve - * @return the popup, or null if not found - */ - public Popup getPopup(final App type) { - return popups.stream() - .filter(popup -> popup.getType().equals(type)) - .findFirst() - .orElse(null); - } -} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupsController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupsController.java new file mode 100644 index 0000000..d44cc7b --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupsController.java @@ -0,0 +1,81 @@ +package edu.ntnu.idi.idatt2003.gruppe42.Controller; + +import edu.ntnu.idi.idatt2003.gruppe42.Model.App; +import edu.ntnu.idi.idatt2003.gruppe42.View.Popup; +import java.util.List; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.Pane; + +/** + * Manages popup visibility, dragging, and bounds-clamping. + */ +public final class PopupsController { + + private final List popups; + + public PopupsController(List popups) { + this.popups = popups; + popups.forEach(this::initPopup); + } + + private void initPopup(Popup popup) { + makeDraggable(popup); + popup.getCloseButton().setOnAction(e -> hide(popup)); + } + + public boolean show(App type) { + if (type == null) { + return false; + } + popups.stream() + .filter(popup -> popup.getType().equals(type)) + .findFirst() + .ifPresent(popup -> { + popup.getRoot().setVisible(true); + popup.getRoot().autosize(); + popup.getRoot().toFront(); + }); + return true; + } + + public boolean hide(Popup popup) { + if (popup == null) { + return false; + } + popup.getRoot().setVisible(false); + return true; + } + + public List getPopups() { + return popups; + } + + private void makeDraggable(Popup popup) { + BorderPane root = popup.getRoot(); + double[] offset = new double[2]; // [x, y] + + popup.getHeader().setOnMousePressed(event -> { + offset[0] = event.getSceneX() - root.getLayoutX(); + offset[1] = event.getSceneY() - root.getLayoutY(); + }); + + popup.getHeader().setOnMouseDragged(event -> { + root.setLayoutX(event.getSceneX() - offset[0]); + root.setLayoutY(event.getSceneY() - offset[1]); + clampToBounds(popup); + }); + } + + private void clampToBounds(Popup popup) { + BorderPane root = popup.getRoot(); + if (!(root.getParent() instanceof Pane parent)) { + return; + } + + double maxX = parent.getWidth() - popup.getWidth(); + double maxY = parent.getHeight() - popup.getHeight(); + + root.setLayoutX(Math.max(0, Math.min(root.getLayoutX(), maxX))); + root.setLayoutY(Math.max(0, Math.min(root.getLayoutY(), maxY))); + } +} \ No newline at end of file diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/ViewControllers/DesktopViewController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/ViewControllers/DesktopViewController.java index 10115b0..098977b 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/ViewControllers/DesktopViewController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/ViewControllers/DesktopViewController.java @@ -5,7 +5,7 @@ import edu.ntnu.idi.idatt2003.gruppe42.Controller.AppControllers.StockAppController; import edu.ntnu.idi.idatt2003.gruppe42.Controller.GameController; import edu.ntnu.idi.idatt2003.gruppe42.Controller.MarketController; -import edu.ntnu.idi.idatt2003.gruppe42.Controller.PopupController; +import edu.ntnu.idi.idatt2003.gruppe42.Controller.PopupsController; import edu.ntnu.idi.idatt2003.gruppe42.Controller.TimeAndWeatherController; import edu.ntnu.idi.idatt2003.gruppe42.Model.App; import edu.ntnu.idi.idatt2003.gruppe42.Model.Player; @@ -33,7 +33,7 @@ * Handles app button creation, resizing, click events, and drag-and-drop. */ public final class DesktopViewController { - private final PopupController popupController; + private final PopupsController popupsController; private final DesktopView desktopView; private final Player player; private final TimeAndWeatherController timeAndWeatherController; @@ -79,17 +79,17 @@ public DesktopViewController( popups.add(newsApp); popups.add(bankApp); - this.popupController = new PopupController(popups); + this.popupsController = new PopupsController(popups); bankApp.setOnShareSelected(share -> { - popupController.show(App.STOCK); + popupsController.show(App.STOCK); stockApp.openStockPage(share.getStock()); }); this.desktopView = new DesktopView(this); this.desktopView.getRoot().getChildren().addAll( - popupController.getPopups().stream() + popupsController.getPopups().stream() .map(Popup::getRoot).toArray(Pane[]::new) ); } @@ -183,7 +183,7 @@ public void handleSettings() { * @param type the app type. */ private void openPopup(final App type) { - popupController.show(type); + popupsController.show(type); } /** diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Millions.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Millions.java index 8c6ede1..19b4acb 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Millions.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Millions.java @@ -17,6 +17,7 @@ public class Millions extends Application { private Scene scene; private Stage stage; private DesktopView desktopView; + private DesktopViewController desktopViewController; private Player player; private GameController gameController; @@ -32,7 +33,7 @@ public void start(Stage stage) throws Exception { stage.setTitle("Millions"); stage.setScene(scene); stage.setFullScreen(true); - stage.setFullScreenExitHint(""); + stage.setFullScreenExitHint("Press 'EXIT' to ENTER the matrix"); stage.show(); } @@ -44,13 +45,14 @@ public void initGame(String username, Difficulty difficulty) { } public void switchToStartView() { + stop(); StartView startView = new StartView(); scene.setRoot(startView.getRoot()); stage.setScene(scene); } public void switchToDesktopView() { - DesktopViewController desktopViewController = new DesktopViewController(player, gameController); + desktopViewController = new DesktopViewController(player, gameController); desktopView = desktopViewController.getDesktopView(); scene.setRoot(desktopView.getRoot()); stage.setScene(scene); diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popup.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popup.java index c945b8b..ddc977a 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popup.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popup.java @@ -1,5 +1,5 @@ package edu.ntnu.idi.idatt2003.gruppe42.View; - + import edu.ntnu.idi.idatt2003.gruppe42.Model.App; import javafx.geometry.Insets; import javafx.geometry.Pos; @@ -9,221 +9,109 @@ import javafx.scene.input.MouseEvent; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; -import javafx.scene.layout.Pane; import javafx.scene.layout.Priority; -import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.scene.shape.Circle; import javafx.scene.shape.Rectangle; /** - * An abstract class for all popups. - * Handles dragging, layout, and common components. + * Abstract base class for all draggable popup windows. + * Only responsible for building and exposing UI components. */ public abstract class Popup { + private final int width; private final int height; - private double dx; - private double dy; private final App type; - /** Root layout node. */ private final BorderPane root; private final HBox header; private final Button closeButton; protected final VBox content; - /** - * Constructs a new popup. - * - * @param width width of the popup - * @param height height of the popup - * @param x x-position of the popup - * @param y y-position of the popup - * @param type the app type - */ - protected Popup( - final int width, - final int height, - final int x, - final int y, - final App type - ) { - this.width = width; + protected Popup(int width, int height, int x, int y, App type) { + this.width = width; this.height = height; - this.type = type; + this.type = type; - root = new BorderPane(); - root.getStyleClass().add("popup-root"); + content = new VBox(); + content.getStyleClass().add("popup-content"); + content.setPrefSize(width, height); - ScrollPane scrollPane = new ScrollPane(); + ScrollPane scrollPane = new ScrollPane(content); scrollPane.getStyleClass().add("popup-scroll-pane"); - - // Load stylesheets - root.getStylesheets().add(getClass().getResource("/css/global.css").toExternalForm()); - root.getStylesheets().add(getClass().getResource("/css/popup.css").toExternalForm()); - root.getStylesheets().add(getClass().getResource("/css/apps.css").toExternalForm()); - + scrollPane.setMinSize(width, height); scrollPane.setFitToWidth(true); scrollPane.setFitToHeight(true); - header = new HBox(); - header.setAlignment(Pos.CENTER_LEFT); - header.setPadding(new Insets(5, 10, 5, 10)); - header.setSpacing(10); - header.getStyleClass().add("popup-header"); - - // Close Button (Mac-style red circle) - closeButton = new Button(); - closeButton.setShape(new Circle(6)); - closeButton.setPrefSize(12, 12); - closeButton.setMinSize(12, 12); - closeButton.setMaxSize(12, 12); - closeButton.getStyleClass().add("popup-close-button"); - - // Title Label (Centered) - Label titleLabel = new Label(type.toString().substring(0, 1).toUpperCase() - + type.toString().substring(1).toLowerCase()); - titleLabel.getStyleClass().add("popup-title"); - - // Container for title to center it - HBox titleContainer = new HBox(titleLabel); - titleContainer.setAlignment(Pos.CENTER); - HBox.setHgrow(titleContainer, Priority.ALWAYS); - - // Placeholder for symmetry on the right - Region rightSpacer = new Region(); - rightSpacer.setPrefSize(12, 12); - - header.getChildren().addAll(closeButton, titleContainer, rightSpacer); - setCloseButtonAction(); - - content = new VBox(); - content.getStyleClass().add("popup-content"); - content.setPrefSize(width, height); - scrollPane.setMinSize(width, height); + closeButton = buildCloseButton(); + header = buildHeader(closeButton, titleString()); + root = new BorderPane(); + root.getStyleClass().add("popup-root"); + root.getStylesheets().addAll( + resource("/css/global.css"), + resource("/css/popup.css"), + resource("/css/apps.css") + ); + root.setTop(header); + root.setCenter(scrollPane); root.setLayoutX(x); root.setLayoutY(y); root.setManaged(false); - - scrollPane.setContent(content); - root.setTop(header); - root.setCenter(scrollPane); - - // Initial sizing - root.autosize(); - - // Clip content to rounded corners - Rectangle clip = new Rectangle(); - clip.setArcWidth(20); - clip.setArcHeight(20); - clip.widthProperty().bind(root.widthProperty()); - clip.heightProperty().bind(root.heightProperty()); - root.setClip(clip); - - setOnPressedAction(); - makeDraggable(); root.setVisible(false); + root.autosize(); + root.setClip(roundedClip()); + root.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> root.toFront()); } - private void setCloseButtonAction() { - closeButton.setOnAction(e -> { - root.setVisible(false); - }); - } - - private void setOnPressedAction() { - root.addEventFilter(MouseEvent.MOUSE_PRESSED, mouseEvent -> root.toFront()); - } - - private void makeDraggable() { - header.setOnMousePressed(mouseEvent -> { - dx = mouseEvent.getSceneX() - root.getLayoutX(); - dy = mouseEvent.getSceneY() - root.getLayoutY(); - }); - - header.setOnMouseDragged(mouseEvent -> { - root.setLayoutX(mouseEvent.getSceneX() - dx); - root.setLayoutY(mouseEvent.getSceneY() - dy); - keepInBounds(); - }); + private Button buildCloseButton() { + Button btn = new Button(); + btn.setShape(new Circle(6)); + btn.setMinSize(12, 12); + btn.setMaxSize(12, 12); + btn.getStyleClass().add("popup-close-button"); + return btn; } - /** - * Returns the width of the popup. - * - * @return the width - */ - public int getWidth() { - return width; - } + private HBox buildHeader(Button closeButton, String title) { + Label titleLabel = new Label(title); + titleLabel.getStyleClass().add("popup-title"); - /** - * Returns the height of the popup. - * - * @return the height - */ - public int getHeight() { - return height; - } + HBox titleContainer = new HBox(titleLabel); + titleContainer.setAlignment(Pos.CENTER); + HBox.setHgrow(titleContainer, Priority.ALWAYS); - /** - * Returns the x-position of the popup. - * - * @return the x-position - */ - public double getX() { - return root.getLayoutX(); + HBox hbox = new HBox(10, closeButton, titleContainer); + hbox.setAlignment(Pos.CENTER_LEFT); + hbox.setPadding(new Insets(5, 10, 5, 10)); + hbox.getStyleClass().add("popup-header"); + return hbox; } - /** - * Returns the y-position of the popup. - * - * @return the y-position - */ - public double getY() { - return root.getLayoutY(); + private String titleString() { + String s = type.toString(); + return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase(); } - /** - * Returns the root node of the popup. - * - * @return the root - */ - public BorderPane getRoot() { - return root; + private Rectangle roundedClip() { + Rectangle clip = new Rectangle(); + clip.setArcWidth(20); + clip.setArcHeight(20); + clip.widthProperty().bind(root.widthProperty()); + clip.heightProperty().bind(root.heightProperty()); + return clip; } - /** - * Returns the type of the popup. - * - * @return the type - */ - public App getType() { - return type; + private String resource(String path) { + return getClass().getResource(path).toExternalForm(); } - /** - * Checks if a popup is out of bounds and moves it back if necessary. - */ - public void keepInBounds() { - if (getRoot().getParent() instanceof Pane parent) { - double screenWidth = parent.getWidth(); - double screenHeight = parent.getHeight(); - - if (getX() < 0) { - getRoot().setLayoutX(0); - } else if (getX() + getWidth() > screenWidth) { - getRoot().setLayoutX(screenWidth - getWidth()); - } - - if (getY() < 0) { - getRoot().setLayoutY(0); - } else if (getY() + getHeight() > screenHeight) { - getRoot().setLayoutY(screenHeight - getHeight()); - } - } - } -} + public App getType() { return type; } + public BorderPane getRoot() { return root; } + public HBox getHeader() { return header; } + public Button getCloseButton() { return closeButton; } + public int getWidth() { return width; } + public int getHeight() { return height; } +} \ No newline at end of file diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Views/Components/StockGraph.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Views/Components/StockGraph.java index c1398c5..e9cb960 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Views/Components/StockGraph.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Views/Components/StockGraph.java @@ -22,19 +22,19 @@ public final class StockGraph extends VBox { */ public StockGraph() { this.getStyleClass().add("stock-graph-container"); - NumberAxis xAxis = new NumberAxis(); + final NumberAxis xAxis = new NumberAxis(); xAxis.setLabel("Time"); xAxis.setAutoRanging(true); xAxis.setTickLabelsVisible(false); xAxis.setTickMarkVisible(false); - NumberAxis yAxis = new NumberAxis(); + final NumberAxis yAxis = new NumberAxis(); yAxis.setLabel("Price"); yAxis.setAutoRanging(true); lineChart = new LineChart<>(xAxis, yAxis); lineChart.getStyleClass().add("stock-line-chart"); - lineChart.setPrefSize(400, 250); + lineChart.setPrefSize(500, 250); lineChart.setCreateSymbols(false); lineChart.setLegendVisible(false); lineChart.setAnimated(false); @@ -46,22 +46,20 @@ public StockGraph() { * Updates the graph with data from the specified stock. * * @param stock the stock to display - * @return true if update was scheduled */ - public boolean update(final Stock stock) { + public void update(final Stock stock) { if (stock == null) { - return false; + return; } List history = stock.getHistoricalPrices(); if (history.isEmpty()) { - return false; + return; } - int stockResolution = 50; List latestHistory = history.subList( - Math.max(history.size() - stockResolution, 0), + Math.max(history.size() - 120, 0), history.size() ); @@ -77,7 +75,6 @@ public boolean update(final Stock stock) { lineChart.getData().add(series); }); - return true; } public boolean getVisibility() { diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Views/DesktopView.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Views/DesktopView.java index 9bf3e5c..56c26e3 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Views/DesktopView.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Views/DesktopView.java @@ -3,18 +3,11 @@ import edu.ntnu.idi.idatt2003.gruppe42.Controller.TimeAndWeatherController; import edu.ntnu.idi.idatt2003.gruppe42.Controller.ViewControllers.DesktopViewController; import edu.ntnu.idi.idatt2003.gruppe42.Model.App; -import java.util.Objects; import javafx.application.Platform; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.control.Label; -import javafx.scene.image.Image; -import javafx.scene.layout.Background; -import javafx.scene.layout.BackgroundImage; -import javafx.scene.layout.BackgroundPosition; -import javafx.scene.layout.BackgroundRepeat; -import javafx.scene.layout.BackgroundSize; import javafx.scene.layout.BorderPane; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; @@ -25,174 +18,129 @@ import javafx.scene.layout.StackPane; /** - * View for the desktop. - * Displays a 10x6 grid of apps. + * Desktop view showing a 10x6 app grid and a bottom status bar. */ public final class DesktopView { - private final DesktopViewController desktopViewController; - private final BorderPane root; + private static final int COLS = 10; private static final int ROWS = 6; - /** - * Constructs a new DesktopView. - * - * @param desktopViewController the controller - */ - public DesktopView(final DesktopViewController desktopViewController) { + private final DesktopViewController controller; + private final BorderPane root; + + public DesktopView(DesktopViewController controller) { + this.controller = controller; this.root = new BorderPane(); - this.desktopViewController = desktopViewController; } /** - * Returns the root of the desktop view. - * - * @return the root of the desktop view. + * Builds and returns the root node, constructing children on first call. */ public BorderPane getRoot() { if (root.getCenter() == null) { - GridPane grid = createGrid(); - root.setCenter(grid); + root.setCenter(createGrid()); } if (root.getBottom() == null) { root.setBottom(createBottomBar()); } - // Load stylesheet - root.getStylesheets().add(getClass().getResource("/css/global.css").toExternalForm()); - root.getStylesheets().add(getClass().getResource("/css/desktop.css").toExternalForm()); - root.getStylesheets().add(getClass().getResource("/css/apps.css").toExternalForm()); + root.getStylesheets().addAll( + resource("/css/global.css"), + resource("/css/desktop.css"), + resource("/css/apps.css") + ); root.getStyleClass().add("desktop-root"); return root; } - /** - * Creates the 10x6 grid with app buttons. - * - * @return the grid pane. - */ private GridPane createGrid() { GridPane grid = new GridPane(); grid.setAlignment(Pos.CENTER); - grid.setHgap(0); - grid.setVgap(0); - // Set constraints to make the grid fit the width and height - final double maxPercent = 100.0; for (int col = 0; col < COLS; col++) { - ColumnConstraints colConstraints = new ColumnConstraints(); - colConstraints.setPercentWidth(maxPercent / COLS); - colConstraints.setHgrow(Priority.ALWAYS); - grid.getColumnConstraints().add(colConstraints); + ColumnConstraints cc = new ColumnConstraints(); + cc.setPercentWidth(100.0 / COLS); + cc.setHgrow(Priority.ALWAYS); + grid.getColumnConstraints().add(cc); } for (int row = 0; row < ROWS; row++) { - RowConstraints rowConstraints = new RowConstraints(); - rowConstraints.setPercentHeight(maxPercent / ROWS); - rowConstraints.setVgrow(Priority.ALWAYS); - grid.getRowConstraints().add(rowConstraints); + RowConstraints rc = new RowConstraints(); + rc.setPercentHeight(100.0 / ROWS); + rc.setVgrow(Priority.ALWAYS); + grid.getRowConstraints().add(rc); } + App[] apps = App.values(); for (int row = 0; row < ROWS; row++) { for (int col = 0; col < COLS; col++) { - StackPane cell = createCell(); - grid.add(cell, col, row); - - // Add initial buttons to the first row based on the Apps enum - if (row == 0 && col < App.values().length) { - cell.getChildren().add( - desktopViewController.createAppButton(App.values()[col]) - ); + StackPane cell = new StackPane(); + controller.configureCellAsDropTarget(cell); + if (row == 0 && col < apps.length) { + cell.getChildren().add(controller.createAppButton(apps[col])); } + grid.add(cell, col, row); } } - return grid; - } - /** - * Creates a cell for the grid that acts as a drop target. - * - * @return the stack pane cell. - */ - private StackPane createCell() { - StackPane cell = new StackPane(); - desktopViewController.configureCellAsDropTarget(cell); - return cell; + return grid; } - /** - * Creates the bottom bar with settings, player name, and clock. - * - * @return the bottom bar HBox. - */ private HBox createBottomBar() { - HBox bottomBar = new HBox(15); - bottomBar.setAlignment(Pos.CENTER_LEFT); - bottomBar.setPadding(new Insets(5, 15, 5, 15)); - bottomBar.getStyleClass().add("desktop-bottom-bar"); - - // Settings Button Button settingsButton = new Button("⚙"); settingsButton.getStyleClass().add("desktop-settings-button"); - settingsButton.setOnAction(e -> { - desktopViewController.handleSettings(); - }); + settingsButton.setOnAction(e -> controller.handleSettings()); - // Player Name - Label playerNameLabel = new Label("User: " + desktopViewController.getPlayer().getName()); - playerNameLabel.getStyleClass().add("desktop-label-bold"); - playerNameLabel.setMinWidth(Region.USE_PREF_SIZE); + Label playerLabel = new Label("User: " + controller.getPlayer().getName()); + playerLabel.getStyleClass().add("desktop-label-bold"); + playerLabel.setMinWidth(Region.USE_PREF_SIZE); - // Spacer to push clock to the right Region spacer = new Region(); HBox.setHgrow(spacer, Priority.ALWAYS); - spacer.setMinWidth(20); - - // Time and Weather elements - TimeAndWeatherController twc = desktopViewController.getTimeAndWeatherController(); - - Label weatherLabel = new Label(); - weatherLabel.getStyleClass().add("desktop-label"); - - Label tempLabel = new Label(); - tempLabel.getStyleClass().add("desktop-label"); - - Label dayLabel = new Label(); - dayLabel.getStyleClass().add("desktop-label-bold"); - - Label clockLabel = new Label(); - clockLabel.getStyleClass().add("desktop-label-bold"); - - // Update labels when properties change - twc.hourProperty().addListener((obs, oldVal, newVal) -> Platform.runLater(() -> { - clockLabel.setText(twc.getTimeString()); - })); - - twc.dayIndexProperty().addListener((obs, oldVal, newVal) -> Platform.runLater(() -> { - dayLabel.setText(twc.getDayOfWeekString()); - })); - twc.weatherProperty().addListener((obs, oldVal, newVal) -> Platform.runLater(() -> { - weatherLabel.setText(newVal); - })); - - twc.temperatureProperty().addListener((obs, oldVal, newVal) -> Platform.runLater(() -> { - tempLabel.setText(newVal + "°C"); - })); + HBox bottomBar = new HBox(15, settingsButton, playerLabel, spacer, createStatusBox()); + bottomBar.setAlignment(Pos.CENTER_LEFT); + bottomBar.setPadding(new Insets(5, 15, 5, 15)); + bottomBar.getStyleClass().add("desktop-bottom-bar"); - // Initial values - clockLabel.setText(twc.getTimeString()); - dayLabel.setText(twc.getDayOfWeekString()); - weatherLabel.setText(twc.weatherProperty().get()); - tempLabel.setText(twc.temperatureProperty().get() + "°C"); + return bottomBar; + } - HBox rightInfo = new HBox(10); - rightInfo.setAlignment(Pos.CENTER_RIGHT); - rightInfo.setMinWidth(Region.USE_PREF_SIZE); - rightInfo.getChildren().addAll(weatherLabel, tempLabel, dayLabel, clockLabel); + private HBox createStatusBox() { + TimeAndWeatherController twc = controller.getTimeAndWeatherController(); + + Label weather = styledLabel("desktop-label"); + Label temp = styledLabel("desktop-label"); + Label day = styledLabel("desktop-label-bold"); + Label clock = styledLabel("desktop-label-bold"); + + weather.setText(twc.weatherProperty().get()); + temp.setText(twc.temperatureProperty().get() + "°C"); + day.setText(twc.getDayOfWeekString()); + clock.setText(twc.getTimeString()); + + twc.hourProperty().addListener((obs, o, n) + -> Platform.runLater(() -> clock.setText(twc.getTimeString()))); + twc.dayIndexProperty().addListener((obs, o, n) + -> Platform.runLater(() -> day.setText(twc.getDayOfWeekString()))); + twc.weatherProperty().addListener((obs, o, n) + -> Platform.runLater(() -> weather.setText(n))); + twc.temperatureProperty().addListener((obs, o, n) + -> Platform.runLater(() -> temp.setText(n + "°C"))); + + HBox box = new HBox(10, weather, temp, day, clock); + box.setAlignment(Pos.CENTER_RIGHT); + box.setMinWidth(Region.USE_PREF_SIZE); + return box; + } - bottomBar.getChildren().addAll(settingsButton, playerNameLabel, spacer, rightInfo); + private Label styledLabel(String styleClass) { + Label label = new Label(); + label.getStyleClass().add(styleClass); + return label; + } - return bottomBar; + private String resource(String path) { + return getClass().getResource(path).toExternalForm(); } -} +} \ No newline at end of file diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Views/StartView.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Views/StartView.java index ac72838..f2b25a8 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Views/StartView.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Views/StartView.java @@ -8,11 +8,6 @@ import javafx.scene.control.ToggleGroup; import javafx.scene.image.Image; import javafx.scene.image.ImageView; -import javafx.scene.layout.Background; -import javafx.scene.layout.BackgroundImage; -import javafx.scene.layout.BackgroundPosition; -import javafx.scene.layout.BackgroundRepeat; -import javafx.scene.layout.BackgroundSize; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.StackPane; @@ -25,10 +20,10 @@ public class StartView { private final TextField usernameField = new TextField(); private final Button loginButton = new Button("→"); private final ToggleGroup startingMoneyGroup = new ToggleGroup(); + private final StackPane root = new StackPane(); public StackPane getRoot() { - StackPane root = new StackPane(); // User input content VBox loginContainer = new VBox(20); @@ -46,10 +41,11 @@ public StackPane getRoot() { avatarContainer.getChildren().add(logoView); avatarContainer.setMaxWidth(130); + // Username Label usernameLabel = new Label("State your name, G"); usernameLabel.getStyleClass().add("difficulty-label"); - usernameLabel.setStyle("-fx-font-size: 18px;"); + // Login Input HBox loginInputBox = new HBox(); loginInputBox.setAlignment(Pos.CENTER_LEFT); loginInputBox.getStyleClass().add("login-input-box"); @@ -60,25 +56,28 @@ public StackPane getRoot() { loginButton.getStyleClass().add("login-submit-button"); loginInputBox.getChildren().addAll(usernameField, loginButton); + // Starting Money Label Label startingMoneyLabel = new Label("How much matrix money?"); startingMoneyLabel.getStyleClass().add("difficulty-label"); VBox startingMoneyOptions = new VBox(10); startingMoneyOptions.setAlignment(Pos.CENTER); + // Starting Money Options RadioButton easyCheck = new RadioButton("Easy ($1000)"); RadioButton mediumCheck = new RadioButton("Medium ($100)"); RadioButton hardCheck = new RadioButton("Hard ($0)"); - easyCheck.getStyleClass().add("difficulty-label"); mediumCheck.getStyleClass().add("difficulty-label"); hardCheck.getStyleClass().add("difficulty-label"); - easyCheck.setToggleGroup(startingMoneyGroup); mediumCheck.setToggleGroup(startingMoneyGroup); hardCheck.setToggleGroup(startingMoneyGroup); + startingMoneyOptions.getChildren().addAll(easyCheck, mediumCheck, hardCheck); - loginContainer.getChildren().addAll(avatarContainer, usernameLabel, loginInputBox, startingMoneyLabel, startingMoneyOptions); + loginContainer.getChildren().addAll( + avatarContainer, usernameLabel, loginInputBox, startingMoneyLabel, startingMoneyOptions + ); root.getChildren().add(loginContainer); root.getStyleClass().add("login-root"); @@ -86,10 +85,16 @@ public StackPane getRoot() { return root; } + public TextField getUsernameField() { return usernameField; } + /** + * Getter for the difficulty mode the user has selected. + * @return Difficulty + * + */ public String getSelectedMode() { RadioButton selectedMode = (RadioButton) startingMoneyGroup.getSelectedToggle(); if (selectedMode == null) { @@ -97,6 +102,7 @@ public String getSelectedMode() { } return selectedMode.getText(); } + public Button getLoginButton() { return loginButton; } diff --git a/src/main/resources/css/apps.css b/src/main/resources/css/apps.css index 53a2a3a..3216f29 100644 --- a/src/main/resources/css/apps.css +++ b/src/main/resources/css/apps.css @@ -5,7 +5,7 @@ -fx-border-color: #f0f0f0; -fx-border-width: 0 0 1 0; -fx-cursor: hand; - -fx-background-color: transparent !important; + -fx-background-color: transparent; } .stock-symbol { @@ -145,7 +145,7 @@ } .portfolio-list .list-cell, .stock-list .list-cell { - -fx-background-color: transparent !important; + -fx-background-color: transparent; } .portfolio-list .list-cell:hover, .stock-list .list-cell:hover {