aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/jcgp/gui/constants/Position.java8
-rw-r--r--src/jcgp/gui/handlers/InputHandlers.java5
-rw-r--r--src/jcgp/gui/handlers/NodeHandlers.java107
-rw-r--r--src/jcgp/gui/handlers/OutputHandlers.java9
-rw-r--r--src/jcgp/gui/handlers/Target.java70
-rw-r--r--src/jcgp/gui/population/GUIGene.java21
-rw-r--r--src/jcgp/gui/population/GUIMutable.java10
-rw-r--r--src/jcgp/gui/population/GUINode.java25
-rw-r--r--src/jcgp/gui/population/GUIOutput.java13
9 files changed, 234 insertions, 34 deletions
diff --git a/src/jcgp/gui/constants/Position.java b/src/jcgp/gui/constants/Position.java
index cba5373..6d4e02b 100644
--- a/src/jcgp/gui/constants/Position.java
+++ b/src/jcgp/gui/constants/Position.java
@@ -51,8 +51,8 @@ public final class Position {
// use the offset and the socket positions to connect the lines
for (int i = 0; i < GUI.resources.arity(); i++) {
- node.getLine(i).setStartX(node.getSocket(i).getCenterX() + xOffset + Constants.NODE_RADIUS + Constants.SOCKET_RADIUS);
- node.getLine(i).setStartY(node.getSocket(i).getCenterY() + yOffset + Constants.NODE_RADIUS);
+ node.getLines()[i].setStartX(node.getSocket(i).getCenterX() + xOffset + Constants.NODE_RADIUS + Constants.SOCKET_RADIUS);
+ node.getLines()[i].setStartY(node.getSocket(i).getCenterY() + yOffset + Constants.NODE_RADIUS);
}
}
@@ -67,8 +67,8 @@ public final class Position {
// the output's position is a function of the number of columns and its own index
output.relocate(((GUI.resources.columns() + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.CHROMOSOME_PANE_MARGIN,
output.getOutput().getIndex() * (2 * Constants.NODE_RADIUS + Constants.SPACING) + Constants.CHROMOSOME_PANE_MARGIN);
- output.getLine().setStartX(output.getLayoutX() - Constants.NODE_RADIUS);
- output.getLine().setStartY(output.getLayoutY());
+ output.getLines()[0].setStartX(output.getLayoutX() - Constants.NODE_RADIUS);
+ output.getLines()[0].setStartY(output.getLayoutY());
}
/**
diff --git a/src/jcgp/gui/handlers/InputHandlers.java b/src/jcgp/gui/handlers/InputHandlers.java
index 1d18ef5..cc677eb 100644
--- a/src/jcgp/gui/handlers/InputHandlers.java
+++ b/src/jcgp/gui/handlers/InputHandlers.java
@@ -17,6 +17,11 @@ import jcgp.gui.population.GUIInput;
*
*/
public final class InputHandlers {
+
+ /**
+ * Private constructor to prevent instantiation.
+ */
+ private InputHandlers() {}
/**
* Inputs don't do much; set state to hover when mouse enters.
diff --git a/src/jcgp/gui/handlers/NodeHandlers.java b/src/jcgp/gui/handlers/NodeHandlers.java
index 10a334a..b413a62 100644
--- a/src/jcgp/gui/handlers/NodeHandlers.java
+++ b/src/jcgp/gui/handlers/NodeHandlers.java
@@ -1,9 +1,15 @@
package jcgp.gui.handlers;
import javafx.event.EventHandler;
+import javafx.scene.input.MouseDragEvent;
import javafx.scene.input.MouseEvent;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
import jcgp.backend.population.Gene;
import jcgp.gui.GUI;
+import jcgp.gui.constants.Position;
+import jcgp.gui.population.ChromosomePane;
+import jcgp.gui.population.GUIConnection;
import jcgp.gui.population.GUIGene;
import jcgp.gui.population.GUIGene.GUIGeneState;
import jcgp.gui.population.GUINode;
@@ -22,6 +28,11 @@ import jcgp.gui.population.GUINode;
public final class NodeHandlers {
/**
+ * Private constructor to prevent instantiation.
+ */
+ private NodeHandlers() {}
+
+ /**
* Set the node to {@code GUIGeneState.HOVER} state, and set its immediate connections to {@code GUIGeneState.EXTENDED_HOVER}.
*/
private static EventHandler<MouseEvent> mouseEnteredHandler = new EventHandler<MouseEvent>() {
@@ -29,7 +40,7 @@ public final class NodeHandlers {
public void handle(MouseEvent event) {
// acquire the source, we can safely cast it to GUINode
GUINode source = (GUINode) event.getSource();
-
+
source.setState(GUIGeneState.HOVER);
for (int i = 0; i < GUI.resources.arity(); i++) {
((GUIGene) ((Gene) source.getNode().getConnection(i)).getGUIObject()).setState(GUIGeneState.EXTENDED_HOVER);
@@ -46,13 +57,89 @@ public final class NodeHandlers {
// acquire the source, we can safely cast it to GUINode
GUINode source = (GUINode) event.getSource();
- source.setState(GUIGeneState.NEUTRAL);
- for (int i = 0; i < GUI.resources.arity(); i++) {
- ((GUIGene) ((Gene) source.getNode().getConnection(i)).getGUIObject()).setState(GUIGeneState.NEUTRAL);
+ if (Target.getSourceMutable() != source) {
+ source.setState(GUIGeneState.NEUTRAL);
+ for (int i = 0; i < GUI.resources.arity(); i++) {
+ ((GUIGene) ((Gene) source.getNode().getConnection(i)).getGUIObject()).setState(GUIGeneState.NEUTRAL);
+ }
+ }
+ }
+ };
+
+ private static EventHandler<MouseEvent> socketDragDetected = new EventHandler<MouseEvent>() {
+ @Override
+ public void handle(MouseEvent event) {
+ // it's safe to assume that the source is the socket
+ ((GUINode) ((Circle) event.getSource()).getParent()).startFullDrag();
+ }
+ };
+
+ private static EventHandler<MouseEvent> socketMousePressedHandler = new EventHandler<MouseEvent>() {
+ @Override
+ public void handle(MouseEvent event) {
+ // it's safe to assume that the source is the socket
+ Target.start((Circle) event.getSource());
+ }
+ };
+
+ private static EventHandler<MouseEvent> socketMouseDraggedHandler = new EventHandler<MouseEvent>() {
+ @Override
+ public void handle(MouseEvent event) {
+ // this can only happen after a press, so we know Target is up-to-date
+ if (!Target.isProspecting()) {
+ GUINode node = (GUINode) Target.getSourceMutable();
+ Line line = Target.getConnectionLine();
+ line.setEndX(event.getX() + node.getLayoutX());
+ line.setEndY(event.getY() + node.getLayoutY());
+ }
+
+ }
+ };
+
+ private static EventHandler<MouseEvent> socketMouseReleasedHandler = new EventHandler<MouseEvent>() {
+ @Override
+ public void handle(MouseEvent event) {
+
+ GUINode node = (GUINode) ((Circle) event.getSource()).getParent();
+ int connectionId = Integer.valueOf(((Circle) event.getSource()).getId());
+
+ Position.connect(node.getLines()[connectionId], (GUIGene) ((Gene) node.getNode().getConnection(connectionId)).getGUIObject());
+ }
+ };
+
+ private static EventHandler<MouseDragEvent> dragEnteredHandler = new EventHandler<MouseDragEvent>() {
+ @Override
+ public void handle(MouseDragEvent event) {
+ // acquire the source, we can safely cast it to GUINode
+ GUINode source = (GUINode) event.getSource();
+ if (Target.getCurrentConnection() == source) {
+ source.setState(GUIGeneState.NEUTRAL_TARGET);
+ // we are now prospecting
+ Target.setProspecting(true);
+ Position.connect(Target.getConnectionLine(), source);
+ } else if (ChromosomePane.isAllowed(Target.getSourceMutable(), (GUIConnection) source)) {
+ source.setState(GUIGeneState.GOOD_TARGET);
+ // we are now prospecting
+ Target.setProspecting(true);
+ Position.connect(Target.getConnectionLine(), source);
+ } else {
+ source.setState(GUIGeneState.BAD_TARGET);
}
}
};
+ private static EventHandler<MouseDragEvent> dragExitedHandler = new EventHandler<MouseDragEvent>() {
+ @Override
+ public void handle(MouseDragEvent event) {
+ // acquire the source, we can safely cast it to GUINode
+ GUINode source = (GUINode) event.getSource();
+ source.setState(GUIGeneState.NEUTRAL);
+
+ // no longer prospecting
+ Target.setProspecting(false);
+ }
+ };
+
/**
* Adds all handlers to the specified node.
*
@@ -61,5 +148,17 @@ public final class NodeHandlers {
public static void addHandlers(GUINode node) {
node.addEventHandler(MouseEvent.MOUSE_ENTERED, mouseEnteredHandler);
node.addEventHandler(MouseEvent.MOUSE_EXITED, mouseExitedHandler);
+
+ node.addEventHandler(MouseDragEvent.MOUSE_DRAG_ENTERED, dragEnteredHandler);
+ node.addEventHandler(MouseDragEvent.MOUSE_DRAG_EXITED, dragExitedHandler);
+
+ Circle[] sockets = node.getSockets();
+ for (int s = 0; s < sockets.length; s++) {
+
+ sockets[s].addEventFilter(MouseEvent.DRAG_DETECTED, socketDragDetected);
+ sockets[s].addEventHandler(MouseEvent.MOUSE_PRESSED, socketMousePressedHandler);
+ sockets[s].addEventHandler(MouseEvent.MOUSE_DRAGGED, socketMouseDraggedHandler);
+ sockets[s].addEventHandler(MouseEvent.MOUSE_RELEASED, socketMouseReleasedHandler);
+ }
}
}
diff --git a/src/jcgp/gui/handlers/OutputHandlers.java b/src/jcgp/gui/handlers/OutputHandlers.java
index f72e430..b89d746 100644
--- a/src/jcgp/gui/handlers/OutputHandlers.java
+++ b/src/jcgp/gui/handlers/OutputHandlers.java
@@ -19,6 +19,11 @@ import jcgp.gui.population.GUIOutput;
*
*/
public final class OutputHandlers {
+
+ /**
+ * Private constructor to prevent instantiation.
+ */
+ private OutputHandlers() {}
/**
* Set the output to {@code GUIGeneState.HOVER} state, and recursively set its active genes
@@ -50,8 +55,8 @@ public final class OutputHandlers {
};
/**
- * If the output is locked, unlock it and all of its associated genes recursively. If it is unlocked,
- * lock it and its active genes.
+ * If the output is locked, unlock it and all of its associated genes recursively.
+ * If it is unlocked, lock it and its active genes.
*/
private static EventHandler<MouseEvent> mouseClickHandler = new EventHandler<MouseEvent>() {
@Override
diff --git a/src/jcgp/gui/handlers/Target.java b/src/jcgp/gui/handlers/Target.java
new file mode 100644
index 0000000..b050663
--- /dev/null
+++ b/src/jcgp/gui/handlers/Target.java
@@ -0,0 +1,70 @@
+package jcgp.gui.handlers;
+
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
+import jcgp.gui.population.GUIConnection;
+import jcgp.gui.population.GUIMutable;
+
+/**
+ * @author Eduardo Pedroni
+ *
+ */
+public final class Target {
+
+ /**
+ * Private constructor to prevent instantiation.
+ */
+ private Target() {}
+
+ private static GUIConnection targetConnection;
+ private static GUIMutable sourceMutable;
+ private static int connectionIndex;
+ private static Line connectionLine;
+ private static Circle sourceSocket;
+ private static boolean prospecting = false;
+
+ public static void start(Circle newSocket) {
+ // store new socket
+ sourceSocket = newSocket;
+ // derive the rest of the information from it
+ connectionIndex = Integer.valueOf(newSocket.getId());
+ sourceMutable = (GUIMutable) newSocket.getParent();
+ connectionLine = sourceMutable.getLines()[connectionIndex];
+ }
+
+ public static GUIMutable getSourceMutable() {
+ return sourceMutable;
+ }
+
+ public static int getConnectionIndex() {
+ return connectionIndex;
+ }
+
+ public static Line getConnectionLine() {
+ return connectionLine;
+ }
+
+ public static Circle getSourceSocket() {
+ return sourceSocket;
+ }
+
+ public static GUIConnection getTarget() {
+ return targetConnection;
+ }
+
+ public static GUIConnection getCurrentConnection() {
+ return sourceMutable.getConnections()[connectionIndex];
+ }
+
+ public static void setProspecting(boolean value) {
+ prospecting = value;
+ }
+
+ public static boolean isProspecting() {
+ return prospecting;
+ }
+
+ public static void setTarget(GUIConnection newTarget) {
+ targetConnection = newTarget;
+ }
+}
diff --git a/src/jcgp/gui/population/GUIGene.java b/src/jcgp/gui/population/GUIGene.java
index f0fd568..5e6107f 100644
--- a/src/jcgp/gui/population/GUIGene.java
+++ b/src/jcgp/gui/population/GUIGene.java
@@ -54,7 +54,13 @@ public abstract class GUIGene extends Group {
/**
* User is hovering over an output connected to this gene.
*/
- ACTIVE_HOVER
+ ACTIVE_HOVER,
+
+ GOOD_TARGET,
+
+ NEUTRAL_TARGET,
+
+ BAD_TARGET
}
private GUIGeneState currentState = GUIGeneState.NEUTRAL;
@@ -119,7 +125,7 @@ public abstract class GUIGene extends Group {
switch (newState) {
case NEUTRAL:
mainCircle.setFill(isLocked() ? Constants.HARD_HIGHLIGHT_PAINT : Constants.NEUTRAL_PAINT);
- setLinesVisible(isLocked() ? true : false);
+ setLinesVisible(isLocked());
break;
case HOVER:
mainCircle.setFill(Constants.MEDIUM_HIGHLIGHT_PAINT);
@@ -127,12 +133,21 @@ public abstract class GUIGene extends Group {
break;
case EXTENDED_HOVER:
mainCircle.setFill(Constants.SOFT_HIGHLIGHT_PAINT);
- setLinesVisible(isLocked() ? true : false);
+ setLinesVisible(isLocked());
break;
case ACTIVE_HOVER:
mainCircle.setFill(Constants.SOFT_HIGHLIGHT_PAINT);
setLinesVisible(true);
break;
+ case GOOD_TARGET:
+ mainCircle.setFill(Constants.GOOD_SELECTION_PAINT);
+ break;
+ case NEUTRAL_TARGET:
+ mainCircle.setFill(Constants.NEUTRAL_SELECTION_PAINT);
+ break;
+ case BAD_TARGET:
+ mainCircle.setFill(Constants.BAD_SELECTION_PAINT);
+ break;
}
currentState = newState;
}
diff --git a/src/jcgp/gui/population/GUIMutable.java b/src/jcgp/gui/population/GUIMutable.java
index b210672..fa996e2 100644
--- a/src/jcgp/gui/population/GUIMutable.java
+++ b/src/jcgp/gui/population/GUIMutable.java
@@ -1,5 +1,7 @@
package jcgp.gui.population;
+import javafx.scene.shape.Line;
+
/**
* A loose equivalent to {@link jcgp.backend.population.Mutable}.
* <br>
@@ -9,4 +11,10 @@ package jcgp.gui.population;
* @author Eduardo Pedroni
*
*/
-public interface GUIMutable {}
+public interface GUIMutable {
+
+ public Line[] getLines();
+
+ public GUIConnection[] getConnections();
+
+}
diff --git a/src/jcgp/gui/population/GUINode.java b/src/jcgp/gui/population/GUINode.java
index ee98f22..1a32426 100644
--- a/src/jcgp/gui/population/GUINode.java
+++ b/src/jcgp/gui/population/GUINode.java
@@ -76,21 +76,7 @@ public class GUINode extends GUIGene implements GUIMutable, GUIConnection {
this.node = node;
}
- /**
- * Returns one of this object's connection lines. Lines are
- * indexed in the same order as sockets and the connections
- * they represent.
- *
- * @param index the line to return.
- * @return the indexed line object.
- */
- public Line getLine(int index) {
- return lines[index];
- }
-
- /**
- * @return the entire {@code Line} array.
- */
+ @Override
public Line[] getLines() {
return lines;
}
@@ -136,4 +122,13 @@ public class GUINode extends GUIGene implements GUIMutable, GUIConnection {
((GUIConnection) ((Gene) node.getConnection(i)).getGUIObject()).setLockRecursively(value);
}
}
+
+ @Override
+ public GUIConnection[] getConnections() {
+ GUIConnection[] connections = new GUIConnection[GUI.resources.arity()];
+ for (int c = 0; c < connections.length; c++) {
+ connections[c] = (GUIConnection) ((Gene) node.getConnection(c)).getGUIObject();
+ }
+ return connections;
+ }
}
diff --git a/src/jcgp/gui/population/GUIOutput.java b/src/jcgp/gui/population/GUIOutput.java
index 3bc81d9..f023d00 100644
--- a/src/jcgp/gui/population/GUIOutput.java
+++ b/src/jcgp/gui/population/GUIOutput.java
@@ -62,15 +62,18 @@ public class GUIOutput extends GUIGene implements GUIMutable {
this.output = output;
}
- /**
- * @return this output's single connection line.
- */
- public Line getLine() {
- return line;
+ @Override
+ public Line[] getLines() {
+ return new Line[] {line};
}
@Override
protected void setLinesVisible(boolean value) {
line.setVisible(value);
}
+
+ @Override
+ public GUIConnection[] getConnections() {
+ return new GUIConnection[] {(GUIConnection) output.getGUIObject()};
+ }
}