From 2325e369e399c1f1e2506a38dd288419d7f1b005 Mon Sep 17 00:00:00 2001 From: Per Eric Trapnes Date: Wed, 15 Apr 2026 09:26:24 +0200 Subject: [PATCH] add Grid to desktop, buttons in grid with functionality: can be moved in grid and opens popup when pressed --- .../gruppe42/Controller/AppController.java | 130 ++++++++++++++++++ .../gruppe42/Controller/PopupController.java | 9 +- .../Controller/StartViewController.java | 8 +- .../ntnu/idi/idatt2003/gruppe42/Millions.java | 5 +- .../idi/idatt2003/gruppe42/Model/Apps.java | 10 ++ .../idatt2003/gruppe42/View/DesktopView.java | 110 ++++++++++----- .../gruppe42/View/Popups/AppStorePopup.java | 20 +++ .../gruppe42/View/Popups/BankPopup.java | 20 +++ .../gruppe42/View/Popups/HustlersPopup.java | 20 +++ .../gruppe42/View/Popups/MailPopup.java | 20 +++ .../gruppe42/View/Popups/NewsPopup.java | 20 +++ .../gruppe42/View/Popups/StockPopup.java | 20 +++ 12 files changed, 351 insertions(+), 41 deletions(-) create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppController.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/Apps.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/AppStorePopup.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/BankPopup.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/HustlersPopup.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/MailPopup.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/NewsPopup.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/StockPopup.java diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppController.java new file mode 100644 index 0000000..801233b --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppController.java @@ -0,0 +1,130 @@ +package edu.ntnu.idi.idatt2003.gruppe42.Controller; + +import edu.ntnu.idi.idatt2003.gruppe42.Model.Apps; +import edu.ntnu.idi.idatt2003.gruppe42.View.Popups.AppStorePopup; +import edu.ntnu.idi.idatt2003.gruppe42.View.Popups.BankPopup; +import edu.ntnu.idi.idatt2003.gruppe42.View.Popups.HustlersPopup; +import edu.ntnu.idi.idatt2003.gruppe42.View.Popups.MailPopup; +import edu.ntnu.idi.idatt2003.gruppe42.View.Popups.NewsPopup; +import edu.ntnu.idi.idatt2003.gruppe42.View.Popups.Popup; +import edu.ntnu.idi.idatt2003.gruppe42.View.Popups.StockPopup; +import javafx.beans.binding.Bindings; +import javafx.scene.control.Button; +import javafx.scene.input.ClipboardContent; +import javafx.scene.input.Dragboard; +import javafx.scene.input.TransferMode; +import javafx.scene.layout.Pane; +import javafx.scene.layout.Region; +import javafx.scene.layout.StackPane; + +/** + * Controller for the app buttons. + * Handles app button creation, resizing, click events, and drag-and-drop. + */ +public class AppController { + private final PopupController popupController; + private final Pane parent; + + /** + * Constructs a new app controller. + * + * @param popupController the popup controller to manage popups. + * @param parent the parent pane to add popups to. + */ + public AppController(PopupController popupController, Pane parent) { + this.popupController = popupController; + this.parent = parent; + } + + /** + * Creates an app button with click and drag functionality. + * + * @param type the type of the app. + * @return the app button. + */ + public Button createAppButton(Apps type) { + Button button = new Button(type.toString()); + button.setMinSize(0, 0); + + // Bind button size to parent dimensions to keep it square and responsive + button.parentProperty().addListener((observable, oldParent, newParent) -> { + if (newParent instanceof Region region) { + button.prefWidthProperty().bind( + Bindings.min( + region.widthProperty().multiply(0.8), + region.heightProperty()).multiply(0.8)); + button.prefHeightProperty().bind(button.prefWidthProperty()); + } else { + button.prefWidthProperty().unbind(); + button.prefHeightProperty().unbind(); + } + }); + + // Print when clicked and open popup + button.setOnAction(event -> { + System.out.println("button pressed: " + type); + openPopup(type); + }); + + // Handle start of drag: initiate drag-and-drop + button.setOnDragDetected(event -> { + Dragboard dragboard = button.startDragAndDrop(TransferMode.MOVE); + dragboard.setDragView(button.snapshot(null, null)); + dragboard.setDragViewOffsetX(event.getX()); + dragboard.setDragViewOffsetY(event.getY()); + ClipboardContent clipboardContent = new ClipboardContent(); + clipboardContent.putString("app_button"); + dragboard.setContent(clipboardContent); + event.consume(); + }); + + return button; + } + + /** + * Opens the correct popup based on the app type. + * + * @param type the app type. + */ + private void openPopup(Apps type) { + Popup popup = switch (type) { + case APPSTORE -> new AppStorePopup(400, 300, 100, 100); + case HUSTLERS -> new HustlersPopup(400, 300, 140, 140); + case STOCK -> new StockPopup(400, 300, 200, 200); + case MAIL -> new MailPopup(400, 300, 160, 160); + case NEWS -> new NewsPopup(400, 300, 180, 180); + case BANK -> new BankPopup(400, 300, 120, 120); + }; + + if (popupController.add(popup)) { + parent.getChildren().add(popup.getRoot()); + } + } + + /** + * Configures a cell to be a drop target for app buttons. + * + * @param cell the stack pane cell to configure. + */ + public void configureCellAsDropTarget(StackPane cell) { + // Handle drag over cell: allow drop if cell is empty + cell.setOnDragOver(event -> { + if (event.getGestureSource() instanceof Button && cell.getChildren().isEmpty()) { + event.acceptTransferModes(TransferMode.MOVE); + } + event.consume(); + }); + + // Handle drop on cell: move the button to this cell + cell.setOnDragDropped(event -> { + boolean success = false; + if (event.getGestureSource() instanceof Button button) { + ((StackPane) button.getParent()).getChildren().remove(button); + cell.getChildren().add(button); + success = true; + } + event.setDropCompleted(success); + event.consume(); + }); + } +} 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 index be1164d..c4f07e2 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupController.java @@ -30,9 +30,9 @@ public boolean add(Popup popup) { if (popup == null || popups.contains(popup)) { return false; } - popup.getCloseButton().setOnAction(e -> remove(popup)); - popup.getRoot().setOnMousePressed(e -> bringToFront(popup)); - popup.getContent().setOnMousePressed(e -> bringToFront(popup)); + popup.getCloseButton().setOnAction(event -> remove(popup)); + popup.getRoot().setOnMousePressed(event -> bringToFront(popup)); + popup.getContent().setOnMousePressed(event -> bringToFront(popup)); return popups.add(popup); } @@ -64,8 +64,7 @@ public void bringToFront(Popup popup) { } /** - * Checks if a popup is out of bounds and moves it back if necessary. - * + * Checks if a popup is out of bounds and moves it back if necessary * @param popup the popup to check */ public void keepInBounds(Popup popup) { diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/StartViewController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/StartViewController.java index 0d0e8a8..d9e8da9 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/StartViewController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/StartViewController.java @@ -1,5 +1,6 @@ package edu.ntnu.idi.idatt2003.gruppe42.Controller; +import edu.ntnu.idi.idatt2003.gruppe42.Millions; import edu.ntnu.idi.idatt2003.gruppe42.Model.Player; import edu.ntnu.idi.idatt2003.gruppe42.View.StartView; import java.math.BigDecimal; @@ -8,9 +9,11 @@ public class StartViewController { private String username = ""; private final StartView startView; + private final Millions application; - public StartViewController(StartView startView) { + public StartViewController(Millions application, StartView startView) { + this.application = application; this.startView = startView; startView.getUsernameField().textProperty().addListener((obs, old, newValue) -> { @@ -19,7 +22,7 @@ public StartViewController(StartView startView) { } }); - startView.getLoginButton().setOnAction(e -> handleStart()); + startView.getLoginButton().setOnAction(event -> handleStart()); } private void handleStart() { @@ -27,6 +30,7 @@ private void handleStart() { Player player = new Player(username, money); System.out.println(player.getMoney()); + application.switchToDesktopView(); } private boolean isValidName(String value) { 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 44185a8..c9cfd38 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Millions.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Millions.java @@ -18,16 +18,15 @@ public void start(Stage stage) throws Exception { this.stage = stage; StartView startView = new StartView(); - new StartViewController(startView); + new StartViewController(this, startView); scene = new Scene(startView.getRoot(), 900, 700); stage.setTitle("Millions"); stage.setScene(scene); stage.setFullScreen(true); + stage.setFullScreenExitHint(""); stage.show(); - - switchToDesktopView(); } public void switchToStartView() { diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/Apps.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/Apps.java new file mode 100644 index 0000000..ed3967d --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/Apps.java @@ -0,0 +1,10 @@ +package edu.ntnu.idi.idatt2003.gruppe42.Model; + +public enum Apps { + APPSTORE, + HUSTLERS, + STOCK, + MAIL, + NEWS, + BANK +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/DesktopView.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/DesktopView.java index 52735a7..ad94a51 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/DesktopView.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/DesktopView.java @@ -1,47 +1,95 @@ package edu.ntnu.idi.idatt2003.gruppe42.View; +import edu.ntnu.idi.idatt2003.gruppe42.Controller.AppController; import edu.ntnu.idi.idatt2003.gruppe42.Controller.PopupController; -import edu.ntnu.idi.idatt2003.gruppe42.View.Popups.Popup; -import edu.ntnu.idi.idatt2003.gruppe42.View.Popups.SimplePopup; +import edu.ntnu.idi.idatt2003.gruppe42.Model.Apps; +import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.layout.BorderPane; -import javafx.scene.layout.Pane; -import java.util.Random; +import javafx.scene.layout.ColumnConstraints; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.Priority; +import javafx.scene.layout.RowConstraints; +import javafx.scene.layout.StackPane; +/** + * View for the desktop. + * Displays a 6x4 grid of apps. + */ public class DesktopView { - private PopupController popupController; + private final PopupController popupController; + private final AppController appController; + private final BorderPane root; + private static final int COLS = 6; + private static final int ROWS = 4; public DesktopView() { - popupController = new PopupController(); + this.popupController = new PopupController(); + this.root = new BorderPane(); + this.appController = new AppController(popupController, root); } + /** + * Returns the root of the desktop view. + * + * @return the root of the desktop view. + */ public BorderPane getRoot() { - - BorderPane root = new BorderPane(); - Pane center = new Pane(); - - Button button = new Button("Add"); - Random random = new Random(); - button.setOnAction(e -> { - int width = random.nextInt(400) + 100; - int height = random.nextInt(400) + 100; - int x = random.nextInt(1000); - int y = random.nextInt(700); - Popup popup = new SimplePopup(width, height, x, y); - center.getChildren().add(popup.getRoot()); - popupController.add(popup); - popupController.keepInBounds(popup); - - popup.getRoot().setOnMouseDragged(event -> { - popupController.keepInBounds(popup); - }); - }); - - center.getChildren().add(button); - //center.getChildren().addAll(popupController.getPopups().stream().map(Popup::getRoot).toList()); - root.setCenter(center); - + GridPane grid = createGrid(); + root.setCenter(grid); return root; } + + /** + * Creates the 6x4 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 of the screen + for (int col = 0; col < COLS; col++) { + ColumnConstraints colConstraints = new ColumnConstraints(); + colConstraints.setPercentWidth(100.0 / COLS); + colConstraints.setHgrow(Priority.ALWAYS); + grid.getColumnConstraints().add(colConstraints); + } + for (int row = 0; row < ROWS; row++) { + RowConstraints rowConstraints = new RowConstraints(); + rowConstraints.setPercentHeight(100.0 / ROWS); + rowConstraints.setVgrow(Priority.ALWAYS); + grid.getRowConstraints().add(rowConstraints); + } + + 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 < Apps.values().length) { + cell.getChildren().add(appController.createAppButton(Apps.values()[col])); + } + } + } + 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(); + cell.setStyle("-fx-border-color: black; -fx-border-width: 1;"); + appController.configureCellAsDropTarget(cell); + return cell; + } + } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/AppStorePopup.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/AppStorePopup.java new file mode 100644 index 0000000..0cb2938 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/AppStorePopup.java @@ -0,0 +1,20 @@ +package edu.ntnu.idi.idatt2003.gruppe42.View.Popups; + +/** + * A popup for the AppStore app. + */ +public class AppStorePopup extends Popup { + + /** + * Constructs a new AppStore 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 + */ + public AppStorePopup(int width, int height, int x, int y) { + super(width, height, x, y); + // Add AppStore specific content here + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/BankPopup.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/BankPopup.java new file mode 100644 index 0000000..96c2a51 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/BankPopup.java @@ -0,0 +1,20 @@ +package edu.ntnu.idi.idatt2003.gruppe42.View.Popups; + +/** + * A popup for the Bank app. + */ +public class BankPopup extends Popup { + + /** + * Constructs a new Bank 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 + */ + public BankPopup(int width, int height, int x, int y) { + super(width, height, x, y); + // Add Bank specific content here + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/HustlersPopup.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/HustlersPopup.java new file mode 100644 index 0000000..0e2148a --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/HustlersPopup.java @@ -0,0 +1,20 @@ +package edu.ntnu.idi.idatt2003.gruppe42.View.Popups; + +/** + * A popup for the Hustlers app. + */ +public class HustlersPopup extends Popup { + + /** + * Constructs a new Hustlers 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 + */ + public HustlersPopup(int width, int height, int x, int y) { + super(width, height, x, y); + // Add Hustlers specific content here + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/MailPopup.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/MailPopup.java new file mode 100644 index 0000000..b5ec21f --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/MailPopup.java @@ -0,0 +1,20 @@ +package edu.ntnu.idi.idatt2003.gruppe42.View.Popups; + +/** + * A popup for the Mail app. + */ +public class MailPopup extends Popup { + + /** + * Constructs a new Mail 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 + */ + public MailPopup(int width, int height, int x, int y) { + super(width, height, x, y); + // Add Mail specific content here + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/NewsPopup.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/NewsPopup.java new file mode 100644 index 0000000..03dee1f --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/NewsPopup.java @@ -0,0 +1,20 @@ +package edu.ntnu.idi.idatt2003.gruppe42.View.Popups; + +/** + * A popup for the News app. + */ +public class NewsPopup extends Popup { + + /** + * Constructs a new News 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 + */ + public NewsPopup(int width, int height, int x, int y) { + super(width, height, x, y); + // Add News specific content here + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/StockPopup.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/StockPopup.java new file mode 100644 index 0000000..059fe80 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Popups/StockPopup.java @@ -0,0 +1,20 @@ +package edu.ntnu.idi.idatt2003.gruppe42.View.Popups; + +/** + * A popup for the Stock app. + */ +public class StockPopup extends Popup { + + /** + * Constructs a new Stock 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 + */ + public StockPopup(int width, int height, int x, int y) { + super(width, height, x, y); + // Add Stock specific content here + } +}