Skip to content
Snippets Groups Projects
Commit 1671807b authored by Håvard Daleng's avatar Håvard Daleng
Browse files

Implemented working zoom and pan functionality.

parent cad88c47
No related branches found
No related tags found
No related merge requests found
package edu.ntnu.stud.chaosgame;
import edu.ntnu.stud.chaosgame.controller.game.ChaosGameDescription;
import edu.ntnu.stud.chaosgame.controller.game.ChaosGameFileHandler;
import edu.ntnu.stud.chaosgame.controller.game.ChaosCanvas;
import edu.ntnu.stud.chaosgame.controller.game.ChaosGame;
import edu.ntnu.stud.chaosgame.model.generators.ChaosGameDescriptionFactory;
import edu.ntnu.stud.chaosgame.view.ChaosGameGUIView;
import edu.ntnu.stud.chaosgame.view.ChaosGameGuiView;
import javafx.application.Application;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.Objects;
import java.util.Scanner;
/**
* Main class for the Chaos Game application.
......@@ -20,7 +13,7 @@ public class Main extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
ChaosGameGUIView view = new ChaosGameGUIView(primaryStage);
ChaosGameGuiView view = new ChaosGameGuiView(primaryStage);
}
......
package edu.ntnu.stud.chaosgame.controller;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
public class PopupManager {
/**
* Display a basic error.
*
* @param header the header of the popup message.
* @param content the content of the popup message.
*/
public static void displayError(String header, String content) {
Alert alert = new Alert(AlertType.ERROR);
alert.setHeaderText(header);
alert.setContentText(content);
alert.showAndWait();
}
}
......@@ -10,7 +10,6 @@ import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
......@@ -26,7 +25,7 @@ import javafx.util.Duration;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;
public class ChaosGameGUIView implements ChaosGameObserver {
public class ChaosGameGuiView implements ChaosGameObserver {
private int currentLine = 0;
/**
......@@ -57,7 +56,7 @@ public class ChaosGameGUIView implements ChaosGameObserver {
/**
* The ImageView for the GUI..
*/
private ImageView imageView;
private ChaosGameImageView imageView;
/**
* The Scene for the GUI..
......@@ -114,7 +113,7 @@ public class ChaosGameGUIView implements ChaosGameObserver {
private RadioButton improvedBarnsleyButton;
public ChaosGameGUIView(Stage primaryStage) throws IOException {
public ChaosGameGuiView(Stage primaryStage) throws IOException {
this.initializeComponents();
......@@ -195,21 +194,22 @@ public class ChaosGameGUIView implements ChaosGameObserver {
*/
private void initializeImageView() {
// Image view
this.imageView = new ImageView();
this.imageView = new ChaosGameImageView(this);
width = 1000;
height = 1000;
WritableImage writableImage = new WritableImage(width, height);
pixelWriter = writableImage.getPixelWriter();
this.imageView.setImage(writableImage);
imageView.setOnScroll(event -> {
this.fillImageView();
/*imageView.setOnScroll(event -> {
double zoomFactor = 1.05; // This is the zoom factor per scroll
double deltaY = event.getDeltaY();
double movement = event.getDeltaY();
imageView.setTranslateX(imageView.getTranslateX() - event.getDeltaX());
imageView.setTranslateY(imageView.getTranslateY() - event.getDeltaY());
if (deltaY > 0) {
if (movement > 0) {
imageView.setScaleX(imageView.getScaleX() * zoomFactor);
imageView.setScaleY(imageView.getScaleY() * zoomFactor);
} else {
......@@ -224,7 +224,20 @@ public class ChaosGameGUIView implements ChaosGameObserver {
imageView.setScaleY(Math.min(imageView.getScaleY(), 10.0)); // max scale
event.consume(); // consume the event so it doesn't propagate further
});
});*/
}
/**
* Color the entire image view white to facilitate scrolling.
*/
private void fillImageView() {
// Color the image white
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
pixelWriter.setColor(x, y, Color.WHITE);
}
}
}
......@@ -255,6 +268,7 @@ public class ChaosGameGUIView implements ChaosGameObserver {
WritableImage newWritableImage = new WritableImage(width, height);
setPixelWriter(newWritableImage.getPixelWriter());
setImageViewFromImage(newWritableImage);
this.fillImageView();
canvas.clearCanvas();
this.descriptionRef.set(factory.getDescriptions().get(0)); // Assuming the Sierpinski description is at index 0
......@@ -269,6 +283,7 @@ public class ChaosGameGUIView implements ChaosGameObserver {
WritableImage newWritableImage = new WritableImage(width, height);
setPixelWriter(newWritableImage.getPixelWriter());
setImageViewFromImage(newWritableImage);
this.fillImageView();
canvas.clearCanvas();
this.descriptionRef.set(factory.getDescriptions().get(1)); // Assuming the Sierpinski description is at index 0
canvasRef.set(new ChaosCanvas(1000, 1000, this.descriptionRef.get().getMinCoords(), this.descriptionRef.get().getMaxCoords()));
......@@ -282,6 +297,7 @@ public class ChaosGameGUIView implements ChaosGameObserver {
WritableImage newWritableImage = new WritableImage(width, height);
setPixelWriter(newWritableImage.getPixelWriter());
setImageViewFromImage(newWritableImage);
this.fillImageView();
canvas.clearCanvas();
this.descriptionRef.set(factory.getDescriptions().get(2)); // Assuming the Sierpinski description is at index 0
canvasRef.set(new ChaosCanvas(1000, 1000, this.descriptionRef.get().getMinCoords(), this.descriptionRef.get().getMaxCoords()));
......@@ -294,6 +310,7 @@ public class ChaosGameGUIView implements ChaosGameObserver {
WritableImage newWritableImage = new WritableImage(width, height);
setPixelWriter(newWritableImage.getPixelWriter());
setImageViewFromImage(newWritableImage);
this.fillImageView();
canvas.clearCanvas();
// Test
......
package edu.ntnu.stud.chaosgame.view;
import edu.ntnu.stud.chaosgame.controller.PopupManager;
import javafx.scene.image.ImageView;
import javafx.scene.input.ScrollEvent;
import javafx.scene.transform.Affine;
/**
* This class extends ImageView to implement proper zooming and panning
* according to the requirements of the chaos game.
*/
public class ChaosGameImageView extends ImageView {
private final ChaosGameGuiView controller;
private final Affine transform = new Affine();
private double lastCentreX;
private double lastCentreY;
private double startX;
private double startY;
public ChaosGameImageView(ChaosGameGuiView controller) {
this.setOnScroll(this::zoom);
this.setOnMousePressed(this::mousePressed);
this.setOnMouseDragged(this::mouseDragged);
this.setOnMouseReleased(this::mouseReleased);
this.getTransforms().add(transform);
this.controller = controller;
this.lastCentreX = (float) controller.getWidth() / 2;
this.lastCentreY = (float) -controller.getHeight() / 2;
//this.setStyle("-fx-background-color: white;");
}
/**
* Zooms the image view in or out based on the scroll event.
*
* @param event the event.
*/
private synchronized void zoom(ScrollEvent event) {
double zoomFactor = event.getDeltaY() > 0 ? 1.20 : 1 / 1.05;
try {
// Get the old values
double oldScaleX = transform.getMxx();
double oldScaleY = transform.getMyy();
double oldTranslateX = transform.getTx();
double oldTranslateY = transform.getTy();
// Compute the new values
double newScaleX = oldScaleX * zoomFactor;
double newScaleY = oldScaleY * zoomFactor;
double newTranslateX = oldTranslateX - (event.getX() * (newScaleX - oldScaleX));
double newTranslateY = oldTranslateY - (event.getY() * (newScaleY - oldScaleY));
// Update the transform
transform.setMxx(newScaleX);
transform.setMyy(newScaleY);
transform.setTx(newTranslateX);
transform.setTy(newTranslateY);
} catch (Exception e) {
PopupManager.displayError("Zoom error", e.getMessage());
}
}
private synchronized void mousePressed(javafx.scene.input.MouseEvent event) {
startX = event.getX();
startY = event.getY();
}
private synchronized void mouseDragged(javafx.scene.input.MouseEvent event) {
double deltaX = event.getX() - startX;
double deltaY = event.getY() - startY;
transform.setTx(transform.getTx() + deltaX);
transform.setTy(transform.getTy() + deltaY);
}
private synchronized void mouseReleased(javafx.scene.input.MouseEvent event) {
double deltaX = event.getX() - startX;
double deltaY = event.getY() - startY;
lastCentreX += deltaX;
lastCentreY += deltaY;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment