/*******************************************************************************
- * 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;
import org.simantics.g2d.element.handler.Children;
import org.simantics.g2d.element.handler.Children.ChildEvent;
import org.simantics.g2d.element.handler.Children.ChildListener;
+import org.simantics.g2d.element.handler.ElementLayers;
import org.simantics.g2d.element.handler.FillColor;
import org.simantics.g2d.element.handler.Outline;
import org.simantics.g2d.element.handler.OutlineColorSpec;
import org.simantics.g2d.element.handler.StrokeSpec;
import org.simantics.g2d.element.handler.TerminalTopology;
import org.simantics.g2d.element.handler.Transform;
-import org.simantics.g2d.layers.ILayer;
+import org.simantics.g2d.layers.ILayers;
+import org.simantics.g2d.layers.ILayers.ILayersListener;
import org.simantics.g2d.layers.ILayersEditor;
-import org.simantics.g2d.layers.ILayersEditor.ILayersEditorListener;
import org.simantics.g2d.participant.TransformUtil;
import org.simantics.g2d.scenegraph.SceneGraphConstants;
import org.simantics.g2d.utils.ElementNodeBridge;
import org.simantics.scenegraph.g2d.G2DParentNode;
import org.simantics.scenegraph.g2d.G2DSceneGraph;
import org.simantics.scenegraph.g2d.IG2DNode;
+import org.simantics.scenegraph.g2d.color.ColorFilter;
import org.simantics.scenegraph.g2d.nodes.ConnectionNode;
import org.simantics.scenegraph.g2d.nodes.DataNode;
import org.simantics.scenegraph.g2d.nodes.LinkNode;
* 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);
oldValue.removeKeyHintListener(Hints.KEY_DIRTY, diagramHintListener);
oldValue.removeKeyHintListener(Hints.KEY_DISABLE_PAINTING, diagramHintListener);
- ILayersEditor layers = oldValue.getHint(DiagramHints.KEY_LAYERS_EDITOR);
+ ILayers layers = oldValue.getHint(DiagramHints.KEY_LAYERS);
if (layers != null) {
- layers.removeListener(layersListener);
+ layers.removeLayersListener(layersListener);
}
for (TransactionContext tc : oldValue.getDiagramClass().getItemsByClass(TransactionContext.class)) {
}
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);
newValue.addKeyHintListener(Hints.KEY_DISABLE_PAINTING, diagramHintListener);
newValue.addKeyHintListener(Hints.KEY_DIRTY, diagramHintListener);
- ILayersEditor layers = newValue.getHint(DiagramHints.KEY_LAYERS_EDITOR);
+ ILayers layers = newValue.getHint(DiagramHints.KEY_LAYERS);
if (layers != null) {
- layers.addListener(layersListener);
+ layers.addLayersListener(layersListener);
}
for (TransactionContext tc : newValue.getDiagramClass().getItemsByClass(TransactionContext.class)) {
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);
}
// Layer configuration change listening and reaction logic
// ------------------------------------------------------------------------
- ILayersEditorListener layersListener = new ILayersEditorListener() {
- private void layersChanged() {
+ ILayersListener layersListener = new ILayersListener() {
+ @Override
+ public void changed() {
Object task = BEGIN("EP.layersChanged");
- // Update visibility/focusability for each node only, do not reinitialize the graphics.
+ ICanvasContext ctx = getContext();
+ if(ctx != null) {
+ G2DSceneGraph sg = ctx.getSceneGraph();
+ if(sg != null) {
+ ILayersEditor layers = diagram.getHint(DiagramHints.KEY_LAYERS);
+ sg.setGlobalProperty(G2DSceneGraph.IGNORE_FOCUS, layers.getIgnoreFocusSettings());
+ }
+ }
updateAllVisibility();
END(task);
}
- @Override
- public void layerRemoved(ILayer layer) {
- layersChanged();
- }
- @Override
- public void layerDeactivated(ILayer layer) {
- layersChanged();
- }
- @Override
- public void layerAdded(ILayer layer) {
- layersChanged();
- }
- @Override
- public void layerActivated(ILayer layer) {
- layersChanged();
- }
- @Override
- public void ignoreFocusChanged(boolean value) {
- ICanvasContext ctx = getContext();
- if(ctx == null) return;
- G2DSceneGraph sg = ctx.getSceneGraph();
- if(sg == null) return;
- sg.setGlobalProperty(G2DSceneGraph.IGNORE_FOCUS, value);
- }
- @Override
- public void ignoreVisibilityChanged(boolean value) {
- layersChanged();
- }
};
protected void updateAllVisibility() {
}
} else if (key == ElementHints.KEY_FOCUS_LAYERS || key == ElementHints.KEY_VISIBLE_LAYERS) {
if (sender instanceof IElement) {
- assert getContext().getThreadAccess().currentThreadAccess();
- IElement e = (IElement) sender;
- Object task = BEGIN("layers changed: " + e);
- update(e);
- END(task);
+ getContext().getThreadAccess().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ assert getContext().getThreadAccess().currentThreadAccess();
+ IElement e = (IElement) sender;
+ Object task = BEGIN("layers changed: " + e);
+ update(e);
+ END(task);
+ }
+ });
}
}
}
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);
}
}
if (ElementUtils.isHidden(e))
return null;
-// ElementClass ec = e.getElementClass();
-// ILayers layers = diagram.getHint(DiagramHints.KEY_LAYERS);
-// if (layers != null && !layers.getIgnoreVisibilitySettings()) {
-// ElementLayers el = ec.getAtMostOneItemOfClass(ElementLayers.class);
-// if (el != null && !el.isVisible(e, layers)) {
-// return null;
-// }
-// }
// Update the node scene graph through SceneGraph handlers.
List<SceneGraph> nodeHandlers = e.getElementClass().getItemsByClass(SceneGraph.class);
e.setHint(elementSgNodeKey, holder);
}
holder.setComposite(composite);
- holder.setVisible(true);
+ boolean visible = true;
+ ElementClass ec = e.getElementClass();
+ ILayers layers = diagram.getHint(DiagramHints.KEY_LAYERS);
+ if (layers != null && !layers.getIgnoreVisibilitySettings()) {
+ ElementLayers el = ec.getAtMostOneItemOfClass(ElementLayers.class);
+ if (el != null && !el.isVisible(e, layers)) {
+ visible = false;
+ }
+ }
+ holder.setVisible(visible);
+
+ ColorFilter colorFilter = e.getHint(ElementHints.KEY_COLOR_FILTER);
+ holder.setColorFilter(colorFilter);
for (SceneGraph n : nodeHandlers) {
n.init(e, holder);
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);
}
}