Skip to content
Snippets Groups Projects
ChaosGameGui.java 22.3 KiB
Newer Older
Magnus Eik's avatar
Magnus Eik committed
package edu.ntnu.stud.chaosgame.view;

import edu.ntnu.stud.chaosgame.controller.game.ChaosGame;
import edu.ntnu.stud.chaosgame.controller.game.GuiButtonController;
import edu.ntnu.stud.chaosgame.controller.utility.Formatter;
import edu.ntnu.stud.chaosgame.model.game.ChaosCanvas;
import edu.ntnu.stud.chaosgame.model.game.ChaosGameDescription;
Magnus Eik's avatar
Magnus Eik committed
import edu.ntnu.stud.chaosgame.model.generators.ChaosGameDescriptionFactory;
import javafx.animation.Timeline;
import javafx.animation.TranslateTransition;
import javafx.geometry.Insets;
Magnus Eik's avatar
Magnus Eik committed
import javafx.geometry.Pos;
Magnus Eik's avatar
Magnus Eik committed
import javafx.scene.Scene;
import javafx.scene.control.*;
Magnus Eik's avatar
Magnus Eik committed
import javafx.scene.image.ImageView;
Magnus Eik's avatar
Magnus Eik committed
import javafx.scene.layout.*;
Magnus Eik's avatar
Magnus Eik committed
import javafx.scene.paint.Color;
Magnus Eik's avatar
Magnus Eik committed
import javafx.scene.text.Font;
Magnus Eik's avatar
Magnus Eik committed
import javafx.stage.Stage;
import javafx.stage.Window;
Håvard Daleng's avatar
Håvard Daleng committed
// todo: look through GUI and get rid of redundancies, clean up code
public class ChaosGameGui implements ChaosGameObserver, GuiButtonObserver {
  /** The primary stage for the GUI. */
  private final int currentLine = 0;

  /** The controller for the GUI. */
  private final GuiButtonController controller;

  /** The canvas for this GUI. */
Håvard Daleng's avatar
Håvard Daleng committed
  private ChaosGameDescription description;

Håvard Daleng's avatar
Håvard Daleng committed
  private ChaosGameDescriptionFactory factory;

  private ChaosGameImageView imageView;
Håvard Daleng's avatar
Håvard Daleng committed
  private Scene scene;

Håvard Daleng's avatar
Håvard Daleng committed
  private int width;
Håvard Daleng's avatar
Håvard Daleng committed

Håvard Daleng's avatar
Håvard Daleng committed
  private int height;

Håvard Daleng's avatar
Håvard Daleng committed
  private ChaosGame game;

Håvard Daleng's avatar
Håvard Daleng committed
  private Timeline timeline;

Håvard Daleng's avatar
Håvard Daleng committed
  private BorderPane borderPane;

Håvard Daleng's avatar
Håvard Daleng committed
  private VBox sideMenu;

  /** The start, stop, new, clear, quit and show sidebar buttons for the GUI. */
Håvard Daleng's avatar
Håvard Daleng committed
  private Button startButton;
Håvard Daleng's avatar
Håvard Daleng committed

Håvard Daleng's avatar
Håvard Daleng committed
  private Button stopButton;
Håvard Daleng's avatar
Håvard Daleng committed

Håvard Daleng's avatar
Håvard Daleng committed
  private Button clearButton;
Håvard Daleng's avatar
Håvard Daleng committed

Håvard Daleng's avatar
Håvard Daleng committed
  private Button quitButton;
Håvard Daleng's avatar
Håvard Daleng committed

  /** The load fractal from file and write fractal to file buttons for the GUI. */
Håvard Daleng's avatar
Håvard Daleng committed
  private Button loadFractalFromFileButton;
Håvard Daleng's avatar
Håvard Daleng committed

  /** The write fractal to file button for the GUI. */
Håvard Daleng's avatar
Håvard Daleng committed
  private Button writeFractalToFileButton;

