Skip to content

Commit

Permalink
text vis og setting upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
EspenTinius committed May 26, 2026
1 parent 6815b80 commit 3e68358
Show file tree
Hide file tree
Showing 5 changed files with 522 additions and 302 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
package edu.ntnu.idi.idatt2003.g40.mappe.view.settings;

/**
* User-triggered actions available on the main-menu settings view.
*
* <p>{@link #AUDIO}, {@link #VIDEO} and {@link #HOTKEYS} are kept for
* backwards compatibility with the older sidebar/tab layout - they no
* longer correspond to user-pressable buttons in the redesigned view,
* but the {@code SettingsController} still wires no-op handlers to
* them so existing call sites keep compiling.</p>
* */
public enum SettingsActions {
/** Legacy audio-tab action. No longer triggered by the redesigned view. */
AUDIO,

/** Legacy video-tab action. No longer triggered by the redesigned view. */
VIDEO,

/** Legacy hot-keys-tab action. No longer triggered by the redesigned view. */
HOTKEYS,
BACK;

/** Returns to the main menu. */
BACK,

/** Selects the dark theme. */
DARK_MODE,

/** Selects the light theme. */
LIGHT_MODE;
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package edu.ntnu.idi.idatt2003.g40.mappe.view.settings;

import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventData;
import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventManager;
import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventType;
import edu.ntnu.idi.idatt2003.g40.mappe.utils.ThemeManager;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewController;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewData;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewEnum;

/**
* Controller for {@link SettingsView}.
*
* <p>Wires up the category buttons to switch the right-hand content,
* and the Back button to return to the main menu.</p>
* <p>Wires up the Back button to return to the main menu and the
* theme toggle buttons to the global {@link ThemeManager}. The
* legacy {@code AUDIO}, {@code VIDEO} and {@code HOTKEYS} actions
* are no longer pressable in the redesigned view, so no handlers
* are attached for them.</p>
*/
public class SettingsController extends ViewController<SettingsView> {

Expand All @@ -24,14 +25,26 @@ public class SettingsController extends ViewController<SettingsView> {
public SettingsController(final SettingsView view,
final EventManager eventManager) {
super(view, eventManager);
// Sync the highlighted theme button with the current theme on
// construction (matches InGameSettingsController behaviour).
getViewElement().setActiveTheme(
ThemeManager.getInstance().getCurrentTheme());
}

/** {@inheritDoc} */
@Override
protected void initInteractions() {
getViewElement().setOnAction(SettingsActions.AUDIO, () -> getViewElement().showAudioSection());
getViewElement().setOnAction(SettingsActions.VIDEO, () -> getViewElement().showVideoSection());
getViewElement().setOnAction(SettingsActions.HOTKEYS, () -> getViewElement().showHotKeysSection());
getViewElement().setOnAction(SettingsActions.BACK, () -> changeScene(ViewEnum.MAIN_MENU));
getViewElement().setOnAction(SettingsActions.BACK,
() -> changeScene(ViewEnum.MAIN_MENU));

getViewElement().setOnAction(SettingsActions.DARK_MODE, () -> {
ThemeManager.getInstance().setTheme(ThemeManager.Theme.DARK);
getViewElement().setActiveTheme(ThemeManager.Theme.DARK);
});

getViewElement().setOnAction(SettingsActions.LIGHT_MODE, () -> {
ThemeManager.getInstance().setTheme(ThemeManager.Theme.LIGHT);
getViewElement().setActiveTheme(ThemeManager.Theme.LIGHT);
});
}
}
}
Original file line number Diff line number Diff line change
@@ -1,174 +1,168 @@
package edu.ntnu.idi.idatt2003.g40.mappe.view.settings;

import edu.ntnu.idi.idatt2003.g40.mappe.utils.ThemeManager;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewElement;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewEnum;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;

/**
* View shown when the player clicks "Settings" on the main menu.
*
* <p>Layout: left sidebar with category buttons (audio, video, hot keys)
* and a Back button at the bottom. Right pane shows the content for the
* currently selected category. </p>
* <p>
* Mirrors
* {@link edu.ntnu.idi.idatt2003.g40.mappe.view.ingame.settings.InGameSettingsView}
* so the player gets the same panel layout in both places: a compact
* card with a header (title + Back button) and a single Theme section
* containing a Dark / Light toggle.
* </p>
*
* <p>
* The view applies the {@link ThemeManager} directly when the
* player clicks the Dark/Light buttons so the toggle works
* identically to the in-game one.
* </p>
*/
public class SettingsView extends ViewElement<StackPane, SettingsActions> {

/** Category buttons on the left side. */
private Button audioButton;
private Button videoButton;
private Button hotKeysButton;

/** Bottom-left back button. */
/** Back-to-menu button shown in the panel's top-right corner. */
private Button backButton;

/** The currently displayed content pane on the right side. */
private StackPane contentArea;
/** Selects the dark theme. */
private Button darkModeButton;

/** Master volume slider for the audio section. */
private Slider masterVolumeSlider;
/** Selects the light theme. */
private Button lightModeButton;

/** Main border layout containing the sidebar and content area. */
private BorderPane mainPanel;
/** Modal-style card hosting the settings sections. */
private VBox panel;

/**
* Constructor.
*
* <p>Constructs with name "SettingsView"</p>
* <p>
* Constructs with name "SettingsView"
* </p>
*/
public SettingsView() {
super(new StackPane(), ViewEnum.SETTINGS, SettingsActions.class);
}

public Slider getMasterVolumeSlider() {
return masterVolumeSlider;
}

/**
* Replaces the content area with the audio section (master volume).
* Getter for the dark-mode button.
*
* @return the dark-mode button.
*/
public void showAudioSection() {
Label title = new Label("Master volume");
title.getStyleClass().add("settings-title");

masterVolumeSlider = new Slider(0, 100, 50);
masterVolumeSlider.setMaxWidth(360);
masterVolumeSlider.getStyleClass().add("settings-slider");

VBox audioBox = new VBox(24, title, masterVolumeSlider);
audioBox.setAlignment(Pos.TOP_LEFT);
audioBox.setPadding(new Insets(20, 30, 30, 30));

contentArea.getChildren().setAll(audioBox);
public Button getDarkModeButton() {
return darkModeButton;
}

/**
* Replaces the content area with the video section placeholder.
* Getter for the light-mode button.
*
* @return the light-mode button.
*/
public void showVideoSection() {
Label title = new Label("Video");
title.getStyleClass().add("settings-title");
Label placeholder = new Label("(video settings coming soon)");
placeholder.getStyleClass().add("settings-placeholder");

VBox videoBox = new VBox(20, title, placeholder);
videoBox.setAlignment(Pos.TOP_LEFT);
videoBox.setPadding(new Insets(20, 30, 30, 30));

contentArea.getChildren().setAll(videoBox);
public Button getLightModeButton() {
return lightModeButton;
}

/**
* Replaces the content area with the hot keys section placeholder.
* Highlights the active theme button so the player always sees which
* theme is currently selected. Mirrors {@code InGameSettingsView}.
*
* @param theme the active {@link ThemeManager.Theme}.
*/
public void showHotKeysSection() {
Label title = new Label("Hot keys");
title.getStyleClass().add("settings-title");
Label placeholder = new Label("(hot key bindings coming soon)");
placeholder.getStyleClass().add("settings-placeholder");

VBox hotKeysBox = new VBox(20, title, placeholder);
hotKeysBox.setAlignment(Pos.TOP_LEFT);
hotKeysBox.setPadding(new Insets(20, 30, 30, 30));

contentArea.getChildren().setAll(hotKeysBox);
public void setActiveTheme(final ThemeManager.Theme theme) {
darkModeButton.getStyleClass().remove("active");
lightModeButton.getStyleClass().remove("active");
if (theme == ThemeManager.Theme.LIGHT) {
lightModeButton.getStyleClass().add("active");
} else {
darkModeButton.getStyleClass().add("active");
}
}

/** {@inheritDoc} */
@Override
protected void initLayout() {
audioButton = new Button("Audio");
videoButton = new Button("Video");
hotKeysButton = new Button("Hot keys");
// Header row: title + back button.
Label title = new Label("Settings");
title.getStyleClass().add("ingame-settings-title");

Region headerSpacer = new Region();
HBox.setHgrow(headerSpacer, Priority.ALWAYS);

backButton = new Button("Back");
backButton.setFocusTraversable(false);
backButton.getStyleClass().add("ingame-settings-toggle-button");

HBox header = new HBox(12, title, headerSpacer, backButton);
header.setAlignment(Pos.CENTER_LEFT);

// Theme section.
Label themeSectionLabel = new Label("Theme");
themeSectionLabel.getStyleClass().add("ingame-settings-section-label");

Label themeDescription = new Label(
"Choose between dark and light appearance for the game.");
themeDescription.getStyleClass().add("ingame-settings-description");
themeDescription.setWrapText(true);

darkModeButton = new Button("Dark mode");
lightModeButton = new Button("Light mode");
darkModeButton.setFocusTraversable(false);
lightModeButton.setFocusTraversable(false);
darkModeButton.getStyleClass().add("ingame-settings-toggle-button");
lightModeButton.getStyleClass().add("ingame-settings-toggle-button");

HBox themeToggleRow = new HBox(12, darkModeButton, lightModeButton);
themeToggleRow.setAlignment(Pos.CENTER_LEFT);

VBox themeSection = new VBox(10, themeSectionLabel,
themeDescription, themeToggleRow);
themeSection.setAlignment(Pos.TOP_LEFT);

// Assemble panel - same dimensions as InGameSettingsView for visual
// parity between the two settings entry points.
panel = new VBox(22, header, themeSection);
panel.setAlignment(Pos.TOP_LEFT);
panel.setPadding(new Insets(28, 32, 32, 32));
panel.setMaxWidth(440);
panel.setMaxHeight(280);
panel.setPrefWidth(440);
panel.getStyleClass().add("ingame-settings-panel");

getRootPane().getStyleClass().add("main-menu-bg");
getRootPane().getChildren().add(panel);
StackPane.setAlignment(panel, Pos.CENTER);

// Sidebar header so the panel doesn't feel anonymous.
Label sidebarHeader = new Label("Settings");
sidebarHeader.getStyleClass().add("settings-title");
VBox.setMargin(sidebarHeader, new Insets(0, 0, 8, 0));

// Spacer pushes the Back button to the bottom of the sidebar.
Region spacer = new Region();
VBox.setVgrow(spacer, javafx.scene.layout.Priority.ALWAYS);

VBox sidebar = new VBox(8,
sidebarHeader,
audioButton, videoButton, hotKeysButton, spacer, backButton);
sidebar.setAlignment(Pos.TOP_LEFT);
sidebar.setPadding(new Insets(28, 22, 28, 22));
sidebar.setPrefWidth(200);

contentArea = new StackPane();
contentArea.setPadding(new Insets(10));

mainPanel = new BorderPane();
mainPanel.setLeft(sidebar);
mainPanel.setCenter(contentArea);
mainPanel.setMaxWidth(820);
mainPanel.setMaxHeight(520);
mainPanel.setPrefWidth(820);
mainPanel.setPrefHeight(520);

// Center the BorderPane.
HBox centerWrapper = new HBox(mainPanel);
centerWrapper.setAlignment(Pos.CENTER);

getRootPane().getChildren().add(centerWrapper);

// Default section shown when settings opens.
showAudioSection();

registerButton(SettingsActions.AUDIO, audioButton);
registerButton(SettingsActions.VIDEO, videoButton);
registerButton(SettingsActions.HOTKEYS, hotKeysButton);
registerButton(SettingsActions.BACK, backButton);
registerButton(SettingsActions.DARK_MODE, darkModeButton);
registerButton(SettingsActions.LIGHT_MODE, lightModeButton);
}

/** {@inheritDoc} */
@Override
protected void initStyling() {
getRootPane().getStyleClass().add("main-menu-bg");
mainPanel.getStyleClass().add("settings-panel");
audioButton.getStyleClass().add("settings-tab-button");
videoButton.getStyleClass().add("settings-tab-button");
hotKeysButton.getStyleClass().add("settings-tab-button");
backButton.getStyleClass().add("settings-tab-button");
// Styling is applied via the .ingame-settings-* and .main-menu-bg
// style classes assigned in initLayout(). Nothing else to do here.
}

/** {@inheritDoc} */
@Override
public void onUpdate() {
// Reset til audio-section hver gang viewet vises.
if (contentArea != null) {
showAudioSection();
// Re-sync the highlighted theme button every time the view shows,
// since the player may have toggled the theme from the in-game
// overlay since they last visited.
if (darkModeButton != null && lightModeButton != null) {
setActiveTheme(ThemeManager.getInstance().getCurrentTheme());
}
}
}
11 changes: 1 addition & 10 deletions src/main/resources/saves/Newbie.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,7 @@
"stockDataPath": null,
"week": 5,
"ownedShares": [
{ "symbol": "NVDA", "quantity": 5.0, "purchasePrice": 191.27 },
{ "symbol": "NVDA", "quantity": 5.0, "purchasePrice": 191.27 },
{ "symbol": "NVDA", "quantity": 5.0, "purchasePrice": 191.27 },
{ "symbol": "NVDA", "quantity": 5.0, "purchasePrice": 191.27 },
{ "symbol": "NVDA", "quantity": 5.0, "purchasePrice": 191.27 },
{ "symbol": "NVDA", "quantity": 5.0, "purchasePrice": 191.27 },
{ "symbol": "NVDA", "quantity": 5.0, "purchasePrice": 191.27 },
{ "symbol": "NVDA", "quantity": 5.0, "purchasePrice": 191.27 },
{ "symbol": "NVDA", "quantity": 5.0, "purchasePrice": 191.27 },
{ "symbol": "NVDA", "quantity": 5.0, "purchasePrice": 191.27 }
{ "symbol": "NVDA", "quantity": 50.0, "purchasePrice": 191.27 }
],
"transactions": [
{ "type": "PURCHASE", "symbol": "NVDA", "quantity": 5.0, "price": 191.27, "week": 1 },
Expand Down
Loading

0 comments on commit 3e68358

Please sign in to comment.