diff options
Diffstat (limited to 'src/jcgp/gui/population/GUIInput.java')
-rw-r--r-- | src/jcgp/gui/population/GUIInput.java | 241 |
1 files changed, 202 insertions, 39 deletions
diff --git a/src/jcgp/gui/population/GUIInput.java b/src/jcgp/gui/population/GUIInput.java index 3db7416..8b55a58 100644 --- a/src/jcgp/gui/population/GUIInput.java +++ b/src/jcgp/gui/population/GUIInput.java @@ -1,70 +1,233 @@ package jcgp.gui.population; +import javafx.event.EventHandler; +import javafx.scene.input.MouseDragEvent; +import javafx.scene.input.MouseEvent; import javafx.scene.paint.Paint; import javafx.scene.shape.Circle; +import jcgp.backend.population.Connection; import jcgp.backend.population.Input; import jcgp.gui.constants.Constants; -import jcgp.gui.constants.Position; -import jcgp.gui.handlers.InputHandlers; -/** - * The GUI counterpart of {@link jcgp.backend.population.Input}. This is a - * subclass of {@code GUIGene} which represents a chromosome input. - * - * @author Eduardo Pedroni - */ -public class GUIInput extends GUIGene implements GUIConnection { +public class GUIInput extends GUIGene { private Input input; - - /** - * Instantiate {@code GUIInput} given an {@code Input}. - * - * @param input the associated backend input. - */ - public GUIInput(final Input input) { + + public GUIInput(ChromosomePane parentRef, final Input input) { super(); - // store the input, associate itself with it + + this.parent = parentRef; this.input = input; - input.setGUIObject(this); - // inputs only have a single output socket + relocate(Constants.NODE_RADIUS, + (input.getIndex() * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS); + + updateText(); + Circle outputSocket = new Circle(Constants.NODE_RADIUS, 0, Constants.SOCKET_RADIUS, Paint.valueOf("white")); - outputSocket.setStroke(Paint.valueOf("black")); outputSocket.setId(String.valueOf(0)); - getChildren().add(outputSocket); + outputSocket.setStroke(Paint.valueOf("black")); + + getChildren().addAll(mainCircle, text, outputSocket); - // relocate to the right position, add mouse handlers - Position.place(this); - InputHandlers.addHandlers(this); - } + /* + * Mouse event handlers on whole gene + */ + addEventFilter(MouseDragEvent.MOUSE_DRAG_ENTERED, new EventHandler<MouseDragEvent>() { + @Override + public void handle(MouseDragEvent event) { + // the drag has entered this node, react appropriately + // this happens even if we are the source of the drag + ((GUIGene) event.getGestureSource()).setConnectionLine((GUIGene) event.getSource()); + Connection source = ((GUIGene) event.getGestureSource()).getChangingConnection(); + if (input == source) { + setState(GUIGeneState.NO_CHANGE_TARGET); + } else { + setState(GUIGeneState.VALID_TARGET); + } + } + }); - /** - * @return the {@code Input} instance associated with this object. - */ - public Input getInput() { - return input; + addEventFilter(MouseDragEvent.MOUSE_DRAG_EXITED, new EventHandler<MouseDragEvent>() { + @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 + parent.setTarget(false); + if (event.isPrimaryButtonDown()) { + if (getState() == GUIGeneState.NO_CHANGE_TARGET) { + setState(GUIGeneState.INDIRECT_HOVER); + } else { + setState(GUIGeneState.NEUTRAL); + ((GUIGene) event.getGestureSource()).setConnectionStates(GUIGeneState.INDIRECT_HOVER); + } + } + } + + }); + + addEventFilter(MouseDragEvent.MOUSE_DRAG_RELEASED, new EventHandler<MouseDragEvent>() { + @Override + public void handle(MouseDragEvent event) { + GUIGene source = ((GUIGene) event.getGestureSource()); + // set states to reflect the new situation + if (source.isLocked()) { + source.setState(GUIGeneState.HOVER); + source.setConnectionStates(GUIGeneState.HOVER); + } else { + source.setState(GUIGeneState.NEUTRAL); + source.setConnectionStates(GUIGeneState.NEUTRAL); + } + + // the user released the drag gesture on this node, react appropriately + if (source.isLocked()) { + // remove locks from the old connection, add the to the new + // note that the old connection may still have locks after this + parent.getGuiGene(source.getChangingConnection()).removeLocks(source.getLocks()); + source.setChangingConnection(input); + addLocks(source.getLocks()); + } else { + source.setChangingConnection(input); + } + + source.updateLines(); + setState(GUIGeneState.HOVER); + } + }); + + addEventFilter(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + // cursor has entered this node without dragging, or it is dragging and this is the source + if (getState() == GUIGeneState.NEUTRAL) { + setState(GUIGeneState.HOVER); + } + } + }); + + addEventFilter(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + // cursor has left this node without dragging, or it is dragging and this is the source + if (getState() == GUIGeneState.HOVER) { + setState(GUIGeneState.NEUTRAL); + setConnectionStates(GUIGeneState.NEUTRAL); + } + } + }); } + @Override + public void setState(GUIGeneState newState) { + super.setState(newState); + + switch (newState) { + case ACTIVE_HOVER: + if (locked > 0) { + setState(GUIGeneState.LOCKED_HOVER); + } else { + mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR)); + } + break; + case INVALID_TARGET: + mainCircle.setFill(Paint.valueOf(Constants.BAD_SELECTION_COLOUR)); + break; + case LOCKED_HOVER: + mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR)); + break; + case HOVER: + mainCircle.setFill(Paint.valueOf(Constants.MEDIUM_HIGHLIGHT_COLOUR)); + break; + case INDIRECT_HOVER: + mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR)); + break; + case NEUTRAL: + if (locked > 0) { + setState(GUIGeneState.HOVER); + } else { + mainCircle.setFill(Paint.valueOf(Constants.NEUTRAL_COLOUR)); + } + break; + case NO_CHANGE_TARGET: + parent.setTarget(true); + mainCircle.setFill(Paint.valueOf(Constants.NEUTRAL_SELECTION_COLOUR)); + break; + case SOURCE: + mainCircle.setFill(Paint.valueOf(Constants.MEDIUM_HIGHLIGHT_COLOUR)); + break; + case VALID_TARGET: + parent.setTarget(true); + mainCircle.setFill(Paint.valueOf(Constants.GOOD_SELECTION_COLOUR)); + break; + default: + break; + } + + } + /** - * Associates this instance with a new input. + * Set all connections to a given state. * - * @param input the new input. + * @param newState the state to set connections to. */ - void setInput(Input input) { - this.input = input; + @Override + public void setConnectionStates(GUIGeneState newState) { + // nothing + } + + @Override + public void resetState() { + setState(GUIGeneState.NEUTRAL); } @Override - public void setStateRecursively(GUIGeneState state) { - setState(state); + protected void setLocked(boolean value) { + locked += value ? 1 : -1; + setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); } @Override - protected void setLinesVisible(boolean value) {} + public void setChangingConnection(Connection newConnection) { + // do nothing + } + + @Override + public Connection getChangingConnection() { + return null; + } @Override - public void setLockRecursively(boolean value) { - setLock(value); + public void addLocks(int value) { + locked += value; + setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); } + + @Override + public void updateLines() { + // nothing + } + + @Override + public void removeLocks(int value) { + locked -= value; + setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.NEUTRAL); + } + + @Override + public void setConnectionLine(GUIGene gene) { + // nothing + } + + public void setValue(Object newValue) { + input.setValue(newValue); + } + + @Override + public void updateText() { + if (parent.isEvaluating()) { + text.setText("I: " + input.getIndex() + "\n" + input.getValue().toString()); + } else { + text.setText("I: " + input.getIndex()); + } + } } |