1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.g2d.diagram.handler;
14 import java.awt.Shape;
15 import java.awt.geom.AffineTransform;
16 import java.awt.geom.Area;
17 import java.awt.geom.Point2D;
18 import java.awt.geom.Rectangle2D;
19 import java.util.Collections;
20 import java.util.Comparator;
21 import java.util.List;
23 import org.simantics.g2d.canvas.ICanvasContext;
24 import org.simantics.g2d.connection.handler.ConnectionHandler;
25 import org.simantics.g2d.element.IElement;
26 import org.simantics.g2d.element.handler.BendsHandler;
27 import org.simantics.g2d.element.handler.TerminalTopology;
28 import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline;
29 import org.simantics.g2d.elementclass.BranchPoint;
30 import org.simantics.g2d.elementclass.MonitorHandler;
31 import org.simantics.g2d.utils.GeometryUtils;
32 import org.simantics.scenegraph.utils.TransformedRectangle;
36 * @See {@link GeometryUtils} for intersect and contains tests
37 * @See {@link TransformedRectangle}
38 * @See {@link Area} intersects operations for complex shapes
39 * @author Toni Kalajainen
41 public class PickRequest {
43 public static enum PickPolicy {
44 PICK_INTERSECTING_OBJECTS,
45 PICK_CONTAINED_OBJECTS
48 public Shape pickArea;
49 public PickPolicy pickPolicy = PickPolicy.PICK_INTERSECTING_OBJECTS;
50 /** Pick filter (null == everything is accepted) */
51 public PickFilter pickFilter = null;
52 public PickSorter pickSorter = null;
55 * Used to optimize picking if provided via R-tree traversal to find
56 * intersecting elements, not everything.
58 public ICanvasContext pickContext;
60 public PickRequest(double x, double y)
62 pickArea = new Rectangle2D.Double(x, y, 1, 1);
64 public PickRequest(Point2D p)
66 pickArea = new Rectangle2D.Double(p.getX(), p.getY(), 0.0001, 0.0001);
68 public PickRequest(Shape shape)
72 public PickRequest(Shape shape, AffineTransform transform)
74 pickArea = GeometryUtils.transformShape(shape, transform);
77 public PickRequest context(ICanvasContext ctx) {
78 this.pickContext = ctx;
82 public static interface PickFilter {
83 boolean accept(IElement e);
85 public static final PickFilter FILTER_ALL = new PickFilter() {
87 public boolean accept(IElement e) {
92 public static final PickFilter FILTER_CONNECTIONS = new PickFilter() {
94 public boolean accept(IElement e) {
95 return e.getElementClass().containsClass(ConnectionHandler.class);
98 public String toString() { return "FILTER_CONNECTIONS"; }
101 public static final PickFilter FILTER_CONNECTION_EDGES = new PickFilter() {
103 public boolean accept(IElement e) {
104 return e.getElementClass().containsClass(BendsHandler.class) || e.getElementClass().containsClass(ConnectionSelectionOutline.class);
107 public String toString() { return "FILTER_CONNECTION_EDGES"; }
110 public static final PickFilter FILTER_BRANCH_POINT = new PickFilter() {
112 public boolean accept(IElement e) {
113 return e.getElementClass().containsClass(BranchPoint.class);
116 public String toString() { return "FILTER_BRANCH_POINTS"; }
118 // Anything that has terminals
119 public static final PickFilter FILTER_NODES = new PickFilter() {
121 public boolean accept(IElement e) {
122 return e.getElementClass().containsClass(TerminalTopology.class);
125 public String toString() { return "FILTER_NODES"; }
127 public static final PickFilter FILTER_MONITORS = new PickFilter() {
129 public boolean accept(IElement e) {
130 return e.getElementClass().containsClass(MonitorHandler.class);
133 public String toString() { return "FILTER_MONITORS"; }
137 public static interface PickSorter {
138 void sort(List<IElement> elements);
141 public static final PickSorter CONNECTIONS_LAST = new PickSorter() {
143 public void sort(List<IElement> elements) {
144 Collections.sort(elements, new Comparator<IElement>() {
146 public int compare(IElement e1, IElement e2) {
147 boolean isConn1 = PickFilter.FILTER_CONNECTION_EDGES.accept(e1);
148 boolean isConn2 = PickFilter.FILTER_CONNECTION_EDGES.accept(e2);
149 if (!isConn1 && isConn2)
151 if (isConn1 && !isConn2)
158 public static final PickSorter CONNECTIONS_FIRST = new PickSorter() {
160 public void sort(List<IElement> elements) {
161 Collections.sort(elements, new Comparator<IElement>() {
163 public int compare(IElement e1, IElement e2) {
164 boolean isConn1 = PickFilter.FILTER_CONNECTION_EDGES.accept(e1);
165 boolean isConn2 = PickFilter.FILTER_CONNECTION_EDGES.accept(e2);
166 if (!isConn1 && isConn2)
168 if (isConn1 && !isConn2)