diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java index 0e2d3cb..5453765 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java @@ -25,6 +25,8 @@ import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.dashboard.DashBoardView; import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.market.MarketController; import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.market.MarketView; +import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.minigames.MiniGamesController; +import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.minigames.MiniGamesView; import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.stats.StatsController; import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.stats.StatsView; import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.topbar.TopBarController; @@ -139,6 +141,13 @@ public void start(final Stage stage) throws Exception { eventManager, player.getTransactionArchive()); + MiniGamesView miniGamesView = new MiniGamesView(); + new MiniGamesController( + miniGamesView, + eventManager, + stocksInFile.getFirst() + ); + // Wire top bar buttons til å bytte mellom dashboard / stats / market / // transactions. Stats-knappen tar deg til stats-siden. topBarController.setMarketIntegration( @@ -147,7 +156,9 @@ public void start(final Stage stage) throws Exception { marketView.getRootPane(), statsView.getRootPane(), transactionsView.getRootPane(), - transactionsController::refresh); + transactionsController::refresh, + miniGamesView.getRootPane() + ); // Register all views viewManager.addView(mainMenuView); diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesActions.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesActions.java new file mode 100644 index 0000000..d2c4de6 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesActions.java @@ -0,0 +1,26 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.minigames; + +/** + * Action set for the associated {@link MiniGamesView}. + * */ +public enum MiniGamesActions { + /** + * Action when selecting clicker game. + * */ + CLICKER_GAME, + + /** + * Action when selecting "find stock" game. + * */ + FIND_STOCK, + + /** + * Action when selecting "time click" game. + * */ + TIME_CLICKS, + + /** + * Action when clicking the question mark box (help section). + * */ + HELP +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesController.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesController.java new file mode 100644 index 0000000..1ebb07a --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesController.java @@ -0,0 +1,62 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.minigames; + +import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock; +import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventManager; +import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewController; + +/** + * Controller class for the associated {@link MiniGamesView} object. + * + *

Extends {@link ViewController}

