-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g2d.diagram.handler.impl;\r
-\r
-import java.awt.Shape;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.NoninvertibleTransformException;\r
-import java.awt.geom.Rectangle2D;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.List;\r
-\r
-import org.simantics.g2d.diagram.DiagramHints;\r
-import org.simantics.g2d.diagram.IDiagram;\r
-import org.simantics.g2d.diagram.handler.PickContext;\r
-import org.simantics.g2d.diagram.handler.PickRequest;\r
-import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy;\r
-import org.simantics.g2d.element.ElementClass;\r
-import org.simantics.g2d.element.ElementUtils;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.g2d.element.handler.ElementLayers;\r
-import org.simantics.g2d.element.handler.InternalSize;\r
-import org.simantics.g2d.element.handler.Outline;\r
-import org.simantics.g2d.element.handler.Pick;\r
-import org.simantics.g2d.element.handler.Pick2;\r
-import org.simantics.g2d.element.handler.Transform;\r
-import org.simantics.g2d.layers.ILayers;\r
-import org.simantics.g2d.utils.GeometryUtils;\r
-\r
-/**\r
- * @author Toni Kalajainen\r
- */\r
-public class PickContextImpl implements PickContext {\r
-\r
- public static final PickContextImpl INSTANCE = new PickContextImpl(); \r
-\r
- @Override\r
- public void pick(\r
- IDiagram diagram, \r
- PickRequest request, \r
- Collection<IElement> finalResult) \r
- {\r
- assert(diagram!=null);\r
- assert(request!=null);\r
- assert(finalResult!=null);\r
-\r
- ILayers layers = diagram.getHint(DiagramHints.KEY_LAYERS);\r
-\r
- Collection<IElement> result = finalResult;\r
- if (request.pickSorter != null) {\r
- // Need a temporary List<IElement> for PickSorter\r
- result = new ArrayList<IElement>();\r
- }\r
- Rectangle2D elementBounds = new Rectangle2D.Double();\r
- nextElement:\r
- for (IElement e : diagram.getSnapshot())\r
- {\r
- // Ignore hidden elements.\r
- if (ElementUtils.isHidden(e))\r
- continue;\r
-\r
- ElementClass ec = e.getElementClass();\r
- \r
- if(layers != null && !layers.getIgnoreFocusSettings()) {\r
- ElementLayers el = ec.getAtMostOneItemOfClass(ElementLayers.class);\r
- if(el != null) {\r
- if(!el.isFocusable(e, layers)) continue;\r
- }\r
- }\r
- \r
- if (request.pickFilter!=null && !request.pickFilter.accept(e)) continue;\r
- \r
- Transform t = e.getElementClass().getSingleItem(Transform.class);\r
- AffineTransform canvasToElement = t.getTransform(e);\r
- if (canvasToElement==null) continue;\r
- double det = canvasToElement.getDeterminant();\r
- if (det == 0) {\r
- // Singular transform, just reset the rotation/scaling part to\r
- // allow picking to proceed.\r
- // TODO: this may modify the internal transform value of an element which is not intended\r
- canvasToElement.setToTranslation(\r
- canvasToElement.getTranslateX(),\r
- canvasToElement.getTranslateY());\r
- }\r
-\r
- // Get bounds, ignore elements that have no bounds\r
- InternalSize b = e.getElementClass().getAtMostOneItemOfClass(InternalSize.class);\r
- if (b==null) continue;\r
- elementBounds.setFrame(Double.NaN, Double.NaN, Double.NaN, Double.NaN);\r
- b.getBounds(e, elementBounds);\r
- if (Double.isNaN(elementBounds.getWidth()) || Double.isNaN(elementBounds.getHeight()))\r
- continue;\r
-\r
- Shape elementBoundsOnCanvas = GeometryUtils.transformShape(elementBounds, canvasToElement);\r
- if (elementBoundsOnCanvas instanceof Rectangle2D)\r
- elementBoundsOnCanvas = elementBoundsOnCanvas.getBounds2D();\r
- elementBoundsOnCanvas = elementBoundsOnCanvas.getBounds2D();\r
- org.simantics.scenegraph.utils.GeometryUtils.expandRectangle((Rectangle2D)elementBoundsOnCanvas, 1e-3, 1e-3, 1e-3, 1e-3);\r
- \r
- // Pick with pick handler(s)\r
- List<Pick> pickHandlers = e.getElementClass().getItemsByClass(Pick.class);\r
- if (!pickHandlers.isEmpty())\r
- {\r
- // Rough filtering with bounds\r
- if (!GeometryUtils.intersects(request.pickArea, elementBoundsOnCanvas)) {\r
-// System.out.println("Element bounds discards " + e.getElementClass());\r
- continue;\r
- }\r
- \r
- // Convert pick shape to element coordinates\r
-// AffineTransform elementToCanvas;\r
-// try {\r
-// elementToCanvas = canvasToElement.createInverse();\r
-// } catch (NoninvertibleTransformException e1) {\r
-// throw new RuntimeException(e1);\r
-// }\r
-// Shape pickShapeInElementCoords = GeometryUtils.transformShape(request.pickArea, elementToCanvas);\r
- for (Pick p : pickHandlers)\r
- {\r
- if (p instanceof Pick2) {\r
- Pick2 p2 = (Pick2) p;\r
- //if (p2.pick(e, pickShapeInElementCoords, request.pickPolicy, result) > 0)\r
- if (p2.pick(e, request.pickArea, request.pickPolicy, result) > 0)\r
- continue nextElement;\r
- } else {\r
- //if (p.pickTest(e, pickShapeInElementCoords, request.pickPolicy)) {\r
- if (p.pickTest(e, request.pickArea, request.pickPolicy)) {\r
- result.add(e);\r
- continue nextElement;\r
- }\r
- }\r
- }\r
- continue nextElement;\r
- }\r
- \r
- // Pick with shape handler(s) \r
- List<Outline> shapeHandlers = e.getElementClass().getItemsByClass(Outline.class);\r
- if (!shapeHandlers.isEmpty())\r
- {\r
- // Rough filtering with bounds\r
- if (!GeometryUtils.intersects(request.pickArea, elementBoundsOnCanvas)) continue;\r
- \r
- // Convert pick shape to element coordinates\r
- AffineTransform elementToCanvas;\r
- try {\r
- elementToCanvas = canvasToElement.createInverse();\r
- } catch (NoninvertibleTransformException e1) {\r
- throw new RuntimeException(e1);\r
- }\r
- Shape pickShapeInElementCoords = GeometryUtils.transformShape(request.pickArea, elementToCanvas);\r
- \r
- // Intersection with one shape is enough\r
- if (request.pickPolicy == PickPolicy.PICK_INTERSECTING_OBJECTS)\r
- {\r
- for (Outline es : shapeHandlers)\r
- {\r
- Shape elementShape = es.getElementShape(e); \r
- if (elementShape==null) continue nextElement;\r
- if (GeometryUtils.intersects(pickShapeInElementCoords, elementShape))\r
- {\r
- result.add(e);\r
- continue nextElement;\r
- }\r
- }\r
- continue nextElement;\r
- }\r
- \r
- // Contains of all shapes is required \r
- if (request.pickPolicy == PickPolicy.PICK_CONTAINED_OBJECTS)\r
- {\r
- for (Outline es : shapeHandlers)\r
- {\r
- Shape elementShape = es.getElementShape(e);\r
- if (!GeometryUtils.contains(pickShapeInElementCoords, elementShape))\r
- continue nextElement;\r
- }\r
- result.add(e); \r
- continue nextElement;\r
- }\r
- continue nextElement;\r
- } \r
- \r
- // Pick by rectangle\r
- if (request.pickPolicy == PickPolicy.PICK_INTERSECTING_OBJECTS)\r
- {\r
- if (GeometryUtils.intersects(request.pickArea, elementBoundsOnCanvas)) \r
- result.add(e);\r
- }\r
- \r
- else\r
- \r
- if (request.pickPolicy == PickPolicy.PICK_CONTAINED_OBJECTS)\r
- {\r
- if (GeometryUtils.contains(request.pickArea, elementBoundsOnCanvas)) \r
- result.add(e);\r
- }\r
- \r
- }\r
-\r
- if (request.pickSorter != null) {\r
- request.pickSorter.sort((List<IElement>) result);\r
- finalResult.addAll(result);\r
- }\r
- }\r
-\r
-}\r
+/*******************************************************************************
+ * 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.impl;
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.simantics.g2d.diagram.DiagramHints;
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.diagram.handler.PickContext;
+import org.simantics.g2d.diagram.handler.PickRequest;
+import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy;
+import org.simantics.g2d.element.ElementClass;
+import org.simantics.g2d.element.ElementUtils;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.element.handler.ElementLayers;
+import org.simantics.g2d.element.handler.InternalSize;
+import org.simantics.g2d.element.handler.Outline;
+import org.simantics.g2d.element.handler.Pick;
+import org.simantics.g2d.element.handler.Pick2;
+import org.simantics.g2d.element.handler.Transform;
+import org.simantics.g2d.layers.ILayers;
+import org.simantics.g2d.utils.GeometryUtils;
+
+/**
+ * @author Toni Kalajainen
+ */
+public class PickContextImpl implements PickContext {
+
+ public static final PickContextImpl INSTANCE = new PickContextImpl();
+
+ @Override
+ public void pick(
+ IDiagram diagram,
+ PickRequest request,
+ Collection<IElement> finalResult)
+ {
+ assert(diagram!=null);
+ assert(request!=null);
+ assert(finalResult!=null);
+
+ ILayers layers = diagram.getHint(DiagramHints.KEY_LAYERS);
+
+ Collection<IElement> result = finalResult;
+ if (request.pickSorter != null) {
+ // Need a temporary List<IElement> for PickSorter
+ result = new ArrayList<IElement>();
+ }
+ Rectangle2D elementBounds = new Rectangle2D.Double();
+ nextElement:
+ for (IElement e : diagram.getSnapshot())
+ {
+ // Ignore hidden elements.
+ if (ElementUtils.isHidden(e))
+ continue;
+
+ ElementClass ec = e.getElementClass();
+
+ if(layers != null && !layers.getIgnoreFocusSettings()) {
+ ElementLayers el = ec.getAtMostOneItemOfClass(ElementLayers.class);
+ if(el != null) {
+ if(!el.isFocusable(e, layers)) continue;
+ }
+ }
+
+ if (request.pickFilter!=null && !request.pickFilter.accept(e)) continue;
+
+ Transform t = e.getElementClass().getSingleItem(Transform.class);
+ AffineTransform canvasToElement = t.getTransform(e);
+ if (canvasToElement==null) continue;
+ double det = canvasToElement.getDeterminant();
+ if (det == 0) {
+ // Singular transform, just reset the rotation/scaling part to
+ // allow picking to proceed.
+ // TODO: this may modify the internal transform value of an element which is not intended
+ canvasToElement.setToTranslation(
+ canvasToElement.getTranslateX(),
+ canvasToElement.getTranslateY());
+ }
+
+ // Get bounds, ignore elements that have no bounds
+ InternalSize b = e.getElementClass().getAtMostOneItemOfClass(InternalSize.class);
+ if (b==null) continue;
+ elementBounds.setFrame(Double.NaN, Double.NaN, Double.NaN, Double.NaN);
+ b.getBounds(e, elementBounds);
+ if (Double.isNaN(elementBounds.getWidth()) || Double.isNaN(elementBounds.getHeight()))
+ continue;
+
+ Shape elementBoundsOnCanvas = GeometryUtils.transformShape(elementBounds, canvasToElement);
+ if (elementBoundsOnCanvas instanceof Rectangle2D)
+ elementBoundsOnCanvas = elementBoundsOnCanvas.getBounds2D();
+ elementBoundsOnCanvas = elementBoundsOnCanvas.getBounds2D();
+ org.simantics.scenegraph.utils.GeometryUtils.expandRectangle((Rectangle2D)elementBoundsOnCanvas, 1e-3, 1e-3, 1e-3, 1e-3);
+
+ // Pick with pick handler(s)
+ List<Pick> pickHandlers = e.getElementClass().getItemsByClass(Pick.class);
+ if (!pickHandlers.isEmpty())
+ {
+ // Rough filtering with bounds
+ if (!GeometryUtils.intersects(request.pickArea, elementBoundsOnCanvas)) {
+// System.out.println("Element bounds discards " + e.getElementClass());
+ continue;
+ }
+
+ // Convert pick shape to element coordinates
+// AffineTransform elementToCanvas;
+// try {
+// elementToCanvas = canvasToElement.createInverse();
+// } catch (NoninvertibleTransformException e1) {
+// throw new RuntimeException(e1);
+// }
+// Shape pickShapeInElementCoords = GeometryUtils.transformShape(request.pickArea, elementToCanvas);
+ for (Pick p : pickHandlers)
+ {
+ if (p instanceof Pick2) {
+ Pick2 p2 = (Pick2) p;
+ //if (p2.pick(e, pickShapeInElementCoords, request.pickPolicy, result) > 0)
+ if (p2.pick(e, request.pickArea, request.pickPolicy, result) > 0)
+ continue nextElement;
+ } else {
+ //if (p.pickTest(e, pickShapeInElementCoords, request.pickPolicy)) {
+ if (p.pickTest(e, request.pickArea, request.pickPolicy)) {
+ result.add(e);
+ continue nextElement;
+ }
+ }
+ }
+ continue nextElement;
+ }
+
+ // Pick with shape handler(s)
+ List<Outline> shapeHandlers = e.getElementClass().getItemsByClass(Outline.class);
+ if (!shapeHandlers.isEmpty())
+ {
+ // Rough filtering with bounds
+ if (!GeometryUtils.intersects(request.pickArea, elementBoundsOnCanvas)) continue;
+
+ // Convert pick shape to element coordinates
+ AffineTransform elementToCanvas;
+ try {
+ elementToCanvas = canvasToElement.createInverse();
+ } catch (NoninvertibleTransformException e1) {
+ throw new RuntimeException(e1);
+ }
+ Shape pickShapeInElementCoords = GeometryUtils.transformShape(request.pickArea, elementToCanvas);
+
+ // Intersection with one shape is enough
+ if (request.pickPolicy == PickPolicy.PICK_INTERSECTING_OBJECTS)
+ {
+ for (Outline es : shapeHandlers)
+ {
+ Shape elementShape = es.getElementShape(e);
+ if (elementShape==null) continue nextElement;
+ if (GeometryUtils.intersects(pickShapeInElementCoords, elementShape))
+ {
+ result.add(e);
+ continue nextElement;
+ }
+ }
+ continue nextElement;
+ }
+
+ // Contains of all shapes is required
+ if (request.pickPolicy == PickPolicy.PICK_CONTAINED_OBJECTS)
+ {
+ for (Outline es : shapeHandlers)
+ {
+ Shape elementShape = es.getElementShape(e);
+ if (!GeometryUtils.contains(pickShapeInElementCoords, elementShape))
+ continue nextElement;
+ }
+ result.add(e);
+ continue nextElement;
+ }
+ continue nextElement;
+ }
+
+ // Pick by rectangle
+ if (request.pickPolicy == PickPolicy.PICK_INTERSECTING_OBJECTS)
+ {
+ if (GeometryUtils.intersects(request.pickArea, elementBoundsOnCanvas))
+ result.add(e);
+ }
+
+ else
+
+ if (request.pickPolicy == PickPolicy.PICK_CONTAINED_OBJECTS)
+ {
+ if (GeometryUtils.contains(request.pickArea, elementBoundsOnCanvas))
+ result.add(e);
+ }
+
+ }
+
+ if (request.pickSorter != null) {
+ request.pickSorter.sort((List<IElement>) result);
+ finalResult.addAll(result);
+ }
+ }
+
+}