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%2Fparticipant%2FElementPainter.java;h=9134c1729ac161c7ec4d9bcb927880da9612b8dd;hp=1eb15f61c2132ece167643ee6af6638ef4cb6e9b;hb=f48fa9bd04b1802047c1eba99ad73eb4234a46c2;hpb=0ae2b770234dfc3cbb18bd38f324125cf0faca07 diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java index 1eb15f61c..9134c1729 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * Copyright (c) 2007, 2018 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 @@ -8,6 +8,7 @@ * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - GitLab issue #66 *******************************************************************************/ package org.simantics.g2d.diagram.participant; @@ -91,6 +92,7 @@ import org.simantics.scenegraph.g2d.nodes.SingleElementNode; import org.simantics.scenegraph.g2d.nodes.UnboundedNode; import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode; import org.simantics.scenegraph.utils.ColorUtil; +import org.simantics.scenegraph.utils.GeometryUtils; import org.simantics.scenegraph.utils.NodeUtil; import org.simantics.utils.datastructures.collections.CollectionUtils; import org.simantics.utils.datastructures.hints.HintListenerAdapter; @@ -135,11 +137,12 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos * ElementPainter. */ public static interface ISelectionProvider { - public void init(final IElement e, final G2DParentNode parentNode, final String nodeId, + public void init(int selectionId, final IElement e, final G2DParentNode parentNode, final String nodeId, final AffineTransform transform, final Rectangle2D bounds, final Color color); } private static final boolean DEBUG = false; + private static final boolean NODE_TO_ELEMENT_MAPPING = true; public static final int ELEMENT_PAINT_PRIORITY = 10; @@ -155,7 +158,7 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos SingleElementNode diagramParent; RTreeNode elementParent; - boolean paintSelectionFrames; + ElementPainterConfiguration cfg; /** * Internally reused to avert constant reallocation. @@ -171,7 +174,11 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos } public ElementPainter(boolean paintSelectionFrames) { - this.paintSelectionFrames = paintSelectionFrames; + this(new ElementPainterConfiguration().paintSelectionFrames(paintSelectionFrames)); + } + + public ElementPainter(ElementPainterConfiguration cfg) { + this.cfg = cfg; } @Override @@ -197,8 +204,9 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos return; if (oldValue != null) { + Map nodeToElementMap = oldValue.removeHint(DiagramHints.NODE_TO_ELEMENT_MAP); for (IElement e : oldValue.getElements()) { - removeElement(e); + removeElement(oldValue, e, nodeToElementMap); } oldValue.removeCompositionListener(this); @@ -216,8 +224,13 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos } if (newValue != null) { + diagram.removeHint(DiagramHints.NODE_TO_ELEMENT_MAP); + Map nodeElementMap = NODE_TO_ELEMENT_MAPPING ? new HashMap<>() : null; + if (nodeElementMap != null) + diagram.setHint(DiagramHints.NODE_TO_ELEMENT_MAP, nodeElementMap); + for (IElement e : newValue.getElements()) { - addElement(e, false); + addElement(newValue, e, false, nodeElementMap); } newValue.addCompositionListener(this); @@ -241,7 +254,8 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos public void initSG(G2DParentNode parent) { diagramParent = parent.addNode("elements_"+Node.IDCOUNTER, UnboundedNode.class); diagramParent.setZIndex(ELEMENT_PAINT_PRIORITY); - elementParent = diagramParent.addNode("spatialRoot", RTreeNode.class); + elementParent = diagramParent.addNode(SceneGraphConstants.SPATIAL_ROOT_NODE_NAME, RTreeNode.class); + elementParent.setLookupId(SceneGraphConstants.SPATIAL_ROOT_NODE_ID); elementParent.setZIndex(0); } @@ -498,10 +512,11 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos if (DEBUG) System.out.println("EP.onElementAdded(" + d + ", " + e + ")"); + Map nodeElementMap = diagram.getHint(DiagramHints.NODE_TO_ELEMENT_MAP); if (inDiagramTransaction()) { - addElement(e, false); + addElement(d, e, false, nodeElementMap); } else { - addElement(e, true); + addElement(d, e, true, nodeElementMap); } } @Override @@ -509,7 +524,7 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos if (DEBUG) System.out.println("EP.onElementRemoved(" + d + ", " + e + ")"); - removeElement(e); + removeElement(d, e, diagram.getHint(DiagramHints.NODE_TO_ELEMENT_MAP)); } @Override @@ -517,17 +532,19 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos if (DEBUG) System.out.println("EP.elementChildrenChanged: " + event); + Map nodeElementMap = diagram.getHint(DiagramHints.NODE_TO_ELEMENT_MAP); + for (IElement removed : event.removed) { - removeElement(removed); + removeElement(diagram, removed, nodeElementMap); } for (IElement added : event.added) { - addElement(added, false); + addElement(diagram, added, false, nodeElementMap); } } private final List childrenTemp = new ArrayList(); - public void addElement(IElement e, boolean synchronizeSceneGraphNow) { + public void addElement(IDiagram d, IElement e, boolean synchronizeSceneGraphNow, Map nodeElementMap) { if (DEBUG) System.out.println("EP.addElement(now=" + synchronizeSceneGraphNow + ", " + e + ")"); @@ -557,9 +574,13 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos ConnectionNode holder = e.getHint(sgKey); if (holder == null) { holder = parentNode.addNode(ElementUtils.generateNodeId(e), ConnectionNode.class); + holder.setKey(e.getHint(ElementHints.KEY_OBJECT)); + holder.setTypeClass(e.getHint(ElementHints.KEY_TYPE_CLASS)); holder.setTransferableProvider(new ElementTransferableProvider(getContext(), e)); e.setHint(sgKey, holder); holder.setZIndex(parentNode.getNodeCount() + 1); + if (nodeElementMap != null) + nodeElementMap.put(holder, e); } } else { @@ -567,9 +588,13 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos SingleElementNode holder = e.getHint(sgKey); if (holder == null) { holder = parentNode.addNode(ElementUtils.generateNodeId(e), SingleElementNode.class); + holder.setKey(e.getHint(ElementHints.KEY_OBJECT)); + holder.setTypeClass(e.getHint(ElementHints.KEY_TYPE_CLASS)); holder.setTransferableProvider(new ElementTransferableProvider(getContext(), e)); e.setHint(sgKey, holder); holder.setZIndex(parentNode.getNodeCount() + 1); + if (nodeElementMap != null) + nodeElementMap.put(holder, e); } } @@ -582,7 +607,7 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos children.getChildren(e, childrenTemp); //System.out.println("children: " + childrenTemp); for (IElement child : childrenTemp) { - addElement(child, false); + addElement(d, child, false, nodeElementMap); } childrenTemp.clear(); } @@ -593,7 +618,7 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos //setTreeDirty(); } - protected void removeElement(IElement e) { + protected void removeElement(IDiagram d, IElement e, Map nodeElementMap) { if (DEBUG) System.out.println("EP.removeElement(" + e + ")"); @@ -619,6 +644,8 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos Node n = e.removeHint(sgKey); if (n != null) { n.remove(); + if (nodeElementMap != null) + nodeElementMap.remove(n); } } @@ -805,7 +832,7 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos Object task = BEGIN("EP.updateSelections"); try { - if (!paintSelectionFrames) + if (!cfg.paintSelectionFrames) return; if (selection == null) return; @@ -911,7 +938,7 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos Object task = BEGIN("EP.updateSelection"); try { - if (!paintSelectionFrames) + if (!cfg.paintSelectionFrames) return; G2DParentNode elementNode = (G2DParentNode) el.getHint(ElementHints.KEY_SG_NODE); @@ -930,7 +957,7 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos continue; if (NodeUtil.needSelectionPaint(elementNode)) - paintSelectionFrame(elementNode, selectionNode, el, color); + paintSelectionFrame(selectionId, elementNode, selectionNode, el, color); nodesUpdated = true; } @@ -957,12 +984,14 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos Color color = getSelectionColor(selectionId); G2DParentNode selectionsNode = getSelectionsNode(selectionId); + Class selectionNodeClass = cfg.selectionNodeClass != null ? cfg.selectionNodeClass : G2DParentNode.class; + for (IElement e : selection) { Node elementNode = e.getHint(ElementHints.KEY_SG_NODE); // System.out.println("selectionNode: " + elementNode + " " + e); if (elementNode instanceof G2DParentNode) { G2DParentNode en = (G2DParentNode) elementNode; - G2DParentNode selectionNode = en.getOrCreateNode(NodeUtil.SELECTION_NODE_NAME, G2DParentNode.class); + G2DParentNode selectionNode = en.getOrCreateNode(NodeUtil.SELECTION_NODE_NAME, selectionNodeClass); selectionNode.setZIndex(SELECTION_PAINT_PRIORITY); if (selectionNodes != null) selectionNodes.add(selectionNode); @@ -976,7 +1005,7 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos createSelectionReference(selectionsNode, elementNode); if (NodeUtil.needSelectionPaint(elementNode)) - paintSelectionFrame(en, selectionNode, e, color); + paintSelectionFrame(selectionId, en, selectionNode, e, color); } else { if (elementNode != null) { @@ -1004,14 +1033,29 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos return result; } - public void paintSelectionFrame(G2DParentNode elementNode, G2DParentNode selectionNode, final IElement e, Color color) { + + /** + * We need to have separate class for SelectionNode, so that SCLSceneGraph can handle this properly. + * + */ + public static class SelectionShapeNode extends ShapeNode { + + private static final long serialVersionUID = -5393630944240940166L; + + } + + public void paintSelectionFrame(int selectionId, G2DParentNode elementNode, G2DParentNode selectionNode, final IElement e, Color color) { // The element node already has the correct transform. AffineTransform selectionTransform = ElementUtils.getTransform(e);// no it doesnt ... new AffineTransform(); Shape shape = ElementUtils.getElementShapeOrBounds(e); Rectangle2D bounds = shape.getBounds2D(); //System.out.println("selection bounds: "+bounds); - final double margin = 1; - bounds.setFrame(bounds.getMinX() - margin, bounds.getMinY() - margin, bounds.getWidth() + 2*margin, bounds.getHeight() + 2*margin); + + Point2D scale = GeometryUtils.getScale2D(selectionTransform); + final double marginX = Math.abs(scale.getX()) > 1e-10 ? 1 / scale.getX() : 1; + final double marginY = Math.abs(scale.getY()) > 1e-10 ? 1 / scale.getY() : 1; + + bounds.setFrame(bounds.getMinX() - marginX, bounds.getMinY() - marginY, bounds.getWidth() + 2*marginX, bounds.getHeight() + 2*marginY); List ss = e.getElementClass().getItemsByClass(SelectionSpecification.class); if (!ss.isEmpty()) { @@ -1021,7 +1065,7 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos Outline outline = (Outline) es.getAdapter(Outline.class); if (outline == null || outline.getElementShape(e) == null) continue; - ShapeNode shapenode = shapeholder.getOrCreateNode(getNodeId("outline", e, es), ShapeNode.class); + ShapeNode shapenode = shapeholder.getOrCreateNode(getNodeId("outline", e, es), SelectionShapeNode.class); // shapenode.setShape(es.getSelectionShape(e)); // shapenode.setStroke(SELECTION_STROKE); // shapenode.setScaleStroke(true); @@ -1057,7 +1101,7 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos G2DParentNode shapeholder = selectionNode.getOrCreateNode(getNodeId("outlines", e), G2DParentNode.class); for (SelectionOutline es : shapeHandlers) { - ShapeNode shapenode = shapeholder.getOrCreateNode(getNodeId("outline", e, es), ShapeNode.class); + ShapeNode shapenode = shapeholder.getOrCreateNode(getNodeId("outline", e, es), SelectionShapeNode.class); // shapenode.setShape(es.getSelectionShape(e)); // shapenode.setStroke(SELECTION_STROKE); // shapenode.setScaleStroke(true); @@ -1077,10 +1121,13 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos ISelectionProvider provider = this.getContext().getDefaultHintContext().getHint(KEY_SELECTION_PROVIDER); if (provider != null) { - provider.init(e, selectionNode, getNodeId("shape", e), selectionTransform, bounds, color); + provider.init(selectionId, e, selectionNode, getNodeId("shape", e), selectionTransform, bounds, color); } else { SelectionNode s = selectionNode.getOrCreateNode(getNodeId("shape", e), SelectionNode.class); - s.init(selectionTransform, bounds, color); + s.init(selectionId, selectionTransform, bounds, color); + Double paddingFactor = diagram.getHint(DiagramHints.SELECTION_PADDING_SCALE_FACTOR); + if (paddingFactor != null) + s.setPaddingFactor(paddingFactor); } }