+ * */ +public final class MiniGamesController extends ViewController { + private Stock activeStock; + + public MiniGamesController(final MiniGamesView viewElement, + final EventManager eventManager, + final Stock initialStock) { + super(viewElement, eventManager); + this.activeStock = initialStock; + refresh(); + } + + @Override + protected void initInteractions() { + getViewElement().setOnAction(MiniGamesActions.HELP, () -> { + // Implement help dialog or print logic + }); + + getViewElement().setOnAction(MiniGamesActions.CLICKER_GAME, () -> { + // Logic for launching Clicker Game + }); + + getViewElement().setOnAction(MiniGamesActions.FIND_STOCK, () -> { + // Logic for launching Find Stock Game + }); + + getViewElement().setOnAction(MiniGamesActions.TIME_CLICKS, () -> { + // Logic for launching Time Clicks Game + }); + } + + /** + * Sets the target stock context for the minigames. + * + * @param stock Chosen active layout context stock. + */ + public void setActiveStock(final Stock stock) { + this.activeStock = stock; + refresh(); + } + + /** + * Syncs the current model status with view text properties. + */ + public void refresh() { + if (activeStock != null) { + getViewElement().setSelectedStockText(activeStock.getSymbol()); + } else { + getViewElement().setSelectedStockText("None"); + } + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesView.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesView.java new file mode 100644 index 0000000..5d9ac4d --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesView.java @@ -0,0 +1,120 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.minigames; + +import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewElement; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; + +/** + * Minigames view in the in game section of the application. + * */ +public final class MiniGamesView extends ViewElement { + + private HBox headerBar; + private HBox gamesContainer; + + private Label titleLabel; + private Label selectedStockLabel; + private Label stockValueLabel; + + private Button helpBtn; + private Button clickerGameBtn; + private Button findStockBtn; + private Button timeClicksBtn; + + /** + * Constructor. + */ + public MiniGamesView() throws IllegalArgumentException { + super(new VBox(), MiniGamesActions.class); + } + + @Override + protected void initLayout() { + // Top header layout + headerBar = new HBox(); + headerBar.setAlignment(Pos.TOP_LEFT); + + VBox titleSection = new VBox(); + titleLabel = new Label("Mini games"); + + HBox stockSelectionRow = new HBox(); + stockSelectionRow.setAlignment(Pos.CENTER_LEFT); + selectedStockLabel = new Label("Selected stock: "); + stockValueLabel = new Label("AAPL"); + stockSelectionRow.getChildren().addAll(selectedStockLabel, stockValueLabel); + + titleSection.getChildren().addAll(titleLabel, stockSelectionRow); + + Region topSpacer = new Region(); + HBox.setHgrow(topSpacer, Priority.ALWAYS); + + helpBtn = new Button("?"); + headerBar.getChildren().addAll(titleSection, topSpacer, helpBtn); + + // Main central row container for games + gamesContainer = new HBox(); + gamesContainer.setAlignment(Pos.CENTER); + + clickerGameBtn = new Button("Clicker game"); + findStockBtn = new Button("Find correct\nstock"); + timeClicksBtn = new Button("Time your clicks"); + + // Make buttons fill equal proportions + HBox.setHgrow(clickerGameBtn, Priority.ALWAYS); + HBox.setHgrow(findStockBtn, Priority.ALWAYS); + HBox.setHgrow(timeClicksBtn, Priority.ALWAYS); + + // Equal constraints on dimensions + configureGameButton(clickerGameBtn); + configureGameButton(findStockBtn); + configureGameButton(timeClicksBtn); + + gamesContainer.getChildren().addAll(clickerGameBtn, findStockBtn, timeClicksBtn); + + // Assemble view layers + VBox.setVgrow(gamesContainer, Priority.ALWAYS); + getRootPane().getChildren().addAll(headerBar, gamesContainer); + + // Map interactions + registerButton(MiniGamesActions.HELP, helpBtn); + registerButton(MiniGamesActions.CLICKER_GAME, clickerGameBtn); + registerButton(MiniGamesActions.FIND_STOCK, findStockBtn); + registerButton(MiniGamesActions.TIME_CLICKS, timeClicksBtn); + } + + private void configureGameButton(final Button btn) { + btn.setMaxWidth(Double.MAX_VALUE); + btn.setMaxHeight(Double.MAX_VALUE); + btn.setAlignment(Pos.CENTER); + } + + /** + * Updates the selected stock text. + * + * @param symbol the symbol representing the stock selected. + */ + public void setSelectedStockText(final String symbol) { + stockValueLabel.setText(symbol); + } + + @Override + protected void initStyling() { + getRootPane().getStyleClass().add("minigames-root"); + headerBar.getStyleClass().add("minigames-headerBar"); + titleLabel.getStyleClass().add("minigames-titleLabel"); + selectedStockLabel.getStyleClass().add("minigames-stockLabel"); + stockValueLabel.getStyleClass().add("minigames-stockValue"); + + helpBtn.getStyleClass().add("minigames-helpBtn"); + gamesContainer.getStyleClass().add("minigames-container"); + + clickerGameBtn.getStyleClass().add("minigames-cardBtn"); + findStockBtn.getStyleClass().add("minigames-cardBtn"); + timeClicksBtn.getStyleClass().add("minigames-cardBtn"); + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarActions.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarActions.java index 9b71268..6f07799 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarActions.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarActions.java @@ -5,5 +5,6 @@ public enum TopBarActions { STATS, MARKET, SETTINGS, - TRANSACTIONS; + TRANSACTIONS, + MINIGAMES; } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarController.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarController.java index 86c5d2d..051368d 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarController.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarController.java @@ -39,6 +39,17 @@ public class TopBarController extends ViewController { */ private boolean inTransactionsView = false; + /** + * Whether the minigames screen is currently the active center-view. + * + *

+ * When true, the quit/back button returns to the dashboard instead + * of exiting to the main menu. + *

+ */ + private boolean inMinigamesView = false; + + /** * {@inheritDoc}. */ @@ -83,20 +94,27 @@ protected void initInteractions() { * @param statsCenter root pane of the stats widget. * @param transactionsCenter root pane of the transactions widget. * @param onTransactionUpdate callback invoked when entering transactions. + * @param minigamesCenter root pane of the minigames widget. */ public void setMarketIntegration(final Consumer centerSwitcher, final Node dashboardCenter, final Node marketCenter, final Node statsCenter, final Node transactionsCenter, - final Runnable onTransactionUpdate) { + final Runnable onTransactionUpdate, + final Node minigamesCenter + ) { getViewElement().setOnAction(TopBarActions.EXIT, () -> { - if (inMarketView || inStatsView || inTransactionsView) { + if (inMarketView + || inStatsView + || inTransactionsView + || inMinigamesView) { centerSwitcher.accept(dashboardCenter); getViewElement().setQuitText("Quit"); inMarketView = false; inStatsView = false; inTransactionsView = false; + inMinigamesView = false; } else { changeScene(ViewEnum.MAIN_MENU); } @@ -108,6 +126,7 @@ public void setMarketIntegration(final Consumer centerSwitcher, inMarketView = false; inStatsView = true; inTransactionsView = false; + inMinigamesView = false; }); getViewElement().setOnAction(TopBarActions.MARKET, () -> { @@ -116,6 +135,7 @@ public void setMarketIntegration(final Consumer centerSwitcher, inMarketView = true; inStatsView = false; inTransactionsView = false; + inMinigamesView = false; }); getViewElement().setOnAction(TopBarActions.TRANSACTIONS, () -> { @@ -125,6 +145,16 @@ public void setMarketIntegration(final Consumer centerSwitcher, inMarketView = false; inStatsView = false; inTransactionsView = true; + inMinigamesView = false; + }); + + getViewElement().setOnAction(TopBarActions.MINIGAMES, () -> { + centerSwitcher.accept(minigamesCenter); + getViewElement().setQuitText("Back"); + inMarketView = false; + inStatsView = false; + inTransactionsView = false; + inMinigamesView = true; }); } } \ No newline at end of file diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarView.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarView.java index 30f0259..3be0fcf 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarView.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarView.java @@ -17,6 +17,7 @@ public class TopBarView extends ViewElement { private Button marketBtn; private Button settingsBtn; private Button transactionsBtn; + private Button minigamesBtn; private SummaryView summaryView; @@ -48,8 +49,10 @@ protected void initLayout() { marketBtn = new Button("Market"); settingsBtn = new Button("Settings"); transactionsBtn = new Button("Transactions"); + minigamesBtn = new Button("Minigames"); - Stream.of(quitBtn, statsBtn, marketBtn, settingsBtn, transactionsBtn).forEach(b -> { + + Stream.of(quitBtn, statsBtn, marketBtn, settingsBtn, transactionsBtn, minigamesBtn).forEach(b -> { HBox.setHgrow(b, Priority.ALWAYS); }); @@ -58,7 +61,8 @@ protected void initLayout() { statsBtn, marketBtn, settingsBtn, - transactionsBtn + transactionsBtn, + minigamesBtn ); if (summaryView != null) { @@ -71,12 +75,13 @@ protected void initLayout() { registerButton(TopBarActions.MARKET, marketBtn); registerButton(TopBarActions.SETTINGS, settingsBtn); registerButton(TopBarActions.TRANSACTIONS, transactionsBtn); + registerButton(TopBarActions.MINIGAMES, minigamesBtn); } @Override protected void initStyling() { getRootPane().getStyleClass().add("top-bar"); - Stream.of(quitBtn, statsBtn, marketBtn, settingsBtn, transactionsBtn) + Stream.of(quitBtn, statsBtn, marketBtn, settingsBtn, transactionsBtn, minigamesBtn) .forEach(b -> b.getStyleClass().add("menu-button")); } diff --git a/src/main/resources/styles.css b/src/main/resources/styles.css index 3b73285..de5dd5d 100644 --- a/src/main/resources/styles.css +++ b/src/main/resources/styles.css @@ -797,4 +797,67 @@ -fx-fit-to-height: true; -fx-background: transparent; -fx-background-color: transparent; -} \ No newline at end of file +} +/* -----------------------------------------------*/ +/* ------------------- MINIGAMES -----------------*/ +.minigames-root { + -fx-padding: 30px; + -fx-background-color: #e0e0e0; + -fx-spacing: 40px; +} + +.minigames-headerBar { + -fx-padding: 10px 0px; +} + +.minigames-titleLabel { + -fx-font-size: 48px; + -fx-font-family: "Aptos", "Segoe UI", sans-serif; + -fx-text-fill: #000000; +} + +.minigames-stockLabel { + -fx-font-size: 24px; + -fx-text-fill: #000000; +} + +.minigames-stockValue { + -fx-font-size: 24px; + -fx-text-fill: #000000; + -fx-border-color: #000000; + -fx-border-width: 1.5px; + -fx-padding: 2px 10px; + -fx-background-color: #d8d8d8; +} + +.minigames-helpBtn { + -fx-font-size: 28px; + -fx-pref-width: 50px; + -fx-pref-height: 50px; + -fx-background-color: #d8d8d8; + -fx-border-color: #000000; + -fx-border-width: 1.5px; + -fx-text-fill: #000000; +} + +.minigames-container { + -fx-spacing: 30px; + -fx-padding: 10px 0px; +} + +.minigames-cardBtn { + -fx-background-color: #d8d8d8; + -fx-border-color: #000000; + -fx-border-width: 1.5px; + -fx-font-size: 32px; + -fx-text-fill: #000000; + -fx-text-alignment: center; + -fx-pref-height: 250px; + -fx-min-height: 200px; + -fx-max-width: 350px; +} + +.minigames-cardBtn:hover, .minigames-helpBtn:hover { + -fx-background-color: #c0c0c0; +} +/* --------------------------------------------- */ \ No newline at end of file