From 0c288cc1952809294c8d70d86b9f41b04878ac2e Mon Sep 17 00:00:00 2001 From: Eduardo Pedroni Date: Sun, 23 Mar 2014 18:05:13 +0000 Subject: Majorly refactored, node grid is fully implemented. About to attempt active path locking. --- src/jcgp/gui/population/GUIOutput.java | 277 +++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 src/jcgp/gui/population/GUIOutput.java (limited to 'src/jcgp/gui/population/GUIOutput.java') diff --git a/src/jcgp/gui/population/GUIOutput.java b/src/jcgp/gui/population/GUIOutput.java new file mode 100644 index 0000000..602a022 --- /dev/null +++ b/src/jcgp/gui/population/GUIOutput.java @@ -0,0 +1,277 @@ +package jcgp.gui.population; + +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.event.EventHandler; +import javafx.geometry.VPos; +import javafx.scene.control.Label; +import javafx.scene.input.MouseDragEvent; +import javafx.scene.input.MouseEvent; +import javafx.scene.paint.Paint; +import javafx.scene.shape.Circle; +import javafx.scene.shape.Line; +import javafx.scene.text.Font; +import javafx.scene.text.Text; +import javafx.scene.text.TextAlignment; +import jcgp.GUI; +import jcgp.CGP.Resources; +import jcgp.population.Connection; +import jcgp.population.Input; +import jcgp.population.Node; +import jcgp.population.Output; + +public class GUIOutput extends GUIGene { + + private Circle socket; + + private Label connectionLabel; + + private Line sourceLine; + + private Output output; + + public GUIOutput(ChromosomePane parentRef, final Output output, Resources resources, Line line) { + + this.parent = parentRef; + this.output = output; + this.sourceLine = line; + + relocate((((int) resources.get("columns") + 1) * (2 * NODE_RADIUS + SPACING)) + NODE_RADIUS, + (output.getIndex() * (2 * NODE_RADIUS + SPACING)) + NODE_RADIUS); + + // set the line ends correctly + updateLine(); + + mainCircle = new Circle(NODE_RADIUS, Paint.valueOf("white")); + mainCircle.setStroke(Paint.valueOf("black")); + + text = new Text("O: " + output.getIndex()); + text.setFont(Font.font("Arial", 12)); + text.setTextOrigin(VPos.CENTER); + text.setTextAlignment(TextAlignment.CENTER); + text.setWrappingWidth(NODE_RADIUS * 2); + text.setX(-NODE_RADIUS); + text.setVisible(true); + + socket = new Circle(-NODE_RADIUS, 0, SOCKET_RADIUS, Paint.valueOf("white")); + socket.setId(String.valueOf(0)); + socket.setStroke(Paint.valueOf("black")); + + connectionLabel = new Label("S"); + connectionLabel.setStyle("-fx-background-color:rgb(255, 255, 255); -fx-border-color:rgba(0, 0, 0, 0.5); "); + connectionLabel.relocate(socket.getCenterX() + 5, socket.getCenterY() - 10); + connectionLabel.setVisible(false); + + /* + * Mouse event handlers on sockets + * + */ + socket.addEventFilter(MouseDragEvent.DRAG_DETECTED, new EventHandler() { + @Override + public void handle(MouseEvent event) { + // the mouse has been dragged out of the socket, this means a full drag is in progress + startFullDrag(); + } + }); + + socket.addEventFilter(MouseEvent.MOUSE_ENTERED, new EventHandler() { + @Override + public void handle(MouseEvent event) { + // user is hovering over connection socket + connectionLabel.setVisible(true); + } + }); + + socket.addEventFilter(MouseEvent.MOUSE_EXITED, new EventHandler() { + @Override + public void handle(MouseEvent event) { + // user exits the connection socket + connectionLabel.setVisible(false); + } + }); + + socket.addEventFilter(MouseDragEvent.MOUSE_PRESSED, new EventHandler() { + @Override + public void handle(MouseEvent event) { + // mouse was pressed on the socket + stateProperty.set(GUIGeneState.SOURCE); + } + }); + + socket.addEventFilter(MouseDragEvent.MOUSE_DRAGGED, new EventHandler() { + @Override + public void handle(MouseEvent event) { + sourceLine.setEndX(event.getX() + ((Circle) event.getSource()).getParent().getLayoutX()); + sourceLine.setEndY(event.getY() + ((Circle) event.getSource()).getParent().getLayoutY()); + } + }); + + socket.addEventFilter(MouseDragEvent.MOUSE_RELEASED, new EventHandler() { + @Override + public void handle(MouseEvent event) { + if (event.isDragDetect()) { + // mouse was released before dragging out of the socket + updateLine(); + stateProperty.set(GUIGeneState.HOVER); + } + } + }); + + + /* + * Mouse event handlers on whole gene + */ + addEventFilter(MouseDragEvent.MOUSE_DRAG_ENTERED, new EventHandler() { + @Override + public void handle(MouseDragEvent event) { + // the drag has entered this node, react appropriately + stateProperty.set(GUIGeneState.FORBIDDEN_TARGET); + } + }); + + addEventFilter(MouseDragEvent.MOUSE_DRAG_OVER, new EventHandler() { + @Override + public void handle(MouseDragEvent event) { + // the user is dragging over this node, react appropriately + // this happens even if we are the source of the drag + + } + }); + + addEventFilter(MouseDragEvent.MOUSE_DRAG_EXITED, new EventHandler() { + @Override + public void handle(MouseDragEvent event) { + // the drag has exited this node, react appropriately + // this happens even if we are the source of the drag + if (event.isPrimaryButtonDown()) { + if (event.getGestureSource() == event.getSource()) { + stateProperty.set(GUIGeneState.SOURCE); + } else { + if (stateProperty.get() == GUIGeneState.NO_CHANGE_TARGET) { + stateProperty.set(GUIGeneState.INDIRECT_HOVER); + } else { + stateProperty.set(GUIGeneState.NEUTRAL); + } + } + } + } + }); + + addEventFilter(MouseDragEvent.MOUSE_DRAG_RELEASED, new EventHandler() { + @Override + public void handle(MouseDragEvent event) { + // making a connection to an output is illegal + // set states to reflect the new situation + ((GUIGene) event.getGestureSource()).setState(GUIGeneState.NEUTRAL); + ((GUIGene) event.getGestureSource()).setConnections(GUIGeneState.NEUTRAL); + stateProperty.set(GUIGeneState.HOVER); + } + }); + + + addEventFilter(MouseEvent.MOUSE_ENTERED, new EventHandler() { + @Override + public void handle(MouseEvent event) { + // cursor has entered this node without dragging, or it is dragging and this is the source + if (stateProperty.get() == GUIGeneState.NEUTRAL) { + stateProperty.set(GUIGeneState.HOVER); + } + } + }); + + addEventFilter(MouseEvent.MOUSE_EXITED, new EventHandler() { + @Override + public void handle(MouseEvent event) { + // cursor has left this node without dragging, or it is dragging and this is the source + if (stateProperty.get() == GUIGeneState.HOVER) { + stateProperty.set(GUIGeneState.NEUTRAL); + setConnections(GUIGeneState.NEUTRAL); + } + } + }); + + + getChildren().addAll(mainCircle, text, socket, connectionLabel); + + stateProperty.addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, GUIGeneState oldValue, GUIGeneState newValue) { + + + switch (newValue) { + case ACTIVE_HOVER: + break; + case FORBIDDEN_TARGET: + mainCircle.setFill(Paint.valueOf(GUI.BAD_SELECTION_COLOUR)); + break; + case HOVER: + mainCircle.setFill(Paint.valueOf(GUI.HARD_HIGHLIGHT_COLOUR)); + sourceLine.setVisible(true); + setConnections(GUIGeneState.ACTIVE_HOVER); + break; + case INDIRECT_HOVER: + mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); + break; + case NEUTRAL: + mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_COLOUR)); + sourceLine.setVisible(false); + break; + case NO_CHANGE_TARGET: + mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_SELECTION_COLOUR)); + break; + case SOURCE: + mainCircle.setFill(Paint.valueOf(GUI.HARD_HIGHLIGHT_COLOUR)); + break; + case TARGET: + mainCircle.setFill(Paint.valueOf(GUI.GOOD_SELECTION_COLOUR)); + break; + default: + break; + + } + } + }); + + output.sourceProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, + Connection oldValue, Connection newValue) { + updateLine(); + } + }); + + } + + public void updateLine() { + if (output.getSource() instanceof Node) { + int row = ((Node) output.getSource()).getRow(), + column = ((Node) output.getSource()).getColumn(); + sourceLine.setEndX(((column + 1) * (2 * NODE_RADIUS + SPACING)) + 2 * NODE_RADIUS); + sourceLine.setEndY((row * (2 * NODE_RADIUS + SPACING)) + NODE_RADIUS); + } else if (output.getSource() instanceof Input) { + int inputIndex = ((Input) output.getSource()).getIndex(); + sourceLine.setEndX(2 * NODE_RADIUS); + sourceLine.setEndY(inputIndex * (2 * NODE_RADIUS + SPACING) + NODE_RADIUS); + } + } + + @Override + public Output getGene() { + return output; + } + + @Override + public void setConnections(GUIGeneState newState) { + if (output.getSource() instanceof Node) { + parent.getGuiNode(((Node) output.getSource()).getRow(), ((Node) output.getSource()).getColumn()).setState(newState); + } else if (output.getSource() instanceof Input) { + parent.getGuiInput(((Input) output.getSource()).getIndex()).setState(newState); + } + } + + @Override + public void resetState() { + stateProperty.set(GUIGeneState.NEUTRAL); + setConnections(GUIGeneState.NEUTRAL); + } +} -- cgit v1.2.3