diff --git a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/controllers/GameController.java b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/controllers/GameController.java index e513b39b5d28e63cca0505023d9a78e1886f094d..1792ce25fec6aa9fa852250048ee199524b2a4f3 100644 --- a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/controllers/GameController.java +++ b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/controllers/GameController.java @@ -34,12 +34,6 @@ public class GameController { return ChaosGame.getInstance().getDescription().getTransforms(); } - public void setMinCoords(double minX0, double minX1) { - ChaosGame.getInstance().getDescription().setMinCoords(new Vector2D(minX0, minX1)); - } - public void setMaxCoords(double maxX0, double maxX1) { - ChaosGame.getInstance().getDescription().setMaxCoords(new Vector2D(maxX0, maxX1)); - } public void setChaosGameDescription(ChaosGameDescription description) { ChaosGame.getInstance().setDescription(description); } @@ -56,12 +50,11 @@ public class GameController { ChaosGame.getInstance().runSteps(); } - public void setJuliaTransformation(Complex point) { + public void setJuliaTransformation(Complex point, Vector2D minCoords, Vector2D maxCoords) { List<Transform2D> transforms = new ArrayList<>(); - // Add the JuliaTransform to the list of transforms transforms.add(new JuliaTransform(point, -1)); transforms.add(new JuliaTransform(point, 1)); - ChaosGame.getInstance().setDescription(ChaosGameDescription.createWithTransforms(transforms, new Vector2D(-1.6, -1.0), new Vector2D(1.6, 1.0))); + ChaosGame.getInstance().setDescription(ChaosGameDescription.createWithTransforms(transforms, minCoords, maxCoords)); } public void setAffineTransformation(List<Transform2D> transforms, Vector2D minCoords, Vector2D maxCoords) { diff --git a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/models/Complex.java b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/models/Complex.java index eff3584fb2064863c87e3d44d63f89d18ad3ef48..fe3f3f912c7062fc45c31399bf8f81e93da97c9e 100644 --- a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/models/Complex.java +++ b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/models/Complex.java @@ -55,14 +55,6 @@ public class Complex extends Vector2D { return new Complex(realPart, imaginaryPart); } - public Complex negate() { - return new Complex(-getX0(), -getX1()); - } - - public double abs() { - return Math.sqrt(getX0() * getX0() + getX1() * getX1()); - } - public String toString() { return "(" + getX0() + " + " + getX1() + "i)"; } diff --git a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/models/chaos/ChaosGame.java b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/models/chaos/ChaosGame.java index 861557155124b91ff5a597eecbd2f93bbcef2f5d..08feed430272a92c2a405f8d234fbf184e436ed3 100644 --- a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/models/chaos/ChaosGame.java +++ b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/models/chaos/ChaosGame.java @@ -76,12 +76,10 @@ public class ChaosGame { } private void resetGame() { - // Reset or reinitialize internal states, e.g., clearing the canvas, resetting points, etc. - // Assuming there's a method to clear the canvas if (this.canvas != null) { this.canvas.clear(); } - this.currentPoint = new Complex(0, 0); // Reset to default position if applicable + this.currentPoint = new Complex(0, 0); } public void addObserver(ChaosGameObserver observer) { diff --git a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/AffineDialog.java b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/AffineDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..9d6c6408ea78520e6d68f88e17a3423b385ff340 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/AffineDialog.java @@ -0,0 +1,192 @@ +package edu.ntnu.idatt2003.mappevurderingprog2.views.Components; + +import edu.ntnu.idatt2003.mappevurderingprog2.controllers.GameController; +import edu.ntnu.idatt2003.mappevurderingprog2.models.AffineTransform2D; +import edu.ntnu.idatt2003.mappevurderingprog2.models.Matrix2x2; +import edu.ntnu.idatt2003.mappevurderingprog2.models.Transform2D; +import edu.ntnu.idatt2003.mappevurderingprog2.models.Vector2D; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.Dialog; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import javafx.geometry.Insets; +import javafx.geometry.Pos; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +public class AffineDialog { + private Dialog<Void> dialog; + private GameController gameController; + private boolean isEditMode; + private GridPane grid = new GridPane(); + + public AffineDialog(GameController gameController, boolean isEditMode) { + this.gameController = gameController; + this.isEditMode = isEditMode; + setupDialog(); + } + + private void setupDialog() { + dialog = new Dialog<>(); + dialog.setTitle("Edit Affine Transformation"); + + VBox dialogVBox = new VBox(10); + dialogVBox.setPadding(new Insets(10)); + + grid.setHgap(10); + grid.setVgap(10); + grid.setPadding(new Insets(10, 150, 10, 10)); + + TextField stepsField = new TextField(isEditMode ? String.valueOf(gameController.getCurrentSteps()) : ""); + grid.add(new Label("Number of Steps:"), 0, 0); + grid.add(stepsField, 1, 0); + + TextField minCoordsFieldX = new TextField(isEditMode ? String.valueOf(gameController.getCurrentMinCoords().getX0()) : ""); + TextField minCoordsFieldY = new TextField(isEditMode ? String.valueOf(gameController.getCurrentMinCoords().getX1()) : ""); + grid.add(new Label("Min Coordinates X:"), 0, 1); + grid.add(minCoordsFieldX, 1, 1); + grid.add(new Label("Min Coordinates Y:"), 2, 1); + grid.add(minCoordsFieldY, 3, 1); + + TextField maxCoordsFieldX = new TextField(isEditMode ? String.valueOf(gameController.getCurrentMaxCoords().getX0()) : ""); + TextField maxCoordsFieldY = new TextField(isEditMode ? String.valueOf(gameController.getCurrentMaxCoords().getX1()) : ""); + grid.add(new Label("Max Coordinates X:"), 0, 2); + grid.add(maxCoordsFieldX, 1, 2); + grid.add(new Label("Max Coordinates Y:"), 2, 2); + grid.add(maxCoordsFieldY, 3, 2); + + AtomicInteger rowIndex = new AtomicInteger(3); + grid.add(new Label("Matrix"), 0, rowIndex.get()); + grid.add(new Label("Vector"), 1, rowIndex.get()); + rowIndex.incrementAndGet(); + + List<Node[]> transformationFields = new ArrayList<>(); + + if (isEditMode) { + List<Transform2D> affineTransformations = gameController.getAffineTransformations(); + for (Transform2D transform : affineTransformations) { + if (transform instanceof AffineTransform2D) { + addTransformationFields(grid, (AffineTransform2D) transform, rowIndex.get(), transformationFields); + rowIndex.incrementAndGet(); + } + } + } else { + for (int i = 0; i < 3; i++) { + addEmptyTransformationFields(grid, rowIndex.get(), transformationFields); + rowIndex.incrementAndGet(); + } + } + + ScrollPane scrollPane = new ScrollPane(grid); + scrollPane.setFitToWidth(true); + scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); + + HBox editBox = new HBox(10); + editBox.setAlignment(Pos.CENTER_LEFT); + + Button editButton = new Button(isEditMode ? "Edit Fractal" : "Create Fractal"); + editButton.setOnAction(event -> { + try { + int steps = Integer.parseInt(stepsField.getText()); + double minX = Double.parseDouble(minCoordsFieldX.getText()); + double minY = Double.parseDouble(minCoordsFieldY.getText()); + double maxX = Double.parseDouble(maxCoordsFieldX.getText()); + double maxY = Double.parseDouble(maxCoordsFieldY.getText()); + + gameController.setChaosGameSteps(steps); + + List<Transform2D> transforms = new ArrayList<>(); + for (Node[] fields : transformationFields) { + TextField matrixField = (TextField) fields[0]; + TextField vectorField = (TextField) fields[1]; + + double[][] matrixValues = parseMatrix(matrixField.getText()); + double[] vectorValues = parseVector(vectorField.getText()); + + Matrix2x2 matrix = new Matrix2x2(matrixValues[0][0], matrixValues[0][1], matrixValues[1][0], matrixValues[1][1]); + Vector2D vector = new Vector2D(vectorValues[0], vectorValues[1]); + + transforms.add(new AffineTransform2D(matrix, vector)); + } + + gameController.setAffineTransformation(transforms, new Vector2D(minX, minY), new Vector2D(maxX, maxY)); + gameController.setChaosCanvasSize(200, 200); + gameController.runTransformation(); + dialog.close(); + } catch (NumberFormatException e) { + System.out.println("Invalid input for matrix or vector."); + } + }); + + HBox buttonBox = new HBox(10); + buttonBox.setAlignment(Pos.CENTER_RIGHT); + + Button addBtn = new Button("Add Transformation"); + addBtn.setOnAction(event -> { + addEmptyTransformationFields(grid, rowIndex.get(), transformationFields); + rowIndex.incrementAndGet(); + }); + + Button removeBtn = new Button("Remove Transformation"); + removeBtn.setOnAction(event -> { + if (!transformationFields.isEmpty()) { + Node[] lastFields = transformationFields.remove(transformationFields.size() - 1); + grid.getChildren().removeAll(lastFields); + rowIndex.decrementAndGet(); + } + }); + + editBox.getChildren().addAll(editButton); + buttonBox.getChildren().addAll(addBtn, removeBtn); + + dialogVBox.getChildren().addAll(scrollPane, editBox, buttonBox); + dialog.getDialogPane().setContent(dialogVBox); + dialog.getDialogPane().getButtonTypes().add(ButtonType.CLOSE); + } + + private void addTransformationFields(GridPane grid, AffineTransform2D transform, int rowIndex, List<Node[]> fieldList) { + TextField matrixField = new TextField("[" + transform.getMatrix().getA00() + ", " + transform.getMatrix().getA01() + "; " + transform.getMatrix().getA10() + ", " + transform.getMatrix().getA11() + "]"); + TextField vectorField = new TextField("[" + transform.getVector().getX0() + ", " + transform.getVector().getX1() + "]"); + grid.add(matrixField, 0, rowIndex); + grid.add(vectorField, 1, rowIndex); + fieldList.add(new Node[]{matrixField, vectorField}); + } + + private void addEmptyTransformationFields(GridPane grid, int rowIndex, List<Node[]> fieldList) { + TextField matrixField = new TextField("[" + 1.0 + ", " + 0.0 + "; " + 0.0 + ", " + 1.0 + "]"); // Start with an empty field + TextField vectorField = new TextField("[" + 0.0 + ", " + 0.0 + "]"); // Start with an empty field + grid.add(matrixField, 0, rowIndex); + grid.add(vectorField, 1, rowIndex); + fieldList.add(new Node[]{matrixField, vectorField}); + } + + private double[][] parseMatrix(String text) { + text = text.replaceAll("[\\[\\]]", ""); + String[] rows = text.split(";"); + double[][] matrix = new double[2][2]; + for (int i = 0; i < rows.length; i++) { + String[] values = rows[i].split(","); + matrix[i][0] = Double.parseDouble(values[0].trim()); + matrix[i][1] = Double.parseDouble(values[1].trim()); + } + return matrix; + } + + private double[] parseVector(String text) { + text = text.replaceAll("[\\[\\]]", ""); + String[] values = text.split(","); + return new double[]{Double.parseDouble(values[0].trim()), Double.parseDouble(values[1].trim())}; + } + + public void showDialog() { + dialog.showAndWait(); + } +} \ No newline at end of file diff --git a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/CreateFractalMenu.java b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/CreateFractalMenu.java index 19c9d028994d6988497d54c4996b98ff05b60113..7c8249826670bba891e813e2af4cc143fa8e8453 100644 --- a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/CreateFractalMenu.java +++ b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/CreateFractalMenu.java @@ -1,95 +1,32 @@ package edu.ntnu.idatt2003.mappevurderingprog2.views.Components; +import edu.ntnu.idatt2003.mappevurderingprog2.controllers.GameController; +import edu.ntnu.idatt2003.mappevurderingprog2.views.View; import javafx.scene.control.Button; -import javafx.scene.control.Dialog; import javafx.scene.control.Label; -import javafx.scene.control.TextField; -import javafx.scene.control.ButtonType; -import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; -import javafx.geometry.Insets; import javafx.geometry.Pos; public class CreateFractalMenu extends VBox { - public CreateFractalMenu() { + private GameController gameController; + public CreateFractalMenu(View view, GameController gameController) { + this.gameController = gameController; Label headline = new Label("Create a new fractal"); headline.setStyle("-fx-font-size: 16px; -fx-font-weight: bold;"); Button affineButton = new Button("Affine"); - Button juliaButton = new Button("Julia"); + affineButton.setOnAction(event -> { + AffineDialog affineDialog = new AffineDialog(gameController, false); + affineDialog.showDialog(); + }); - affineButton.setOnAction(e -> showAffineDialog()); - juliaButton.setOnAction(e -> showJuliaDialog()); + Button juliaButton = new Button("Julia"); + juliaButton.setOnAction(event -> { + JuliaDialog juliaDialog = new JuliaDialog(gameController, false); + juliaDialog.showDialog(); + }); getChildren().addAll(headline, affineButton, juliaButton); setAlignment(Pos.TOP_CENTER); setSpacing(10); } - - private void showAffineDialog() { - Dialog<Void> dialog = new Dialog<>(); - dialog.setTitle("Affine Transformation"); - - GridPane grid = new GridPane(); - grid.setHgap(10); - grid.setVgap(10); - grid.setPadding(new Insets(20, 150, 10, 10)); - - TextField nameField = new TextField(); - nameField.setPromptText("Name of the fractal"); - TextField matrixField = new TextField(); - matrixField.setPromptText("Type in the matrix"); - TextField vectorField = new TextField(); - vectorField.setPromptText("Type in the vector"); - - Button addTransformationButton = new Button("Add transformation"); - Button saveButton = new Button("Save fractal"); - Button createButton = new Button("Create fractal"); - - grid.add(new Label("Fractal Name:"), 0, 0); - grid.add(nameField, 1, 0); - grid.add(new Label("Matrix:"), 0, 1); - grid.add(matrixField, 1, 1); - grid.add(new Label("Vector:"), 0, 2); - grid.add(vectorField, 1, 2); - grid.add(addTransformationButton, 1, 3); - grid.add(saveButton, 0, 4); - grid.add(createButton, 1, 4); - - dialog.getDialogPane().setContent(grid); - dialog.getDialogPane().getButtonTypes().add(ButtonType.CLOSE); - dialog.showAndWait(); - } - - private void showJuliaDialog() { - Dialog<Void> dialog = new Dialog<>(); - dialog.setTitle("Julia Set"); - - GridPane grid = new GridPane(); - grid.setHgap(10); - grid.setVgap(10); - grid.setPadding(new Insets(20, 150, 10, 10)); - - TextField nameField = new TextField(); - nameField.setPromptText("Name of the fractal"); - TextField realField = new TextField(); - realField.setPromptText("Type in the real part"); - TextField imagField = new TextField(); - imagField.setPromptText("Type in the imaginary part"); - - Button saveButton = new Button("Save fractal"); - Button createButton = new Button("Create fractal"); - - grid.add(new Label("Fractal Name:"), 0, 0); - grid.add(nameField, 1, 0); - grid.add(new Label("Real Part:"), 0, 1); - grid.add(realField, 1, 1); - grid.add(new Label("Imaginary Part:"), 0, 2); - grid.add(imagField, 1, 2); - grid.add(saveButton, 0, 3); - grid.add(createButton, 1, 3); - - dialog.getDialogPane().setContent(grid); - dialog.getDialogPane().getButtonTypes().add(ButtonType.CLOSE); - dialog.showAndWait(); - } } diff --git a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/EditFractalMenu.java b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/EditFractalMenu.java index b3ef31fddca9de960a43391cf47ef3ed5ea0ce9f..3514590c0b3b0b5b5ce79332eb8218c25b7a54f7 100644 --- a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/EditFractalMenu.java +++ b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/EditFractalMenu.java @@ -1,25 +1,14 @@ package edu.ntnu.idatt2003.mappevurderingprog2.views.Components; import edu.ntnu.idatt2003.mappevurderingprog2.controllers.GameController; -import edu.ntnu.idatt2003.mappevurderingprog2.models.AffineTransform2D; -import edu.ntnu.idatt2003.mappevurderingprog2.models.Matrix2x2; -import edu.ntnu.idatt2003.mappevurderingprog2.models.Transform2D; -import edu.ntnu.idatt2003.mappevurderingprog2.models.Vector2D; import edu.ntnu.idatt2003.mappevurderingprog2.views.View; -import java.util.List; import javafx.scene.control.Button; -import javafx.scene.control.ButtonType; -import javafx.scene.control.Dialog; import javafx.scene.control.Label; -import javafx.scene.control.ScrollPane; -import javafx.scene.control.TextField; -import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; -import javafx.geometry.Insets; import javafx.geometry.Pos; public class EditFractalMenu extends VBox { - GameController gameController; + private GameController gameController; public EditFractalMenu(View view, GameController gameController) { this.gameController = gameController; Label editLabel = new Label("Edit current fractal"); @@ -28,11 +17,12 @@ public class EditFractalMenu extends VBox { Button editButton = new Button("Edit"); editButton.setOnAction(event -> { if (gameController.isJuliaTransformation()) { - showJuliaDialog(); + JuliaDialog juliaDialog = new JuliaDialog(gameController, true); + juliaDialog.showDialog(); } else if (gameController.isAffineTransformation()) { - showAffineDialog(); + AffineDialog affineDialog = new AffineDialog(gameController, true); + affineDialog.showDialog(); } else { - // Handle the case where there is no transformation System.out.println("No existing transformation to edit."); } }); @@ -41,168 +31,4 @@ public class EditFractalMenu extends VBox { setAlignment(Pos.TOP_CENTER); setSpacing(10); } - - private void showJuliaDialog() { - Dialog<Void> dialog = new Dialog<>(); - dialog.setTitle("Edit Julia Set"); - - GridPane grid = setupCommonFields(); - addJuliaSpecificFields(grid); - - dialog.getDialogPane().setContent(grid); - dialog.getDialogPane().getButtonTypes().add(ButtonType.CLOSE); - dialog.showAndWait(); - } - - private void showAffineDialog() { - Dialog<Void> dialog = new Dialog<>(); - dialog.setTitle("Edit Affine Transformation"); - - GridPane grid = setupCommonFields(); - addAffineSpecificFields(grid); - - dialog.getDialogPane().setContent(grid); - dialog.getDialogPane().getButtonTypes().add(ButtonType.CLOSE); - dialog.showAndWait(); - } - - private GridPane setupCommonFields() { - GridPane grid = new GridPane(); - grid.setHgap(10); - grid.setVgap(10); - grid.setPadding(new Insets(20, 150, 10, 10)); - - TextField stepsField = new TextField(); - stepsField.setText(String.valueOf(gameController.getCurrentSteps())); - grid.add(new Label("Number of Steps:"), 0, 0); - grid.add(stepsField, 1, 0); - - TextField minCoordsFieldX = new TextField(); - TextField minCoordsFieldY = new TextField(); - minCoordsFieldX.setText(String.valueOf(gameController.getCurrentMinCoords().getX0())); - minCoordsFieldY.setText(String.valueOf(gameController.getCurrentMinCoords().getX1())); - grid.add(new Label("Min Coordinates X:"), 0, 1); - grid.add(minCoordsFieldX, 1, 2); - grid.add(new Label("Min Coordinates Y:"), 2, 1); - grid.add(minCoordsFieldY, 3, 2); - - TextField maxCoordsFieldX = new TextField(); - TextField maxCoordsFieldY = new TextField(); - maxCoordsFieldX.setText(String.valueOf(gameController.getCurrentMaxCoords().getX0())); - maxCoordsFieldY.setText(String.valueOf(gameController.getCurrentMaxCoords().getX1())); - grid.add(new Label("Max Coordinates X:"), 0, 2); - grid.add(maxCoordsFieldX, 1, 1); - grid.add(new Label("Max Coordinates Y:"), 2, 2); - grid.add(maxCoordsFieldY, 3, 1); - - return grid; - } - - - private void addJuliaSpecificFields(GridPane grid) { - TextField realField = new TextField(); - realField.setText(String.valueOf(gameController.getCurrentJuliaPoint().getRealPart())); - grid.add(new Label("Real Part:"), 0, 3); - grid.add(realField, 1, 3); - - TextField imagField = new TextField(); - imagField.setText(String.valueOf(gameController.getCurrentJuliaPoint().getImaginaryPart())); - grid.add(new Label("Imaginary Part:"), 0, 4); - grid.add(imagField, 1, 4); - - Button editButton = new Button("Edit Fractal"); - grid.add(editButton, 1, 5); - } - - private void addAffineSpecificFields(GridPane grid) { - // Add a button for editing transformations instead of direct text fields for matrix and vector - Button editTransformationsButton = new Button("Edit Transformations"); - editTransformationsButton.setOnAction(event -> { - showTransformationEditDialog(); - }); - grid.add(new Label("Transformations:"), 0, 3); - grid.add(editTransformationsButton, 1, 3, 2, 1); // Spanning two columns for better layout - - // Button to submit changes to the fractal - Button editButton = new Button("Edit Fractal"); - grid.add(editButton, 1, 4); - } - - private void showTransformationEditDialog() { - Dialog<Void> dialog = new Dialog<>(); - dialog.setTitle("Edit Affine Transformations"); - - GridPane transformationGrid = new GridPane(); - transformationGrid.setHgap(10); - transformationGrid.setVgap(10); - transformationGrid.setPadding(new Insets(20, 150, 10, 10)); - - // A ScrollPane that will contain the GridPane - ScrollPane scrollPane = new ScrollPane(); - scrollPane.setContent(transformationGrid); - scrollPane.setFitToWidth(true); // Ensures the GridPane width fits the scroll pane - scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); // Vertical scrollbar when needed - scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); // Horizontal scrollbar when needed - - updateGrid(transformationGrid); // Call to populate the grid initially - - dialog.getDialogPane().setContent(scrollPane); // Set the scroll pane as the content of the dialog - dialog.getDialogPane().getButtonTypes().add(ButtonType.CLOSE); - dialog.showAndWait(); - } - - private void updateGrid(GridPane grid) { - grid.getChildren().clear(); // Clear existing content - List<Transform2D> transformations = gameController.getAffineTransformations(); - int row = 0; - for (Transform2D transform : transformations) { - if (transform instanceof AffineTransform2D) { - addMatrixAndVectorFields(grid, (AffineTransform2D) transform, row); - row += 3; // Adjust for matrix, vector, and separator - } - } - - // Always add buttons at the end - addControlButtons(grid, row); - } - - - - private void addMatrixAndVectorFields(GridPane grid, AffineTransform2D transform, int row) { - Matrix2x2 matrix = transform.getMatrix(); - Vector2D vector = transform.getVector(); - - grid.addRow(row, new Label("Matrix:"), new TextField(String.valueOf(matrix.getA00())), - new TextField(String.valueOf(matrix.getA01())), new TextField(String.valueOf(matrix.getA10())), - new TextField(String.valueOf(matrix.getA11()))); - row++; - grid.addRow(row, new Label("Vector:"), new TextField(String.valueOf(vector.getX0())), - new TextField(String.valueOf(vector.getX1()))); - row++; - grid.addRow(row, new Label("------------")); - } - - private void addControlButtons(GridPane grid, int row) { - Button addBtn = new Button("Add Transformation"); - addBtn.setOnAction(e -> addTransformation(grid)); - Button removeBtn = new Button("Remove Transformation"); - removeBtn.setOnAction(e -> removeTransformation(grid)); - - grid.addRow(row, addBtn, removeBtn); - } - - private void addTransformation(GridPane grid) { - // Assume default values for new transformation - AffineTransform2D newTransform = new AffineTransform2D(new Matrix2x2(1, 0, 0, 1), new Vector2D(0, 0)); - gameController.getAffineTransformations().add(newTransform); - updateGrid(grid); // Rebuild the grid with the new transformation - } - - private void removeTransformation(GridPane grid) { - List<Transform2D> transformations = gameController.getAffineTransformations(); - if (!transformations.isEmpty()) { - transformations.remove(transformations.size() - 1); - updateGrid(grid); // Rebuild the grid after removal - } - } } diff --git a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/JuliaDialog.java b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/JuliaDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..d7b0f1d03dc918c4ed399230dcfa9073597ad4f4 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/JuliaDialog.java @@ -0,0 +1,92 @@ +package edu.ntnu.idatt2003.mappevurderingprog2.views.Components; + +import edu.ntnu.idatt2003.mappevurderingprog2.controllers.GameController; +import edu.ntnu.idatt2003.mappevurderingprog2.models.Complex; +import edu.ntnu.idatt2003.mappevurderingprog2.models.Vector2D; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.Dialog; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.geometry.Insets; + +public class JuliaDialog { + private Dialog<Void> dialog; + private GameController gameController; + private boolean isEditMode; + + public JuliaDialog(GameController gameController, boolean isEditMode) { + this.gameController = gameController; + this.isEditMode = isEditMode; + setupDialog(); + } + + private void setupDialog() { + dialog = new Dialog<>(); + dialog.setTitle(isEditMode ? "Edit Julia Set" : "Create Julia Set"); + + GridPane grid = new GridPane(); + grid.setHgap(10); + grid.setVgap(10); + grid.setPadding(new Insets(20, 150, 10, 10)); + + TextField stepsField = new TextField(isEditMode ? String.valueOf(gameController.getCurrentSteps()) : ""); + grid.add(new Label("Number of Steps:"), 0, 0); + grid.add(stepsField, 1, 0); + + TextField minCoordsFieldX = new TextField(isEditMode ? String.valueOf(gameController.getCurrentMinCoords().getX0()) : ""); + TextField minCoordsFieldY = new TextField(isEditMode ? String.valueOf(gameController.getCurrentMinCoords().getX1()) : ""); + grid.add(new Label("Min Coordinates X:"), 0, 1); + grid.add(minCoordsFieldX, 1, 1); + grid.add(new Label("Min Coordinates Y:"), 2, 1); + grid.add(minCoordsFieldY, 3, 1); + + TextField maxCoordsFieldX = new TextField(isEditMode ? String.valueOf(gameController.getCurrentMaxCoords().getX0()) : ""); + TextField maxCoordsFieldY = new TextField(isEditMode ? String.valueOf(gameController.getCurrentMaxCoords().getX1()) : ""); + grid.add(new Label("Max Coordinates X:"), 0, 2); + grid.add(maxCoordsFieldX, 1, 2); + grid.add(new Label("Max Coordinates Y:"), 2, 2); + grid.add(maxCoordsFieldY, 3, 2); + + TextField realField = new TextField(isEditMode && gameController.getCurrentJuliaPoint() != null ? String.valueOf(gameController.getCurrentJuliaPoint().getRealPart()) : ""); + grid.add(new Label("Real Part:"), 0, 3); + grid.add(realField, 1, 3); + + TextField imagField = new TextField(isEditMode && gameController.getCurrentJuliaPoint() != null ? String.valueOf(gameController.getCurrentJuliaPoint().getImaginaryPart()) : ""); + grid.add(new Label("Imaginary Part:"), 0, 4); + grid.add(imagField, 1, 4); + + Button editButton = new Button(isEditMode ? "Edit Fractal" : "Create Fractal"); + editButton.setOnAction(event -> handleAction(stepsField, minCoordsFieldX, minCoordsFieldY, maxCoordsFieldX, maxCoordsFieldY, realField, imagField)); + grid.add(editButton, 1, 5); + + dialog.getDialogPane().setContent(grid); + dialog.getDialogPane().getButtonTypes().add(ButtonType.CLOSE); + } + + private void handleAction(TextField stepsField, TextField minCoordsFieldX, TextField minCoordsFieldY, TextField maxCoordsFieldX, TextField maxCoordsFieldY, TextField realField, TextField imagField) { + try { + int steps = Integer.parseInt(stepsField.getText()); + double minX = Double.parseDouble(minCoordsFieldX.getText()); + double minY = Double.parseDouble(minCoordsFieldY.getText()); + double maxX = Double.parseDouble(maxCoordsFieldX.getText()); + double maxY = Double.parseDouble(maxCoordsFieldY.getText()); + double real = Double.parseDouble(realField.getText()); + double imag = Double.parseDouble(imagField.getText()); + + Complex newPoint = new Complex(real, imag); + gameController.setChaosGameSteps(steps); + gameController.setJuliaTransformation(newPoint, new Vector2D(minX, minY), new Vector2D(maxX, maxY)); + gameController.setChaosCanvasSize(200, 200); + gameController.runTransformation(); + dialog.close(); + } catch (NumberFormatException e) { + System.out.println("Invalid input for complex number."); + } + } + + public void showDialog() { + dialog.showAndWait(); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/Menu.java b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/Menu.java index 47d7a8c1cdd5af9d17acfa6435a4366966bdef27..98f63f30943ea39bbeeab7e26a498b89b2f3f8f6 100644 --- a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/Menu.java +++ b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/Menu.java @@ -15,7 +15,7 @@ public class Menu extends VBox { public Menu(View view, GameController gameController) { existingFractalsMenu = new ExistingFractalsMenu(view, gameController); - createFractalMenu = new CreateFractalMenu(); + createFractalMenu = new CreateFractalMenu(view, gameController); editFractalMenu = new EditFractalMenu(view, gameController); extraUserOptions = new ExtraUserOptions(view.getMainCanvas()); initializeMenu(); diff --git a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/TransformationButton.java b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/TransformationButton.java index 7fc5a9def2ad9b85af558825d04e27e3a6c1b0f3..a369721c9ea8597eb8d74be83beff6ab6094ae5c 100644 --- a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/TransformationButton.java +++ b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/Components/TransformationButton.java @@ -20,7 +20,7 @@ public abstract class TransformationButton extends Button { private GameController gameController; public TransformationButton(String label, GameController gameController, View view, Canvas transformationCanvas, ChaosGameDescription chaosGameDescription, int height, int width) { - super(label); // Sets the label of the button + super(label); this.gameController = gameController; this.view = view; this.transformationCanvas = transformationCanvas; @@ -34,6 +34,6 @@ public abstract class TransformationButton extends Button { gameController.setChaosGameDescription(chaosGameDescription); gameController.setChaosCanvasSize(width, height); gameController.runTransformation(); - });// Set the action on button press + }); } } diff --git a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/View.java b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/View.java index c545a8abcb7a56376f66a01b42b7694de7d16789..65d1484a07a352eb55b118aec115e987c72bf585 100644 --- a/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/View.java +++ b/src/main/java/edu/ntnu/idatt2003/mappevurderingprog2/views/View.java @@ -2,6 +2,7 @@ package edu.ntnu.idatt2003.mappevurderingprog2.views; import edu.ntnu.idatt2003.mappevurderingprog2.controllers.GameController; import edu.ntnu.idatt2003.mappevurderingprog2.views.Components.ExtraUserOptions; +import edu.ntnu.idatt2003.mappevurderingprog2.views.Components.JuliaDialog; import edu.ntnu.idatt2003.mappevurderingprog2.views.Components.Menu; import edu.ntnu.idatt2003.mappevurderingprog2.views.Components.Zoom; import edu.ntnu.idatt2003.mappevurderingprog2.models.chaos.ChaosCanvas; @@ -23,7 +24,6 @@ import javafx.scene.layout.*; import javafx.scene.paint.Color; public class View extends BorderPane implements ChaosGameObserver { - private Canvas mainCanvas; private GameController gameController; private Menu menu;