package de.saxsys.projectiler.misc;
import javafx.event.EventHandler;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
/**
* Class for checking whether a point has a minimum distance to an event.
*
* @author alexander.casall
*
*/
public abstract class MouseEventDistanceChecker {
private static final int TRESHOLD = 5;
private boolean alreadyCrossed;
private double startX = -1.0;
private double startY = -1.0;
public MouseEventDistanceChecker(Pane pane) {
initListenersOnPane(pane);
}
private void initListenersOnPane(Pane pane) {
pane.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(final MouseEvent event) {
if (shouldFire(event)) {
fire();
}
}
});
pane.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(final MouseEvent event) {
setStartX(event.getSceneX());
setStartY(event.getSceneY());
reset();
}
});
pane.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(final MouseEvent event) {
checkForAlreadyCrossedTreshold(event);
}
});
}
/**
* Check whether the minimun distance of startX and startY to event is bigger than a treshold.
*
* @param event to check
* @return fire or not
*/
private boolean shouldFire(final MouseEvent event) {
final double deltaX = Math.abs(startX - event.getSceneX());
final double deltaY = Math.abs(startY - event.getSceneY());
if (deltaX > TRESHOLD || deltaY > TRESHOLD) {
return false;
}
return !alreadyCrossed;
}
/**
* Check whether the minimun distance of startX and startY to event is bigger than a treshold. If yes, the
* {@link #shouldFire(double, double, MouseEvent)} will return true the next time.
*
* @param event to check
*/
private void checkForAlreadyCrossedTreshold(final MouseEvent event) {
final double deltaX = Math.abs(startX - event.getSceneX());
final double deltaY = Math.abs(startY - event.getSceneY());
if (deltaX > TRESHOLD || deltaY > TRESHOLD) {
alreadyCrossed = true;
}
}
/**
* Reset the state of the object, so in case of a
* {@link #checkForAlreadyCrossedTreshold(double, double, MouseEvent)} manipulated the behaviour of
* {@link #shouldFire(double, double, MouseEvent)}, it will be reseted.
*/
private void reset() {
alreadyCrossed = false;
}
/**
*
* @param startX initial X of the event. This value will be used for the check.
*/
private void setStartX(final double startX) {
this.startX = startX;
}
/**
*
* @param startY initial Y of the event. This value will be used for the check.
*/
private void setStartY(final double startY) {
this.startY = startY;
}
public abstract void fire();
}