  /** The button which opens a menu to modify the game */
  private Button modifyGameButton;
  /** A description ComboBox for choosing different fractal descriptions. */
Håvard Daleng's avatar
Håvard Daleng committed
  private ComboBox<String> descriptionComboBox;

  /** The iteration limiter text field for the GUI */
  private TextField iterationLimitTextField;

  /** Button to save an image of the fractal. */
  private Button saveImageButton;
Håvard Daleng's avatar
Håvard Daleng committed
  /**
   * Constructor for the ChaosGameGui.
   *
   * @param primaryStage the primary stage for the GUI.
   * @throws IOException if the GUI fails to initialize.
   */
Håvard Daleng's avatar
Håvard Daleng committed
  public ChaosGameGui(Stage primaryStage) throws IOException {
    this.primaryStage = primaryStage;
    this.initializeComponents();
    this.initializeGameComponents();
    this.controller = new GuiButtonController(game, this); // Initialize controller here

    primaryStage.setTitle("Fractal Chaos Game");
    primaryStage.setScene(scene);
    primaryStage.setOnShown(event -> this.imageView.requestFocus());
    primaryStage.show();
Håvard Daleng's avatar
Håvard Daleng committed
    // Initialize aspect ratio based on initial dimensions
    this.aspectRatio = (double) width / height;

    // Add listeners to handle window size changes
    scene
        .widthProperty()
        .addListener(
            (observable, oldValue, newValue) -> {
              resizeCanvas();
            });

    scene
        .heightProperty()
        .addListener(
            (observable, oldValue, newValue) -> {
              resizeCanvas();
            });

    // Bind the width of the sideMenu to the width of the scene
    sideMenu
        .prefWidthProperty()
        .bind(scene.widthProperty().multiply(0.2)); // 20% of the scene width

    // Bind the height of the sideMenu to the height of the scene
    sideMenu.prefHeightProperty().bind(scene.heightProperty());
Håvard Daleng's avatar
Håvard Daleng committed

Håvard Daleng's avatar
Håvard Daleng committed
  private void initializeComponents() {

    // Timeline
    // this.timeline = new Timeline(new KeyFrame(Duration.seconds(0.05), event ->
    // controller.drawChaosGame()));
Håvard Daleng's avatar
Håvard Daleng committed
    this.initializeImageView();

    this.initializeFractalComponents();
Håvard Daleng's avatar
Håvard Daleng committed
    this.initializeSideMenu();

    this.scene = new Scene(this.borderPane, 1700, 1000);
  private TextField createCoordinateTextField(String promptText) {
    TextField textField = new TextField();
    textField.setPrefHeight(5);
    textField.setPrefWidth(90);
    textField.setPromptText(promptText);
    return textField;
  }
  /** Initialize the components related to the chaos game itself. */
Håvard Daleng's avatar
Håvard Daleng committed
  private void initializeGameComponents() {
    // Description
    this.factory = new ChaosGameDescriptionFactory();
    this.description = factory.getDescriptions().get(0);
    this.chaosCanvas =
        new ChaosCanvas(
            1000, 1000, this.description.getMinCoords(), this.description.getMaxCoords());
    game = new ChaosGame(this.description, chaosCanvas);

  /** Initialize components related to the image view and zoom function. */
Håvard Daleng's avatar
Håvard Daleng committed
  private void initializeImageView() {
    // Image view
    this.imageView = new ChaosGameImageView(this);
Håvard Daleng's avatar
Håvard Daleng committed
    width = 1000;
    height = 1000;
    this.canvas = new Canvas(width, height);
    canvas.widthProperty().bind(imageView.fitWidthProperty());
    canvas.heightProperty().bind(imageView.fitHeightProperty());

  public void clearImageView() {
    GraphicsContext gc = canvas.getGraphicsContext2D();
    gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
    imageView.setImage(null);
  /** Initialize the buttons related to managing the fractals. */
  private void initializeFractalComponents() {
Håvard Daleng's avatar
Håvard Daleng committed
    this.descriptionComboBox = new ComboBox<>();

Magnus Eik's avatar
Magnus Eik committed
    // Load fractal file button and tooltip
Håvard Daleng's avatar
Håvard Daleng committed
    this.loadFractalFromFileButton = new Button("Load Fractal");
    Tooltip loadFractalFromFileButtonTooltip =
        new Tooltip("Load a text file describing a new fractal chaos game");
    Tooltip.install(loadFractalFromFileButton, loadFractalFromFileButtonTooltip);
Magnus Eik's avatar
Magnus Eik committed
    // Write fractal to file button and tooltip
Håvard Daleng's avatar
Håvard Daleng committed
    this.writeFractalToFileButton = new Button("Write to File");
    Tooltip writeFractalToFileButtonTooltip =
        new Tooltip("Write a text file defining the current fractal chaos game to chosen location");
Magnus Eik's avatar
Magnus Eik committed
    Tooltip.install(writeFractalToFileButton, writeFractalToFileButtonTooltip);
  /** Initialize the side menu for the GUI, including all its buttons and other components. */
Håvard Daleng's avatar
Håvard Daleng committed
  private void initializeSideMenu() {
Magnus Eik's avatar
Magnus Eik committed
    // Create a Border style
    Border blackBorder =
        new Border(
            new BorderStroke(
                Color.BLACK, BorderStrokeStyle.SOLID, new CornerRadii(10), new BorderWidths(5)));
Magnus Eik's avatar
Magnus Eik committed

    // Create Canvas Header
    Label canvasLabel = new Label("Play Controls");
    canvasLabel.setAlignment(Pos.CENTER);
Magnus Eik's avatar
Magnus Eik committed

    // Create Canvas Buttons
    this.startButton = new Button("Start");
    this.stopButton = new Button("Pause");
Håvard Daleng's avatar
Håvard Daleng committed
    this.clearButton = new Button("New");
    this.quitButton = new Button("Quit");
    // this.sideMenuButton = new Button("Side Menu");
Magnus Eik's avatar
Magnus Eik committed

    // Create Tooltips
    Tooltip startButtonTooltip =
        new Tooltip("Starts drawing the current fractal from the selected chaos game");
Magnus Eik's avatar
Magnus Eik committed
    Tooltip stopButtonTooltip = new Tooltip("Pause drawing current fractal");
    Tooltip clearButtonTooltip = new Tooltip("Clear the current fracal");
    Tooltip quitButtonTooltip = new Tooltip("Quit the application");

    // Attach Tooltips to Buttons
    Tooltip.install(startButton, startButtonTooltip);
    Tooltip.install(stopButton, stopButtonTooltip);
    Tooltip.install(clearButton, clearButtonTooltip);
Magnus Eik's avatar
Magnus Eik committed
    Tooltip.install(quitButton, quitButtonTooltip);
Magnus Eik's avatar
Magnus Eik committed
    // Stylize Buttons
    startButton.setStyle("-fx-background-color: #006400;"
        + " -fx-padding: 8 16; -fx-background-radius: 16; -fx-background-insets: 1px;"
        + " -fx-border-width: 2px; -fx-border-color: white; -fx-border-radius: 16;"
        + "-fx-font-size: 14; -fx-text-fill: white;");
    stopButton.setStyle("-fx-background-color: #D2691E;"
        + " -fx-padding: 8 16; -fx-background-radius: 16; -fx-background-insets: 1px;"
        + " -fx-border-width: 2px; -fx-border-color: white; -fx-border-radius: 16;"
        + "-fx-font-size: 14; -fx-text-fill: white;");
    clearButton.setStyle("-fx-background-color: #00008B;"
        + " -fx-padding: 8 16; -fx-background-radius: 16; -fx-background-insets: 1px;"
        + " -fx-border-width: 2px; -fx-border-color: white; -fx-border-radius: 16;"
        + "-fx-font-size: 14; -fx-text-fill: white;");
    quitButton.setStyle("-fx-background-color: #980007;"
        + " -fx-padding: 8 16; -fx-background-radius: 16; -fx-background-insets: 1px;"
        + " -fx-border-width: 2px; -fx-border-color: white; -fx-border-radius: 16;"
        + "-fx-font-size: 14; -fx-text-fill: white;");


Håvard Daleng's avatar
Håvard Daleng committed
    this.sideMenu = new VBox();
Håvard Daleng's avatar
Håvard Daleng committed
    // Parameters
    VBox parameterBox = new VBox();
    VBox controlButtonBox = new VBox();
Magnus Eik's avatar
Magnus Eik committed
    controlButtonBox.setBorder(blackBorder);
    controlButtonBox.setPadding(new Insets(5, 5, 5, 5));
    VBox descriptionBox = new VBox();
    descriptionBox.setBorder(blackBorder);
    descriptionBox.setPadding(new Insets(5, 5, 5, 5));
    VBox bottomButtonBox = new VBox();
Håvard Daleng's avatar
Håvard Daleng committed
    // Step Count GUI
    VBox stepCountBox = new VBox();
    Label stepCountLabel = new Label("Step Count");
    stepCountLabel.setFont(new Font("Arial", 20));
    Label steppingSpeedLabel = new Label("Stepping Speed");
Magnus Eik's avatar
Magnus Eik committed
    stepCountLabel.setAlignment(Pos.CENTER);
    this.stepCountTextField.setTextFormatter(Formatter.getIntFormatter());
Håvard Daleng's avatar
Håvard Daleng committed
    Formatter.limitTextFieldSize(stepCountTextField, 6);
    stepCountTextField.setPrefHeight(5);
    stepCountTextField.setPrefWidth(50);
    stepCountTextField.setText("1000");
    Label iterationLimterLabel = new Label("Iteration Limit");
    this.iterationLimitTextField = new TextField();
    this.iterationLimitTextField.setTextFormatter(Formatter.getIntFormatter());
    Formatter.limitTextFieldSize(iterationLimitTextField, 4);
    iterationLimitTextField.setText("500");

    stepCountBox
        .getChildren()
        .addAll(
            stepCountLabel,
            steppingSpeedLabel,
            stepCountTextField,
            iterationLimterLabel,
            iterationLimitTextField);
Magnus Eik's avatar
Magnus Eik committed
    stepCountBox.setAlignment(Pos.CENTER);
    stepCountBox.setPadding(new Insets(5, 5, 5, 5));
Magnus Eik's avatar
Magnus Eik committed
    stepCountBox.setBorder(blackBorder);

    // Create a Box for Coordinate Controls
    VBox modifyGameBox = new VBox();
    modifyGameBox.setPadding(new Insets(5, 5, 5, 5));
Magnus Eik's avatar
Magnus Eik committed

    // Coordinate Control GUI
    Label coordinateHeader = new Label("Game Modification");
Magnus Eik's avatar
Magnus Eik committed
    coordinateHeader.setFont(new Font("Arial", 20));
    coordinateHeader.setAlignment(Pos.CENTER);
    modifyGameBox.getChildren().add(coordinateHeader);

    // Button for game modification popup
    modifyGameButton = new Button("Create Modified Game");

    Tooltip modifyGameButtonTooltip = new Tooltip("Create New Chaos Game From Current");
    Tooltip.install(modifyGameButton, modifyGameButtonTooltip);

    modifyGameBox.getChildren().addAll(modifyGameButton);
    modifyGameBox.setAlignment(Pos.CENTER);
    modifyGameBox.setBorder(blackBorder);
Magnus Eik's avatar
Magnus Eik committed

    Label colorHeaderLabel = new Label("Color Control");
    colorHeaderLabel.setFont(new Font("Arial", 20));
Magnus Eik's avatar
Magnus Eik committed
    colorHeaderLabel.setAlignment(Pos.CENTER);
    VBox colorVBox = new VBox();
Magnus Eik's avatar
Magnus Eik committed
    Label colorLabel = new Label("Show Redrawn Pixels");
    Tooltip colorCheckBoxTooltip =
        new Tooltip("Change pixel color for pixels drawn multiple times");
    Tooltip.install(colorCheckBox, colorCheckBoxTooltip);
    Region colorRegion = new Region();
    colorRegion.setMinWidth(30);
    colorBox.getChildren().addAll(colorCheckBox, colorRegion, colorLabel);
Magnus Eik's avatar
Magnus Eik committed
    colorBox.setAlignment(Pos.CENTER);
    colorVBox.setPadding(new Insets(5, 5, 5, 5));
    colorVBox.getChildren().addAll(colorHeaderLabel, colorBox);
Magnus Eik's avatar
Magnus Eik committed
    colorVBox.setAlignment(Pos.CENTER);
    colorVBox.setBorder(blackBorder);

    Region separator1 = new Region();
    separator1.setMinHeight(10);
    Region separator2 = new Region();
    separator2.setMinHeight(10);

Magnus Eik's avatar
Magnus Eik committed
    Region space = new Region();
    Region spacer = new Region();
    space.setMinHeight(10);
    spacer.setMinHeight(10);

Håvard Daleng's avatar
Håvard Daleng committed
    // Fill parameter box
    parameterBox.getChildren().addAll(stepCountBox, spacer, modifyGameBox);
Håvard Daleng's avatar
Håvard Daleng committed
    parameterBox.setPadding(new Insets(10));

    // Add basic control buttons
Magnus Eik's avatar
Magnus Eik committed
    controlButtonBox.setAlignment(Pos.CENTER);
    controlButtonBox.getChildren().addAll(canvasLabel, startButton, stopButton, clearButton);
Håvard Daleng's avatar
Håvard Daleng committed

    controlButtonBox.setSpacing(5);
    sideMenu.getChildren().add(controlButtonBox);

    // Add spacing
    sideMenu.getChildren().add(space);
Magnus Eik's avatar
Magnus Eik committed
    Label chaosGameTypeLabel = new Label("Chaos Game Selection");
    chaosGameTypeLabel.setFont(new Font("Arial", 20));
Magnus Eik's avatar
Magnus Eik committed
    chaosGameTypeLabel.setAlignment(Pos.CENTER);
    // Add fractal radio buttons
    descriptionBox.getChildren().addAll(chaosGameTypeLabel, descriptionComboBox);
Magnus Eik's avatar
Magnus Eik committed

    descriptionBox.setSpacing(5);
Magnus Eik's avatar
Magnus Eik committed
    descriptionBox.setAlignment(Pos.CENTER);
    sideMenu.getChildren().add(descriptionBox);
Magnus Eik's avatar
Magnus Eik committed
    sideMenu.getChildren().addAll(separator1, colorVBox, separator2);
Håvard Daleng's avatar
Håvard Daleng committed
    // Add parameter VBox
    sideMenu.getChildren().add(parameterBox);
    // Add file buttons and quit button
Magnus Eik's avatar
Magnus Eik committed
    Label menuButtonLabel = new Label("Menu Controls");
    menuButtonLabel.setFont(new Font("Arial", 20));
Magnus Eik's avatar
Magnus Eik committed
    menuButtonLabel.setAlignment(Pos.CENTER);

    saveImageButton = new Button("Save Image");

    bottomButtonBox
        .getChildren()
        .addAll(
            menuButtonLabel,
            saveImageButton,
            loadFractalFromFileButton,
            writeFractalToFileButton,
            quitButton);
    bottomButtonBox.setSpacing(5);
Magnus Eik's avatar
Magnus Eik committed
    bottomButtonBox.setBorder(blackBorder);
    bottomButtonBox.setAlignment(Pos.CENTER);
    bottomButtonBox.setPadding(new Insets(5, 5, 5, 5));
    sideMenu.getChildren().add(bottomButtonBox);
Magnus Eik's avatar
Magnus Eik committed
    // Stylize buttons
    modifyGameButton.setStyle("-fx-background-color: #00008B;"
        + " -fx-padding: 8 16; -fx-background-radius: 16; -fx-background-insets: 1px;"
        + " -fx-border-width: 2px; -fx-border-color: white; -fx-border-radius: 16;"
        + "-fx-font-size: 14; -fx-text-fill: white;");
    loadFractalFromFileButton.setStyle("-fx-background-color: #00008B;"
        + " -fx-padding: 8 16; -fx-background-radius: 16; -fx-background-insets: 1px;"
        + " -fx-border-width: 2px; -fx-border-color: white; -fx-border-radius: 16;"
        + "-fx-font-size: 14; -fx-text-fill: white;");
    saveImageButton.setStyle("-fx-background-color: #00008B;"
        + " -fx-padding: 8 16; -fx-background-radius: 16; -fx-background-insets: 1px;"
        + " -fx-border-width: 2px; -fx-border-color: white; -fx-border-radius: 16;"
        + "-fx-font-size: 14; -fx-text-fill: white;");
    writeFractalToFileButton.setStyle("-fx-background-color: #00008B;"
        + " -fx-padding: 8 16; -fx-background-radius: 16; -fx-background-insets: 1px;"
        + " -fx-border-width: 2px; -fx-border-color: white; -fx-border-radius: 16;"
        + "-fx-font-size: 14; -fx-text-fill: white;");

Håvard Daleng's avatar
Håvard Daleng committed
    // Add padding
    sideMenu.setPadding(new Insets(10));

    // Create split pane and button to toggle sidebar
    this.sideMenuButton = new Button(">>");
Magnus Eik's avatar
Magnus Eik committed
    Tooltip sideMenuButtonTooltip = new Tooltip("Hide/Unhide menu");
    Tooltip.install(sideMenuButton, sideMenuButtonTooltip);
    this.initializeSideButtonHandler();
    Region sideMenuButtonRegion = new Region();
    sideMenuButtonRegion.setMinWidth(400);
    HBox sideMenuButtonBox = new HBox();
    sideMenuButtonBox.getChildren().addAll(sideMenuButtonRegion, sideMenuButton);

    // The right VBox containing both the sidebar and the sidebar toggle button.
    VBox rightVBox = new VBox();

    rightVBox.getChildren().addAll(sideMenuButtonBox, sideMenu);
Magnus Eik's avatar
Magnus Eik committed
    this.sideMenu.setStyle("-fx-background-color: lightblue; -fx-background-radius: 5;");
Håvard Daleng's avatar
Håvard Daleng committed
    this.borderPane = new BorderPane();
    this.borderPane.setCenter(imageView);
    this.borderPane.setRight(rightVBox);
Håvard Daleng's avatar
Håvard Daleng committed
    imageView.setFocusTraversable(true);
    rightVBox.setFocusTraversable(false);
Håvard Daleng's avatar
Håvard Daleng committed
    borderPane.setFocusTraversable(false);
  }

   * Initialise the side bar button handler, allowing the user to show or hide the right sidebar.
  private void initializeSideButtonHandler() {
    TranslateTransition openNav = new TranslateTransition(new Duration(350), sideMenu);
    openNav.setToX(0);
    TranslateTransition closeNav = new TranslateTransition(new Duration(350), sideMenu);

    this.sideMenuButton.setOnAction(
        e -> {
          if (sideMenu.getTranslateX() != 0) {
            this.sideMenuButton.setText(">>");
            openNav.play();
          } else {
            closeNav.setToX(sideMenu.getWidth());
            closeNav.play();
            this.sideMenuButton.setText("<<");
          }
        });
Håvard Daleng's avatar
Håvard Daleng committed
    return this.imageView;
  }

   * Update the canvas and set a new zoom factor for the image view based on the ratio between the
   * old and new canvas heights.
  public void updateCanvas(ChaosCanvas canvas) {
    this.chaosCanvas = canvas;
  }

Håvard Daleng's avatar
Håvard Daleng committed
  /**
   * Update the observer based on changes to the chaos game. TODO: this method may need to be
   * changed depending on how we implement the UI. The update method may need to be split.
Håvard Daleng's avatar
Håvard Daleng committed
   *
   * @param game the game this observer is monitoring.
   */
  @Override
Håvard Daleng's avatar
Håvard Daleng committed
  public void updateGame(ChaosGame game) {
    controller.drawChaosGame();
  }
  // GuiButtonObserver methods
  @Override
  public void onStartButtonPressed() {
    controller.startGame();
  }

  @Override
  public void onStopButtonPressed() {
    controller.stopGame();
  }

  @Override
  public void onClearButtonPressed() {
    controller.clearCanvas();
  }

  @Override
  public void onQuitButtonPressed() {
    controller.quitGame();
  }

  @Override
  public void onSaveImageButtonPressed() {
    controller.saveImage();
  }

  @Override
  public void onLoadFractalFromFileButtonPressed() {
    controller.loadFractalFromFile();
  }

  @Override
  public void onWriteToFileButtonPressed() {
    controller.writeFractalToFile();
  }

  @Override
  public void onModifyGameButtonPressed() {
    controller.modifyGame();
  }

  /**
   * Get the step count text field for this GUI.
   *
   * @return the step count text field.
   */
  public TextField getStepCountTextField() {
    return this.stepCountTextField;
  }

  /**
   * Get the iteration limit text field for this GUI.
   *
   * @return the iteration limit text field.
   */
  public TextField getIterationLimitTextField() {
    return this.iterationLimitTextField;
  }

  /**
   * Get the color check box for this GUI.
   *
   * @return the color check box.
   */
  public CheckBox getColorCheckBox() {
    return this.colorCheckBox;
  }

Håvard Daleng's avatar
Håvard Daleng committed
  /**
   * Get the canvas for this GUI.
   *
   * @return the canvas.
   */
  public Canvas getCanvas() {
    return this.canvas;
  /**
   * Get the start button for this GUI.
   *
   * @return the start button.
   */
  public Button getStartButton() {
    return this.startButton;
  }

  /**
   * Get the stop button for this GUI.
   *
   * @return the stop button.
   */
  public Button getStopButton() {
    return this.stopButton;
  }

  /**
   * Get the clear button for this GUI.
   *
   * @return the clear button.
   */
  public Button getClearButton() {
    return this.clearButton;
  }
Håvard Daleng's avatar
Håvard Daleng committed

  /**
   * Get the quit button for this GUI.
   *
   * @return the quit button.
   */
  public Button getQuitButton() {
    return this.quitButton;
  }
  /**
   * Get the write fractal to file button.
   *
   * @return the write fractal to file button.
   */
  public Button getWriteToFileButton() {
    return this.writeFractalToFileButton;
  }
  /**
   * Get the primary stage for this GUI.
   *
   * @return the primary stage.
   */
  public Window getStage() {
    return this.primaryStage;
  }
  /** Resize the canvas to fit the new dimensions of the scene. */
  private void resizeCanvas() {
    double newWidth = scene.getWidth() - sideMenu.getWidth();
    double newHeight = scene.getHeight();

    if (newWidth / newHeight > aspectRatio) {
      newWidth = newHeight * aspectRatio;
    } else {
      newHeight = newWidth / aspectRatio;
    }

    // Update imageView size to new calculated dimensions
    imageView.setFitWidth(newWidth);
    imageView.setFitHeight(newHeight);

    // Redraw the fractal to fit the new canvas size
    controller.drawChaosGame();
  }
Håvard Daleng's avatar
Håvard Daleng committed

  /**
   * Get the load fractal from file button.
   *
   * @return the load fractal from file button.
   */
  public Button getLoadFractalFromFileButton() {
    return this.loadFractalFromFileButton;
  }

  /**
   * Get the modify game button.
   *
   * @return the modify game button.
   */
    return this.modifyGameButton;
  }

  /**
   * Get the description combo box.
   *
   * @return the description combo box.
   */
    return this.descriptionComboBox;
  }
  /**
   * Get the save image button.
   *
   * @return the save image button.
   */
    return this.saveImageButton;
  }