/*******************************************************************************
- * 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
*
* Contributors:
* VTT Technical Research Centre of Finland - initial API and implementation
+ * Semantum Oy - GitLab issue #66
*******************************************************************************/
package org.simantics.g2d.diagram.participant;
* 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;
SingleElementNode diagramParent;
RTreeNode elementParent;
- boolean paintSelectionFrames;
+ ElementPainterConfiguration cfg;
/**
* Internally reused to avert constant reallocation.
}
public ElementPainter(boolean paintSelectionFrames) {
- this.paintSelectionFrames = paintSelectionFrames;
+ this(new ElementPainterConfiguration().paintSelectionFrames(paintSelectionFrames));
+ }
+
+ public ElementPainter(ElementPainterConfiguration cfg) {
+ this.cfg = cfg;
}
@Override
return;
if (oldValue != null) {
+ Map<INode, IElement> nodeToElementMap = oldValue.removeHint(DiagramHints.NODE_TO_ELEMENT_MAP);
for (IElement e : oldValue.getElements()) {
- removeElement(e);
+ removeElement(oldValue, e, nodeToElementMap);
}
oldValue.removeCompositionListener(this);
}
if (newValue != null) {
+ diagram.removeHint(DiagramHints.NODE_TO_ELEMENT_MAP);
+ Map<INode, IElement> 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);
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);
}
if (DEBUG)
System.out.println("EP.onElementAdded(" + d + ", " + e + ")");
+ Map<INode, IElement> 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
if (DEBUG)
System.out.println("EP.onElementRemoved(" + d + ", " + e + ")");
- removeElement(e);
+ removeElement(d, e, diagram.getHint(DiagramHints.NODE_TO_ELEMENT_MAP));
}
@Override
if (DEBUG)
System.out.println("EP.elementChildrenChanged: " + event);
+ Map<INode, IElement> 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<IElement> childrenTemp = new ArrayList<IElement>();
- public void addElement(IElement e, boolean synchronizeSceneGraphNow) {
+ public void addElement(IDiagram d, IElement e, boolean synchronizeSceneGraphNow, Map<INode, IElement> nodeElementMap) {
if (DEBUG)
System.out.println("EP.addElement(now=" + synchronizeSceneGraphNow + ", " + e + ")");
holder.setTransferableProvider(new ElementTransferableProvider(getContext(), e));
e.setHint(sgKey, holder);
holder.setZIndex(parentNode.getNodeCount() + 1);
+ if (nodeElementMap != null)
+ nodeElementMap.put(holder, e);
}
} else {
holder.setTransferableProvider(new ElementTransferableProvider(getContext(), e));
e.setHint(sgKey, holder);
holder.setZIndex(parentNode.getNodeCount() + 1);
+ if (nodeElementMap != null)
+ nodeElementMap.put(holder, e);
}
}
children.getChildren(e, childrenTemp);
//System.out.println("children: " + childrenTemp);
for (IElement child : childrenTemp) {
- addElement(child, false);
+ addElement(d, child, false, nodeElementMap);
}
childrenTemp.clear();
}
//setTreeDirty();
}
- protected void removeElement(IElement e) {
+ protected void removeElement(IDiagram d, IElement e, Map<INode, IElement> nodeElementMap) {
if (DEBUG)
System.out.println("EP.removeElement(" + e + ")");
Node n = e.removeHint(sgKey);
if (n != null) {
n.remove();
+ if (nodeElementMap != null)
+ nodeElementMap.remove(n);
}
}
Object task = BEGIN("EP.updateSelections");
try {
- if (!paintSelectionFrames)
+ if (!cfg.paintSelectionFrames)
return;
if (selection == null)
return;
Object task = BEGIN("EP.updateSelection");
try {
- if (!paintSelectionFrames)
+ if (!cfg.paintSelectionFrames)
return;
G2DParentNode elementNode = (G2DParentNode) el.getHint(ElementHints.KEY_SG_NODE);
continue;
if (NodeUtil.needSelectionPaint(elementNode))
- paintSelectionFrame(elementNode, selectionNode, el, color);
+ paintSelectionFrame(selectionId, elementNode, selectionNode, el, color);
nodesUpdated = true;
}
Color color = getSelectionColor(selectionId);
G2DParentNode selectionsNode = getSelectionsNode(selectionId);
+ Class<? extends G2DParentNode> 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);
createSelectionReference(selectionsNode, elementNode);
if (NodeUtil.needSelectionPaint(elementNode))
- paintSelectionFrame(en, selectionNode, e, color);
+ paintSelectionFrame(selectionId, en, selectionNode, e, color);
} else {
if (elementNode != null) {
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);
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);
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);
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);