/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.g2d.diagram.handler; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.simantics.g2d.connection.handler.ConnectionHandler; import org.simantics.g2d.element.IElement; import org.simantics.g2d.element.handler.BendsHandler; import org.simantics.g2d.element.handler.TerminalTopology; import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline; import org.simantics.g2d.elementclass.BranchPoint; import org.simantics.g2d.elementclass.MonitorHandler; import org.simantics.g2d.utils.GeometryUtils; import org.simantics.scenegraph.utils.TransformedRectangle; /** * * @See {@link GeometryUtils} for intersect and contains tests * @See {@link TransformedRectangle} * @See {@link Area} intersects operations for complex shapes * @author Toni Kalajainen */ public class PickRequest { public static enum PickPolicy { PICK_INTERSECTING_OBJECTS, PICK_CONTAINED_OBJECTS } public Shape pickArea; public PickPolicy pickPolicy = PickPolicy.PICK_INTERSECTING_OBJECTS; /** Pick filter (null == everything is accepted) */ public PickFilter pickFilter = null; public PickSorter pickSorter = null; public PickRequest(double x, double y) { pickArea = new Rectangle2D.Double(x, y, 1, 1); } public PickRequest(Point2D p) { pickArea = new Rectangle2D.Double(p.getX(), p.getY(), 0.0001, 0.0001); } public PickRequest(Shape shape) { pickArea = shape; } public PickRequest(Shape shape, AffineTransform transform) { pickArea = GeometryUtils.transformShape(shape, transform); } public static interface PickFilter { boolean accept(IElement e); public static final PickFilter FILTER_ALL = new PickFilter() { @Override public boolean accept(IElement e) { return true; } }; // Connections public static final PickFilter FILTER_CONNECTIONS = new PickFilter() { @Override public boolean accept(IElement e) { return e.getElementClass().containsClass(ConnectionHandler.class); } @Override public String toString() { return "FILTER_CONNECTIONS"; } }; // Connection edges public static final PickFilter FILTER_CONNECTION_EDGES = new PickFilter() { @Override public boolean accept(IElement e) { return e.getElementClass().containsClass(BendsHandler.class) || e.getElementClass().containsClass(ConnectionSelectionOutline.class); } @Override public String toString() { return "FILTER_CONNECTION_EDGES"; } }; // Connections public static final PickFilter FILTER_BRANCH_POINT = new PickFilter() { @Override public boolean accept(IElement e) { return e.getElementClass().containsClass(BranchPoint.class); } @Override public String toString() { return "FILTER_BRANCH_POINTS"; } }; // Anything that has terminals public static final PickFilter FILTER_NODES = new PickFilter() { @Override public boolean accept(IElement e) { return e.getElementClass().containsClass(TerminalTopology.class); } @Override public String toString() { return "FILTER_NODES"; } }; public static final PickFilter FILTER_MONITORS = new PickFilter() { @Override public boolean accept(IElement e) { return e.getElementClass().containsClass(MonitorHandler.class); } @Override public String toString() { return "FILTER_MONITORS"; } }; } public static interface PickSorter { void sort(List elements); // public static final PickSorter CONNECTIONS_LAST = new PickSorter() { @Override public void sort(List elements) { Collections.sort(elements, new Comparator() { @Override public int compare(IElement e1, IElement e2) { boolean isConn1 = PickFilter.FILTER_CONNECTION_EDGES.accept(e1); boolean isConn2 = PickFilter.FILTER_CONNECTION_EDGES.accept(e2); if (!isConn1 && isConn2) return -1; if (isConn1 && !isConn2) return 1; return 0; } }); } }; public static final PickSorter CONNECTIONS_FIRST = new PickSorter() { @Override public void sort(List elements) { Collections.sort(elements, new Comparator() { @Override public int compare(IElement e1, IElement e2) { boolean isConn1 = PickFilter.FILTER_CONNECTION_EDGES.accept(e1); boolean isConn2 = PickFilter.FILTER_CONNECTION_EDGES.accept(e2); if (!isConn1 && isConn2) return 1; if (isConn1 && !isConn2) return -1; return 0; } }); } }; } }