diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/SettingsAppController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/SettingsAppController.java new file mode 100644 index 0000000..74a4a52 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/AppControllers/SettingsAppController.java @@ -0,0 +1,36 @@ +package edu.ntnu.idi.idatt2003.gruppe42.Controller.AppControllers; + +import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.SettingsApp; +import java.nio.file.Path; + +public class SettingsAppController implements AppController { + + private SettingsApp settingsApp; + private Path userSelectedPath; + private Runnable onUserSelection; + + public SettingsAppController(SettingsApp settingsApp) { + this.settingsApp = settingsApp; + + if (!settingsApp.isLoggedIn()) { + settingsApp.getOpenFileChooserButton().setOnAction(event -> { + userSelectedPath = settingsApp.getFileChooser().showOpenDialog(settingsApp.getRoot().getScene().getWindow()).toPath(); + System.out.println(userSelectedPath.toString()); + onUserSelection.run(); + }); + } + } + + public Path getUserSelectedPath() { + return userSelectedPath; + } + + public void setOnUserPathSelected(Runnable callback) { + onUserSelection = callback; + } + + @Override + public void nextTick() { + + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/MarketController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/MarketController.java index 53d3408..8634cf7 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/MarketController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/MarketController.java @@ -22,12 +22,16 @@ public final class MarketController { /** * Constructs a new MarketController and starts the market. */ - public MarketController() { + public MarketController(Path userSelectedPath) { this.stockResolution = 120; - + System.out.println(userSelectedPath); try { Path path = Path.of(Objects.requireNonNull(getClass().getClassLoader() - .getResource("stocks.csv")).toURI()); + .getResource("stocks.csv")).toURI()); + if (userSelectedPath != null) { + path = userSelectedPath; + System.out.println(path); + } exchange = new Exchange(StockFileHandler.readFromFile(path)); startMarket(); 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 index 37c76f8..4aa95d6 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupsController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/PopupsController.java @@ -5,6 +5,8 @@ import edu.ntnu.idi.idatt2003.gruppe42.Model.App; import edu.ntnu.idi.idatt2003.gruppe42.View.Popup; import java.util.List; +import java.util.Optional; + import javafx.scene.control.Button; import javafx.scene.layout.Pane; import javafx.scene.layout.StackPane; @@ -52,10 +54,6 @@ public boolean hide(Popup popup) { return true; } - public List getPopups() { - return popups; - } - public void bindOpenButton(Button button, App type) { button.setOnAction(event -> show(type)); } @@ -79,4 +77,22 @@ private void makeDraggable(Popup popup) { root.setLayoutY(Math.max(0, Math.min(event.getSceneY() - offset[1], maxXY[1]))); }); } + + public void addPopups(List popups) { + popups.forEach(this::addPopup); + } + + public void addPopup(Popup popup) { + initPopup(popup); + this.popups.add(popup); + } + + public Popup getPopup(App type) { + Optional match = popups.stream().filter(popup -> popup.getType().equals(type)).findFirst(); + return match.orElse(null); + } + + public List getPopups() { + return popups; + } } \ 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 64037c0..a4ff879 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 @@ -2,6 +2,7 @@ import edu.ntnu.idi.idatt2003.gruppe42.Controller.AppControllers.AppStoreController; import edu.ntnu.idi.idatt2003.gruppe42.Controller.AppControllers.BankAppController; +import edu.ntnu.idi.idatt2003.gruppe42.Controller.AppControllers.SettingsAppController; 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; @@ -13,19 +14,12 @@ import edu.ntnu.idi.idatt2003.gruppe42.Model.Transaction.Purchase; import edu.ntnu.idi.idatt2003.gruppe42.Model.Transaction.Sale; import edu.ntnu.idi.idatt2003.gruppe42.Model.Transaction.Transaction; -import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.AppStoreApp; -import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.BankApp; -import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.GameOverApp; -import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.HustlersApp; -import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.MailApp; -import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.NewsApp; -import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.StockApp; -import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.WarningApp; -import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.WeekendRapportApp; +import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.*; import edu.ntnu.idi.idatt2003.gruppe42.View.Popup; import edu.ntnu.idi.idatt2003.gruppe42.View.Views.DesktopView; import edu.ntnu.idi.idatt2003.gruppe42.View.Views.DesktopView.ModalLayer; import java.math.BigDecimal; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import javafx.application.Platform; @@ -61,12 +55,12 @@ public final class DesktopViewController { private Runnable onGameOver; - public DesktopViewController(final Player player, final GameController gameController) { + public DesktopViewController(final Player player, final GameController gameController, final Path userSelectedPath, final PopupsController popupsController) { this.player = player; this.timeAndWeatherController = new TimeAndWeatherController(gameController); gameController.addAppController(timeAndWeatherController); - this.marketController = new MarketController(); + this.marketController = new MarketController(userSelectedPath); AppStoreApp appStoreApp = new AppStoreApp(); @@ -84,6 +78,9 @@ public DesktopViewController(final Player player, final GameController gameContr BankApp bankApp = new BankApp(); gameController.addAppController(new BankAppController(bankApp, player)); + SettingsApp settingsApp = (SettingsApp) popupsController.getPopup(App.SETTINGS); + settingsApp.setLoggedIn(true); + List popups = new ArrayList<>(); popups.add(appStoreApp); popups.add(hustlersApp); @@ -92,7 +89,8 @@ public DesktopViewController(final Player player, final GameController gameContr popups.add(newsApp); popups.add(bankApp); - this.popupsController = new PopupsController(popups); + this.popupsController = popupsController; + this.popupsController.addPopups(popups); bankApp.setOnShareSelected(share -> { popupsController.show(App.STOCK); @@ -132,6 +130,7 @@ public DesktopViewController(final Player player, final GameController gameContr wireGameOver(); desktopView.getNextWeekButton().setOnAction(event -> handleAdvanceWeek()); + desktopView.getSettingsButton().setOnAction(event -> popupsController.show(App.SETTINGS)); timeAndWeatherController.dayIndexProperty().addListener((obs, oldDay, newDay) -> { int day = newDay.intValue(); diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/ViewControllers/StartViewController.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/ViewControllers/StartViewController.java index 4859916..ac27a27 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/ViewControllers/StartViewController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Controller/ViewControllers/StartViewController.java @@ -1,9 +1,17 @@ package edu.ntnu.idi.idatt2003.gruppe42.Controller.ViewControllers; +import edu.ntnu.idi.idatt2003.gruppe42.Controller.AppControllers.SettingsAppController; +import edu.ntnu.idi.idatt2003.gruppe42.Controller.PopupsController; import edu.ntnu.idi.idatt2003.gruppe42.Millions; +import edu.ntnu.idi.idatt2003.gruppe42.Model.App; import edu.ntnu.idi.idatt2003.gruppe42.Model.Difficulty; +import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.SettingsApp; import edu.ntnu.idi.idatt2003.gruppe42.View.Apps.WarningApp; +import edu.ntnu.idi.idatt2003.gruppe42.View.Popup; import edu.ntnu.idi.idatt2003.gruppe42.View.Views.StartView; + +import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.Random; @@ -18,6 +26,9 @@ public class StartViewController { private final StartView startView; private final Millions application; + private final PopupsController popupsController; + private Path userSelectedPath; + private SettingsAppController settingsAppController; private static final List TATE_NAMES = List.of( "Top G", @@ -42,9 +53,17 @@ public StartViewController(final Millions application, final StartView startView this.application = application; this.startView = startView; + List popups = new ArrayList<>(); + + SettingsApp settingsApp = new SettingsApp(false); + settingsAppController = new SettingsAppController(settingsApp); + WarningApp warningApp = new WarningApp(); warningApp.centerInParent(); - startView.getRoot().getChildren().add(warningApp.getRoot()); + + startView.getRoot().getChildren().addAll(settingsApp.getRoot(), warningApp.getRoot()); + + settingsAppController.setOnUserPathSelected(this::updateUserSelectedPath); warningApp.configure( "⚠", @@ -52,9 +71,14 @@ public StartViewController(final Millions application, final StartView startView "Choose how much starting money you want before jumping in.", "Got it" ); - warningApp.getPrimaryButton().setOnAction(e -> - warningApp.getRoot().setVisible(false) - ); + + popups.add(settingsApp); + popups.add(warningApp); + popupsController = new PopupsController(popups); + + warningApp.getPrimaryButton().setOnAction(e -> { + popupsController.hide(warningApp); + }); startView.getUsernameField().textProperty().addListener( (obs, old, newValue) -> username = newValue @@ -62,12 +86,15 @@ public StartViewController(final Millions application, final StartView startView startView.getLoginButton().setOnAction(event -> { if (startView.getSelectedMode() == null) { - warningApp.show(); - warningApp.getRoot().toFront(); + popupsController.show(App.WARNING); return; } handleStart(); }); + + startView.getSettingsButton().setOnAction(actionEvent -> { + popupsController.show(App.SETTINGS); + }); } private void handleStart() { @@ -83,7 +110,7 @@ private void handleStart() { } } - application.initGame(resolvedName, difficulty); + application.initGame(resolvedName, difficulty, userSelectedPath, popupsController); } private String resolveUsername(final String input) { @@ -96,4 +123,8 @@ private String resolveUsername(final String input) { private boolean isValidName(final String value) { return value.matches("[a-zA-Z0-9]+"); } + + private void updateUserSelectedPath() { + userSelectedPath = settingsAppController.getUserSelectedPath(); + } } 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 50f3db7..d571c15 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Millions.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Millions.java @@ -1,6 +1,7 @@ package edu.ntnu.idi.idatt2003.gruppe42; import edu.ntnu.idi.idatt2003.gruppe42.Controller.GameController; +import edu.ntnu.idi.idatt2003.gruppe42.Controller.PopupsController; import edu.ntnu.idi.idatt2003.gruppe42.Controller.ViewControllers.DesktopViewController; import edu.ntnu.idi.idatt2003.gruppe42.Controller.ViewControllers.StartViewController; import edu.ntnu.idi.idatt2003.gruppe42.Model.Difficulty; @@ -12,6 +13,8 @@ import javafx.scene.Scene; import javafx.stage.Stage; +import java.nio.file.Path; + /** * JavaFX application entry point. * @@ -47,12 +50,12 @@ public void start(final Stage stage) { * Begins a brand-new game session. Called by the start screen once the * user has chosen a difficulty. */ - public void initGame(final String username, final Difficulty difficulty) { + public void initGame(final String username, final Difficulty difficulty, Path userSelectedPath, PopupsController popupsController) { player = GameFactory.createPlayer(username, difficulty); gameController = new GameController(); gameController.startGame(); - desktopViewController = new DesktopViewController(player, gameController); + desktopViewController = new DesktopViewController(player, gameController, userSelectedPath, popupsController); desktopViewController.setOnGameOver(this::resetGame); desktopView = desktopViewController.getDesktopView(); scene.setRoot(desktopView.getRoot()); diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/App.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/App.java index e1ad0ea..9925085 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/App.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/Model/App.java @@ -10,6 +10,7 @@ public enum App { MAIL("Mail"), NEWS("News"), BANK("Bank"), + SETTINGS("Settings"), WEEKENDRAPPORT("Weekend Rapport"), WARNING("Warning"), GAMEOVER("Game Over"); diff --git a/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Apps/SettingsApp.java b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Apps/SettingsApp.java new file mode 100644 index 0000000..cd84a00 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/gruppe42/View/Apps/SettingsApp.java @@ -0,0 +1,51 @@ +package edu.ntnu.idi.idatt2003.gruppe42.View.Apps; + +import edu.ntnu.idi.idatt2003.gruppe42.Model.App; +import edu.ntnu.idi.idatt2003.gruppe42.View.Popup; +import javafx.scene.control.Button; +import javafx.stage.FileChooser; + +public class SettingsApp extends Popup { + + private Button openFileChooserButton; + private FileChooser fileChooser; + private boolean isLoggedIn; + + public SettingsApp(boolean isLoggedIn) { + super(720, 480, 80, 60, App.SETTINGS); + this.isLoggedIn = isLoggedIn; + updateContent(); + } + + public Button getOpenFileChooserButton() { + return openFileChooserButton; + } + + public FileChooser getFileChooser() { + return fileChooser; + } + + public boolean isLoggedIn() { + return isLoggedIn; + } + + public void setLoggedIn(boolean status) { + this.isLoggedIn = status; + updateContent(); + } + + public void updateContent() { + if (!isLoggedIn) { + openFileChooserButton = new Button("Import stock file"); + fileChooser = new FileChooser(); + fileChooser.setTitle("Select .csv stock file"); + fileChooser.getExtensionFilters().addAll( + new FileChooser.ExtensionFilter("CSV files","*.csv")); + + content.getChildren().setAll(openFileChooserButton); + } else { + //TODO: settings in desktopView + content.getChildren().setAll(); + } + } +} 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 44b0d3f..63c2109 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 @@ -70,6 +70,7 @@ public enum ModalLayer { RAPPORT, WARNING, GAME_OVER } private final EnumSet activeLayers = EnumSet.noneOf(ModalLayer.class); private Button nextWeekButton; + private Button settingsButton; public DesktopView(final DesktopViewController controller) { this.controller = controller; @@ -298,7 +299,7 @@ private static boolean isDesktopApp(final App app) { // Bottom bar private HBox createBottomBar() { - Button settingsButton = new Button("⚙"); + settingsButton = new Button("⚙"); settingsButton.getStyleClass().add("desktop-settings-button"); settingsButton.setOnAction(e -> controller.handleSettings()); @@ -413,4 +414,8 @@ private String resource(final String path) { public Button getNextWeekButton() { return nextWeekButton; } + + public Button getSettingsButton() { + return settingsButton; + } } \ 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 d48e6ac..527c5e0 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,10 +8,7 @@ import javafx.scene.control.ToggleGroup; import javafx.scene.image.Image; import javafx.scene.image.ImageView; -import javafx.scene.layout.HBox; -import javafx.scene.layout.Priority; -import javafx.scene.layout.StackPane; -import javafx.scene.layout.VBox; +import javafx.scene.layout.*; import java.util.Objects; @@ -24,11 +21,13 @@ public class StartView { private final TextField usernameField = new TextField(); private final Button loginButton = new Button("→"); + private Button settingsButton; private final ToggleGroup startingMoneyGroup = new ToggleGroup(); - private final StackPane root = new StackPane(); + private final StackPane content = new StackPane(); + private final BorderPane root = new BorderPane(); - public StackPane getRoot() { + public BorderPane getRoot() { if (!root.getChildren().isEmpty()) { return root; // already built } @@ -87,18 +86,22 @@ public StackPane getRoot() { avatarContainer, usernameLabel, loginInputBox, startingMoneyLabel, startingMoneyOptions ); - root.getChildren().add(loginContainer); - root.getStyleClass().add("login-root"); + settingsButton = new Button("⚙"); + settingsButton.getStyleClass().add("desktop-settings-button"); + root.setBottom(settingsButton); + + content.getChildren().add(loginContainer); + content.getStyleClass().add("login-root"); loadStylesheets(); // DEV_CSS_RELOAD: press R to hot-reload CSS from source without restarting if (DEV_CSS_RELOAD) { - root.setFocusTraversable(true); - root.sceneProperty().addListener((obs, oldScene, newScene) -> { - if (newScene != null) root.requestFocus(); + content.setFocusTraversable(true); + content.sceneProperty().addListener((obs, oldScene, newScene) -> { + if (newScene != null) content.requestFocus(); }); - root.setOnKeyPressed(event -> { + content.setOnKeyPressed(event -> { if (event.getCode() == javafx.scene.input.KeyCode.R) { loadStylesheets(); System.out.println("[CSS] Stylesheets reloaded"); @@ -106,6 +109,7 @@ public StackPane getRoot() { }); } + root.setCenter(content); return root; } @@ -158,4 +162,8 @@ public String getSelectedMode() { public Button getLoginButton() { return loginButton; } + + public Button getSettingsButton() { + return settingsButton; + } } \ No newline at end of file