package bluej.graph;

import bluej.Config;
import bluej.pkgmgr.Package;
import bluej.pkgmgr.PackageEditor;
import bluej.pkgmgr.target.Target;
import bluej.utility.Utility;
import bluej.utility.javafx.FXPlatformConsumer;

import java.util.Collection;
import java.util.List;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;

import threadchecker.OnThread;
import threadchecker.Tag;


| This class controls the selection (the set of selected elements in the graph). | To do this, it maintains a selection set, a marquee (a graphical selection rectangle) | and a rubber band (for drawing new edges). Both the marquee and the rubber band can | be inactive. | @OnThread(Tag.FXPlatform) public class SelectionController { private final PackageEditor graphEditor; private final Package graph; private final Marquee marquee; private final SelectionSet selection; private boolean moving = false; private boolean resizing = false; private TraverseStrategy traverseStragegiImpl = new TraverseStrategyImpl();
| Create the controller for a given graph editor. | @param graphEditor | @param graph | public SelectionController(PackageEditor graphEditor) { this.graphEditor = graphEditor; this.graph = graphEditor.getPackage(); selection = new SelectionSet(Utility.filterList(graph.getVertices(), Target::isSelected)); marquee = new Marquee(graph, selection); }
| A mouse-pressed event. Analyse what we should do with it. | public void mousePressed(javafx.scene.input.MouseEvent evt) { int clickX = (int)evt.getX(); int clickY = (int)evt.getY(); if (!isMultiselectionKeyDown(evt)) { selection.clear(); } if (isButtonOne(evt)) { marquee.start(clickX, clickY); } }
| The mouse was released. | public void mouseReleased(MouseEvent evt) { marquee.stop(); graphEditor.repaint(); if (moving || resizing) { endMove(); graphEditor.repaint(); } for (Target t : graph.getVertices()) { if (t.isFocused() && !t.isSelected()) { selectOnly(t); break; } } }
| A mouse-clicked event. This is only interesting if it was a double | click. If so, inform every element in the current selection. | public void mouseClicked(MouseEvent evt) { if (isButtonOne(evt)) { if (evt.getClickCount() > 1) { selection.getSelected().forEach(target -> { if (evt.getTarget().equals(target)) { selection.doubleClick(false); return; } }); } } }
| The mouse was dragged - either draw a marquee or move some classes. | public void mouseDragged(MouseEvent evt) { if (isButtonOne(evt)) { if (marquee.isActive()) { marquee.move((int)evt.getX(), (int)evt.getY()); graphEditor.repaint(); } else { if (! selection.isEmpty()) {
| | |int deltaX = snapToGrid((int)evt.getX() - dragStartX); | |int deltaY = snapToGrid((int)evt.getY() - dragStartY); | |if(resizing) {}selection.resize(deltaX, deltaY); | |} | |else if (moving) {}selection.move(deltaX, deltaY); | |} } graphEditor.repaint(); } } } | Move the current selection to another selected class, depending on | current selection and the key pressed. | public void navigate(KeyEvent evt) { Target currentTarget = findSingleVertex(); currentTarget = traverseStragegiImpl.findNextVertex(graph, currentTarget, evt.getCode()); selection.selectOnly(currentTarget); currentTarget.requestFocus(); }
| End a move or resize gesture. | private void endMove() { selection.moveStopped(); moving = false; resizing = false; }
| Return the marquee of this conroller. | public Marquee getMarquee() { return marquee; } private Target findSingleVertex() { Target vertex = selection.getAnyVertex(); if (vertex == null) { vertex = graph.getVertices().get(0); } return vertex; }
| Clear the current selection. | public void clearSelection() { selection.clear(); }
| Select all graph vertices. | public void selectAll() { for (Target t : graph.getVertices()) selection.add(t); }
| Clear the current selection. | public void removeFromSelection(Target element) { selection.remove(element); }
| Add to the current selection | @param element | public void addToSelection(Target element) { selection.add(element); }
| Check whether this mouse event was from button one. | (Ctrl-button one on MacOS does not count - that posts the menu | so we consider that button two.) | private boolean isButtonOne(MouseEvent evt) { return !evt.isPopupTrigger() && evt.getButton() == MouseButton.PRIMARY; }
| Check whether the key used for multiple selections is down. | private boolean isMultiselectionKeyDown(MouseEvent evt) { if (Config.isMacOS()) { return evt.isShiftDown() || evt.isMetaDown(); } else { return evt.isShiftDown() || evt.isControlDown(); } }
| Selects the one given target, and no others. | public void selectOnly(Target target) { selection.selectOnly(target); }
| Gets an unordered list of all currently selected targets. | public List getSelection() { return selection.getSelected(); }
| The selection listener will be run every time the selection has changed. | @param selectionListener | public void addSelectionListener(FXPlatformConsumer<Collection<Target>> selectionListener) { selection.addListener(selectionListener); } }
top, use, map, class SelectionController

.   SelectionController
.   mousePressed
.   mouseReleased
.   mouseClicked
.   mouseDragged
.   navigate
.   endMove
.   getMarquee
.   findSingleVertex
.   clearSelection
.   selectAll
.   removeFromSelection
.   addToSelection
.   isButtonOne
.   isMultiselectionKeyDown
.   selectOnly
.   getSelection
.   addSelectionListener




275 neLoCode + 36 LoComm