package com.horstmann.violet.workspace.editorpart.behavior; import java.awt.Color; import java.awt.Graphics2D; import java.awt.event.MouseEvent; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.Iterator; import com.horstmann.violet.framework.util.KeyModifierUtil; import com.horstmann.violet.product.diagram.abstracts.IGraph; import com.horstmann.violet.product.diagram.abstracts.IGridSticker; import com.horstmann.violet.product.diagram.abstracts.edge.IEdge; import com.horstmann.violet.product.diagram.abstracts.node.INode; import com.horstmann.violet.workspace.editorpart.IEditorPart; import com.horstmann.violet.workspace.editorpart.IEditorPartSelectionHandler; import com.horstmann.violet.workspace.sidebar.graphtools.GraphTool; import com.horstmann.violet.workspace.sidebar.graphtools.IGraphToolsBar; public class SelectByLassoBehavior extends AbstractEditorPartBehavior { public SelectByLassoBehavior(IEditorPart editorPart, IGraphToolsBar graphToolsBar) { this.editorPart = editorPart; this.graph = editorPart.getGraph(); this.selectionHandler = editorPart.getSelectionHandler(); this.graphToolsBar = graphToolsBar; } @Override public void onMousePressed(MouseEvent event) { if (event.getClickCount() > 1) { return; } if (event.getButton() != MouseEvent.BUTTON1) { return; } if (!GraphTool.SELECTION_TOOL.equals(this.graphToolsBar.getSelectedTool())) { return; } double zoom = editorPart.getZoomFactor(); final Point2D mousePoint = new Point2D.Double(event.getX() / zoom, event.getY() / zoom); if (!isMouseOnNodeOrEdge(mousePoint)) { resetSelectedElements(); mouseDownPoint = mousePoint; lastMousePoint = mousePoint; } } @Override public void onMouseDragged(MouseEvent event) { if (mouseDownPoint == null) { return; } if (KeyModifierUtil.isCtrl(event)) { return; } double zoom = editorPart.getZoomFactor(); Point2D mousePoint = new Point2D.Double(event.getX() / zoom, event.getY() / zoom); IGridSticker gridSticker = graph.getGridSticker(); Point2D snappedMousePoint = gridSticker.snap(mousePoint); if (snappedMousePoint.equals(lastMousePoint)) { return; } double x1 = mouseDownPoint.getX(); double y1 = mouseDownPoint.getY(); double x2 = mousePoint.getX(); double y2 = mousePoint.getY(); Rectangle2D.Double lasso = new Rectangle2D.Double(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2)); Iterator<INode> iterOnNodes = graph.getAllNodes().iterator(); while (iterOnNodes.hasNext()) { INode n = (INode) iterOnNodes.next(); Rectangle2D bounds = n.getBounds(); if (!lasso.contains(bounds)) { selectionHandler.removeElementFromSelection(n); } else if (lasso.contains(bounds)) { selectionHandler.addSelectedElement(n); } } Iterator<IEdge> iterOnEdges = graph.getAllEdges().iterator(); while (iterOnEdges.hasNext()) { IEdge e = (IEdge) iterOnEdges.next(); Rectangle2D bounds = e.getBounds(); if (!lasso.contains(bounds)) { selectionHandler.removeElementFromSelection(e); } else if (lasso.contains(bounds)) { selectionHandler.addSelectedElement(e); } } if (!snappedMousePoint.equals(lastMousePoint)) { this.editorPart.getSwingComponent().invalidate(); this.editorPart.getSwingComponent().repaint(); } this.lastMousePoint = snappedMousePoint; } @Override public void onMouseReleased(MouseEvent event) { mouseDownPoint = null; lastMousePoint = null; this.editorPart.getSwingComponent().invalidate(); this.editorPart.getSwingComponent().repaint(); } private boolean isMouseOnNodeOrEdge(Point2D mouseLocation) { INode node = this.graph.findNode(mouseLocation); IEdge edge = this.graph.findEdge(mouseLocation); if (node == null && edge == null) { return false; } return true; } private void resetSelectedElements() { this.selectionHandler.clearSelection(); } @Override public void onPaint(Graphics2D g2) { if (mouseDownPoint == null || lastMousePoint == null) { return; } Color oldColor = g2.getColor(); g2.setColor(PURPLE); double x1 = mouseDownPoint.getX(); double y1 = mouseDownPoint.getY(); double x2 = lastMousePoint.getX(); double y2 = lastMousePoint.getY(); Rectangle2D.Double lasso = new Rectangle2D.Double(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2)); g2.draw(lasso); g2.setColor(oldColor); } private static final Color PURPLE = new Color(0.7f, 0.4f, 0.7f); private Point2D mouseDownPoint = null; private Point2D lastMousePoint = null; private IGraph graph; private IEditorPartSelectionHandler selectionHandler; private IEditorPart editorPart; private IGraphToolsBar graphToolsBar; }