X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Fdiagram%2Fhandler%2Fimpl%2FPickContextImpl.java;fp=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Fdiagram%2Fhandler%2Fimpl%2FPickContextImpl.java;h=1f6a76903e9247e1c7d8aa3b21da14cc3d833616;hp=0fca5dcfc4a004fd283663224e0fd40e7588d2c4;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/impl/PickContextImpl.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/impl/PickContextImpl.java index 0fca5dcfc..1f6a76903 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/impl/PickContextImpl.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/impl/PickContextImpl.java @@ -1,215 +1,215 @@ -/******************************************************************************* - * 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 finalResult) - { - assert(diagram!=null); - assert(request!=null); - assert(finalResult!=null); - - ILayers layers = diagram.getHint(DiagramHints.KEY_LAYERS); - - Collection result = finalResult; - if (request.pickSorter != null) { - // Need a temporary List for PickSorter - result = new ArrayList(); - } - 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 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 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) result); - finalResult.addAll(result); - } - } - -} +/******************************************************************************* + * 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 finalResult) + { + assert(diagram!=null); + assert(request!=null); + assert(finalResult!=null); + + ILayers layers = diagram.getHint(DiagramHints.KEY_LAYERS); + + Collection result = finalResult; + if (request.pickSorter != null) { + // Need a temporary List for PickSorter + result = new ArrayList(); + } + 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 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 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) result); + finalResult.addAll(result); + } + } + +}