From 5359e6c16c7fb0f0f2cf01adc7c35a3a1e32c1e4 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 12 May 2026 17:24:16 +0200 Subject: [PATCH] Feat: Added top bar with graph and navigation row --- .../ntnu/idi/idatt2003/g40/mappe/Main.java | 17 ++- .../g40/mappe/view/ingame/InGameActions.java | 4 + .../g40/mappe/view/ingame/InGameView.java | 15 ++- .../financialsummary/SummaryActions.java | 5 + .../financialsummary/SummaryController.java | 23 ++++ .../widgets/financialsummary/SummaryView.java | 106 ++++++++++++++++++ .../view/widgets/topbar/TopBarActions.java | 8 ++ .../view/widgets/topbar/TopBarController.java | 21 ++++ .../mappe/view/widgets/topbar/TopBarView.java | 56 +++++++++ src/main/resources/styles.css | 85 ++++++++++++++ 10 files changed, 333 insertions(+), 7 deletions(-) create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ingame/InGameActions.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryActions.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryController.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryView.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarActions.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarController.java create mode 100644 src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarView.java 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 3053f88..4d9aa72 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 @@ -17,6 +17,11 @@ import java.io.IOException; import java.util.List; import java.util.Objects; + +import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.financialsummary.SummaryController; +import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.financialsummary.SummaryView; +import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.topbar.TopBarController; +import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.topbar.TopBarView; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.layout.Pane; @@ -77,10 +82,18 @@ public void start(final Stage stage) throws Exception { SettingsView settingsView = new SettingsView(); new SettingsController(settingsView, eventManager); + // Summary section of the top bar + SummaryView summaryView = new SummaryView(); + new SummaryController(summaryView, eventManager); + + // Top bar + TopBarView topBarView = new TopBarView(summaryView); + new TopBarController(topBarView, eventManager); + // In-game - InGameView inGameView = new InGameView(); + InGameView inGameView = new InGameView(topBarView); - // Registrer alle views og start på hovedmenyen + // Register all views viewManager.addView(mainMenuView); viewManager.addView(playGameView); viewManager.addView(settingsView); diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ingame/InGameActions.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ingame/InGameActions.java new file mode 100644 index 0000000..cae5ce2 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ingame/InGameActions.java @@ -0,0 +1,4 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view.ingame; + +public enum InGameActions { +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ingame/InGameView.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ingame/InGameView.java index 9ce3bfc..0096e48 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ingame/InGameView.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ingame/InGameView.java @@ -1,18 +1,23 @@ package edu.ntnu.idi.idatt2003.g40.mappe.view.ingame; import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewElement; +import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewEnum; +import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.topbar.TopBarView; import javafx.scene.layout.VBox; -import javafx.scene.text.Text; -public class InGameView extends ViewElement { +public class InGameView extends ViewElement { + + TopBarView topBarView; + + public InGameView(final TopBarView topBarView) { + this.topBarView = topBarView; + super(new VBox(), ViewEnum.IN_GAME, InGameActions.class); - public InGameView() { - super(new VBox(), "InGameView"); } @Override protected void initLayout() { - getRootPane().getChildren().add(new Text("This is the game view!")); + getRootPane().getChildren().add(topBarView.getRootPane()); } @Override diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryActions.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryActions.java new file mode 100644 index 0000000..a9c93c7 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryActions.java @@ -0,0 +1,5 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.financialsummary; + +public enum SummaryActions { + NEXT_WEEK; +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryController.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryController.java new file mode 100644 index 0000000..fecc2ae --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryController.java @@ -0,0 +1,23 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.financialsummary; + +import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventManager; +import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewController; + +public class SummaryController extends ViewController { + + /** + * {@inheritDoc}. + */ + public SummaryController(final SummaryView viewElement, + final EventManager eventManager) + throws IllegalArgumentException { + super(viewElement, eventManager); + } + + @Override + protected void initInteractions() { + getViewElement().setOnAction(SummaryActions.NEXT_WEEK, () -> { + System.out.println("Next week!"); + }); + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryView.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryView.java new file mode 100644 index 0000000..402a3bf --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/financialsummary/SummaryView.java @@ -0,0 +1,106 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.financialsummary; + +import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewElement; +import javafx.geometry.Pos; +import javafx.scene.chart.LineChart; +import javafx.scene.chart.NumberAxis; +import javafx.scene.chart.XYChart; +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; + +public class SummaryView extends ViewElement { + private Label balanceLabel; + private Label weekLabel; + private Label titleLabel; + private LineChart chart; + private XYChart.Series dataSeries; + private Button nextBtn; + + public SummaryView() { + super(new HBox(), SummaryActions.class); + } + + @Override + protected void initLayout() { + getRootPane().setSpacing(20); + getRootPane().setAlignment(Pos.BOTTOM_CENTER); + getRootPane().setFillHeight(false); + + VBox balanceInfo = new VBox(); + + titleLabel = new Label("balance/investments"); + balanceLabel = new Label("200$/2394$"); + + balanceInfo.getChildren().addAll(titleLabel, balanceLabel); + + NumberAxis xAxis = new NumberAxis(1, 22, 1); + xAxis.setMinorTickVisible(false); + xAxis.setTickMarkVisible(true); + xAxis.setTickLabelsVisible(true); + + NumberAxis yAxis = new NumberAxis(); + yAxis.setTickLabelsVisible(false); + yAxis.setTickMarkVisible(false); + yAxis.setMinorTickVisible(false); + + chart = new LineChart<>(xAxis, yAxis); + chart.setCreateSymbols(false); + chart.setLegendVisible(false); + chart.setHorizontalGridLinesVisible(false); + chart.setVerticalGridLinesVisible(false); + chart.setAlternativeRowFillVisible(false); + chart.setAnimated(false); + chart.setPrefHeight(100); + chart.setMinHeight(100); + chart.setMaxHeight(100); + + Region spacer = new Region(); + HBox.setHgrow(spacer, Priority.ALWAYS); + HBox.setHgrow(chart, Priority.ALWAYS); + + Region leftSpacer = new Region(); + HBox.setHgrow(leftSpacer, Priority.SOMETIMES); + + dataSeries = new XYChart.Series<>(); + chart.prefHeightProperty().bind(getRootPane().heightProperty().divide(5)); + chart.minHeightProperty().set(50); + chart.getData().add(dataSeries); + + VBox navInfo = new VBox(); + navInfo.setAlignment(Pos.BOTTOM_RIGHT); + + nextBtn = new Button("next"); + + weekLabel = new Label("week: 0"); + weekLabel.getStyleClass().add("week-label"); + + navInfo.getChildren().addAll(nextBtn, weekLabel); + + getRootPane().getChildren().addAll(balanceInfo, chart, navInfo); + registerButton(SummaryActions.NEXT_WEEK, nextBtn); + } + + @Override + protected void initStyling() { + getRootPane().getStyleClass().add("summary-container"); + titleLabel.getStyleClass().add("balance-title"); + balanceLabel.getStyleClass().add("balance-value"); + nextBtn.getStyleClass().add("next-button"); + } + + public void setBalance(final String text) { + balanceLabel.setText(text); + } + + public void setWeek(int week) { + weekLabel.setText("week: " + week); + } + + public void updateChart(double x, double y) { + dataSeries.getData().add(new XYChart.Data<>(x, y)); + } +} 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 new file mode 100644 index 0000000..08f84fb --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarActions.java @@ -0,0 +1,8 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.topbar; + +public enum TopBarActions { + EXIT, + STATS, + MARKET, + SETTINGS; +} 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 new file mode 100644 index 0000000..542c2b3 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarController.java @@ -0,0 +1,21 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.topbar; + +import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventManager; +import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewController; +import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewEnum; + +public class TopBarController extends ViewController { + + /** + * {@inheritDoc}. + */ + public TopBarController(final TopBarView viewElement, final EventManager eventManager) + throws IllegalArgumentException { + super(viewElement, eventManager); + } + + @Override + protected void initInteractions() { + getViewElement().setOnAction(TopBarActions.EXIT, () -> changeScene(ViewEnum.MAIN_MENU)); + } +} 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 new file mode 100644 index 0000000..b1ab559 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/topbar/TopBarView.java @@ -0,0 +1,56 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.topbar; + +import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewElement; +import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.financialsummary.SummaryView; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; + +import java.util.stream.Stream; + +public class TopBarView extends ViewElement { + private Button quitBtn; + private Button statsBtn; + private Button marketBtn; + private Button settingsBtn; + private final SummaryView summaryView; + + public TopBarView(final SummaryView summaryView) { + this.summaryView = summaryView; + super(new VBox(10), TopBarActions.class); + } + + @Override + protected void initLayout() { + HBox navRow = new HBox(20); + navRow.setAlignment(Pos.CENTER); + + quitBtn = new Button("Quit"); + statsBtn = new Button("Stats"); + marketBtn = new Button("Market"); + settingsBtn = new Button("Settings"); + + navRow.getChildren().addAll( + quitBtn, + statsBtn, + marketBtn, + settingsBtn + ); + + getRootPane().getChildren().addAll(navRow, summaryView.getRootPane()); + + registerButton(TopBarActions.EXIT, quitBtn); + registerButton(TopBarActions.STATS, statsBtn); + registerButton(TopBarActions.MARKET, marketBtn); + registerButton(TopBarActions.SETTINGS, settingsBtn); + + } + + @Override + protected void initStyling() { + getRootPane().getStyleClass().add("top-bar"); // For your CSS file + Stream.of(quitBtn, statsBtn, marketBtn, settingsBtn) + .forEach(b -> b.getStyleClass().add("menu-button")); + } +} diff --git a/src/main/resources/styles.css b/src/main/resources/styles.css index 7fc3640..13e27d0 100644 --- a/src/main/resources/styles.css +++ b/src/main/resources/styles.css @@ -138,7 +138,92 @@ .settings-slider .track { -fx-background-color: rgba(0, 0, 0, 0.4); -fx-pref-height: 2; +} .title-text { -fx-font-size: 100px; +} +/* ------------- TOP BAR ------------- */ +.top-bar { + -fx-background-color: rgba(255, 255, 255, 0.7); + -fx-background-radius: 20; + -fx-margin: 10; + -fx-padding: 1%; +} + + +.top-bar-menu-button { + -fx-font-size: 18px; + -fx-font-weight: bold; + -fx-font-style: italic; + -fx-background-color: #f0f0f0; + -fx-background-radius: 10; + -fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.2), 5, 0, 0, 2); +} + +.top-bar-menu-button:hover { + -fx-background-color: #d0d0d0; +} + +/* ------------- SUMMARY IN TOP BAR -----------*/ +.summary-container { + -fx-border-color: black; + -fx-border-width: 1 0 1 0; /* Horizontal lines from image */ + -fx-padding: 10; +} + +.balance-title { + -fx-font-family: "Aptos"; + -fx-font-style: italic; + -fx-font-weight: bold; + -fx-font-size: 14; +} + +.balance-value { + -fx-font-family: "Aptos"; + -fx-font-weight: bold; + -fx-font-size: 24; +} + +.chart-series-line { + -fx-stroke: green; +} + + +.chart-plot-background { + -fx-background-color: transparent; +} + +.chart { + -fx-padding: 0; +} + +.axis { + -fx-tick-label-font-weight: bold; + -fx-tick-label-font-style: italic; + -fx-tick-label-fill: black; +} + +.axis:bottom { + -fx-border-color: black transparent transparent transparent; + -fx-border-width: 2px; +} + +.axis:left { + -fx-border-color: transparent; +} + +.chart-series-line { + -fx-stroke: #00ff00; + -fx-stroke-width: 2px; +} + +.next-button { + -fx-background-color: #e0e0e0; + -fx-background-radius: 10; + -fx-font-family: "Aptos"; + -fx-font-weight: bold; + -fx-padding: 5 15; + -fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.2), 2, 0, 0, 1); + -fx-cursor: hand; } \ No newline at end of file