-package org.simantics.modeling.ui.diagram.style;\r
-\r
-import java.awt.BasicStroke;\r
-import java.awt.Color;\r
-import java.awt.Paint;\r
-import java.awt.Shape;\r
-import java.awt.Stroke;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Path2D;\r
-import java.awt.geom.Rectangle2D;\r
-import java.util.Collection;\r
-import java.util.HashSet;\r
-import java.util.Set;\r
-\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.common.request.PossibleTypedParent;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.variable.Variable;\r
-import org.simantics.diagram.connection.RouteGraph;\r
-import org.simantics.diagram.connection.RouteGraphConnectionClass;\r
-import org.simantics.diagram.connection.RouteTerminal;\r
-import org.simantics.diagram.content.ConnectionUtil;\r
-import org.simantics.diagram.handler.Paster;\r
-import org.simantics.diagram.handler.Paster.RouteLine;\r
-import org.simantics.diagram.profile.ProfileKeys;\r
-import org.simantics.diagram.profile.StyleBase;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
-import org.simantics.g2d.diagram.IDiagram;\r
-import org.simantics.g2d.diagram.handler.DataElementMap;\r
-import org.simantics.g2d.element.ElementUtils;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.g2d.element.handler.SelectionOutline;\r
-import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline;\r
-import org.simantics.modeling.ModelingResources;\r
-import org.simantics.scenegraph.INode;\r
-import org.simantics.scenegraph.ParentNode;\r
-import org.simantics.scenegraph.g2d.IdentityAffineTransform;\r
-import org.simantics.scenegraph.g2d.nodes.ConnectionNode;\r
-import org.simantics.scenegraph.g2d.nodes.DecorationShapeNode;\r
-import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
-import org.simantics.scenegraph.profile.DataNodeMap;\r
-import org.simantics.scenegraph.profile.EvaluationContext;\r
-import org.simantics.scenegraph.profile.common.ProfileVariables;\r
-import org.simantics.scenegraph.utils.GeometryUtils;\r
-import org.simantics.scl.runtime.tuple.Tuple5;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
-\r
-import gnu.trove.set.TLongSet;\r
-import gnu.trove.set.hash.TLongHashSet;\r
-\r
-/**\r
- * @author Tuukka Lehtonen\r
- */\r
-public class TypicalInheritanceStyle extends StyleBase<TypicalInheritanceResult> {\r
-\r
- private static final TypicalInheritanceResult NOT_INHERITED = new TypicalInheritanceResult(Boolean.FALSE, null, null, Boolean.FALSE, null);\r
-\r
- private static final Paint PAINT = new Color(128, 128, 128, 64);\r
- private static final Paint PAINT_WITHOUT_SOURCE = new Color(255, 128, 128, 64);\r
- private static final Stroke STROKE = new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);\r
-\r
- @Override\r
- public TypicalInheritanceResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {\r
- DiagramResource DIA = DiagramResource.getInstance(graph); \r
- ModelingResources MOD = ModelingResources.getInstance(graph);\r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
-\r
- boolean templatized = graph.hasStatement(element, MOD.IsTemplatized);\r
- boolean hasElementSource = graph.hasStatement(element, MOD.HasElementSource);\r
- if (templatized) {\r
- if (graph.isInstanceOf(element, DIA.RouteGraphConnection)) {\r
- Collection<Resource> connectors = graph.getObjects(element, DIA.HasConnector);\r
- Collection<Resource> routeNodes = graph.getObjects(element, DIA.HasInteriorRouteNode);\r
- TLongHashSet nonTemplatizedConnectors = null;\r
-\r
- // This is needed to make this query result change every time the underlying element changes visually.\r
- Set<Object> identifier = new HashSet<Object>(connectors.size() + routeNodes.size());\r
-\r
- for (Resource connector : connectors) {\r
- for (Resource connectedTo : graph.getObjects(connector, STR.Connects)) {\r
- if (!connectedTo.equals(element)) {\r
- AffineTransform at = DiagramGraphUtil.getDynamicAffineTransform(graph, runtimeDiagram, connectedTo, DIA.HasDynamicTransform, false);\r
- identifier.add(at);\r
-\r
- boolean connectedToTemplatized = graph.hasStatement(connectedTo, MOD.IsTemplatized);\r
- if (!connectedToTemplatized) {\r
- if (nonTemplatizedConnectors == null)\r
- nonTemplatizedConnectors = new TLongHashSet();\r
- nonTemplatizedConnectors.add(connector.getResourceId());\r
- }\r
- break;\r
- }\r
- }\r
- }\r
- if (!routeNodes.isEmpty()) {\r
- for (Resource routeLine : routeNodes) {\r
- RouteLine rl = Paster.readRouteLine(graph, routeLine);\r
- identifier.add(rl);\r
- }\r
- }\r
- return new TypicalInheritanceResult(templatized, nonTemplatizedConnectors, IdentityAffineTransform.INSTANCE, hasElementSource, identifier);\r
- } else if (graph.isInstanceOf(element, DIA.Monitor)) {\r
- AffineTransform worldTransform = DiagramGraphUtil.getWorldTransform(graph, element);\r
- Resource monitoredComponent = graph.getPossibleObject(element, DIA.HasMonitorComponent);\r
-\r
- if (monitoredComponent != null) {\r
- Resource monitoredElement = graph.getPossibleObject(monitoredComponent, MOD.ComponentToElement);\r
- if (graph.isInstanceOf(monitoredElement, DIA.Connection)) {\r
- Resource tailNode = ConnectionUtil.getConnectionTailNode(graph, monitoredElement);\r
- if (tailNode != null) {\r
- monitoredElement = tailNode;\r
- }\r
- }\r
-\r
- if (monitoredElement != null) {\r
- Resource diagram = graph.syncRequest(new PossibleTypedParent(element, DIA.Diagram));\r
- if (diagram != null) {\r
- Resource monitoredDiagram = graph.syncRequest(new PossibleTypedParent(monitoredElement, DIA.Diagram));\r
- if (diagram.equals(monitoredDiagram)) {\r
- AffineTransform monitoredElementWorldTransform = DiagramGraphUtil.getWorldTransform(graph, monitoredElement);\r
- worldTransform.preConcatenate(monitoredElementWorldTransform);\r
- }\r
- }\r
- }\r
- }\r
-\r
- return new TypicalInheritanceResult(templatized, null, worldTransform, hasElementSource, null);\r
- }\r
-\r
- AffineTransform worldTransform = DiagramGraphUtil.getDynamicWorldTransform(graph, runtimeDiagram, element);\r
- return new TypicalInheritanceResult(templatized, null, worldTransform, hasElementSource, null);\r
- }\r
-\r
- return NOT_INHERITED;\r
- }\r
-\r
- public void applyStyleForItem(EvaluationContext context, DataNodeMap map, Object item, TypicalInheritanceResult result) {\r
- final INode _node = map.getNode(item);\r
-\r
- if (result != null && Boolean.TRUE.equals(result.isTemplatized())) {\r
- boolean fill = true;\r
- Stroke stroke = null;\r
- ShapeNode node = null;\r
-\r
- if (_node instanceof ParentNode<?>) {\r
- node = ProfileVariables.claimChild(_node, "", "typical", DecorationShapeNode.class, context);\r
- } else {\r
- // Ignore, cannot create decoration.\r
- return;\r
- }\r
-\r
- if (_node instanceof ConnectionNode) {\r
- fill = false;\r
- stroke = STROKE;\r
- }\r
-\r
- Shape shape = null;\r
- IDiagram diagram = context.getConstant(ProfileKeys.DIAGRAM);\r
- if (diagram != null) {\r
- DataElementMap dem = diagram.getDiagramClass().getAtMostOneItemOfClass(DataElementMap.class);\r
- if (dem != null) {\r
- IElement element = dem.getElement(diagram, item);\r
- if (element != null) {\r
- SelectionOutline so = element.getElementClass().getAtMostOneItemOfClass(SelectionOutline.class);\r
- if (so != null) {\r
- RouteGraph rg = element.getHint(RouteGraphConnectionClass.KEY_ROUTEGRAPH);\r
- if (rg != null) {\r
- RouteGraph rgc = rg;\r
- TLongSet nonTemplatizedConnectors = result.getNonTemplatizedConnectors();\r
- if (nonTemplatizedConnectors != null) {\r
- rgc = rg.copy();\r
- // Must copy the RouteTerminal to an array before\r
- // invoking rgc.remove(RouteTerminal), otherwise\r
- // ConcurrentModificationExceptions will arise.\r
- Collection<RouteTerminal> rtc = rgc.getTerminals();\r
- if (nonTemplatizedConnectors.size() > (rtc.size() - 2)) {\r
- // Cannot make a RouteGraph any simpler\r
- // than a simple connection between two\r
- // terminals.\r
- // Fall back to highlighting the whole\r
- // connection.\r
- } else {\r
- RouteTerminal[] rts = rtc.toArray(new RouteTerminal[rtc.size()]);\r
- for (RouteTerminal rt : rts) {\r
- Object data = rt.getData();\r
- if (data instanceof Long) {\r
- if (nonTemplatizedConnectors.contains(((Long) data).longValue()))\r
- rgc.remove(rt);\r
- }\r
- }\r
- }\r
- }\r
-\r
- Path2D path = rgc.getPath2D();\r
- Stroke connectionStroke = ConnectionSelectionOutline.INSTANCE.resolveStroke(element, ConnectionSelectionOutline.defaultStroke);\r
- shape = connectionStroke.createStrokedShape(path);\r
- } else {\r
- shape = so.getSelectionShape(element);\r
- }\r
- } else {\r
- Rectangle2D rect = ElementUtils.getElementBounds(element);\r
- shape = GeometryUtils.expandRectangle( rect, 0.5 );\r
- }\r
- }\r
- }\r
- }\r
-\r
- AffineTransform at = result.getWorldTransform();\r
- if (at != null)\r
- node.setTransform(at);\r
-\r
- node.setZIndex(-1000);\r
- node.setColor(result.hasElementSource() ? PAINT : PAINT_WITHOUT_SOURCE);\r
- node.setFill(fill);\r
- node.setScaleStroke(false);\r
- node.setScaleShape(false);\r
- node.setStroke(stroke);\r
- node.setShape(shape);\r
- } else {\r
- cleanupStyleForNode(context, _node);\r
- }\r
- }\r
-\r
- @Override\r
- protected void cleanupStyleForNode(EvaluationContext context, INode node) {\r
- ProfileVariables.denyChild(node, "*", "typical");\r
- ProfileVariables.denyChild(node, "", "typical");\r
- }\r
-\r
-}\r
-\r
-class TypicalInheritanceResult extends Tuple5 {\r
- public TypicalInheritanceResult(Boolean templatized, TLongSet nonTemplatizedConnectors, AffineTransform worldTransform, Boolean hasElementSource, Set<Object> queryIdentifier) {\r
- super(templatized, nonTemplatizedConnectors, worldTransform, hasElementSource, queryIdentifier);\r
- }\r
- public boolean isTemplatized() {\r
- return (Boolean) get(0);\r
- }\r
- public TLongSet getNonTemplatizedConnectors() {\r
- return (TLongSet) get(1);\r
- }\r
- public AffineTransform getWorldTransform() {\r
- return (AffineTransform) get(2);\r
- }\r
- public boolean hasElementSource() {\r
- return (Boolean) get(3);\r
- }\r
-}\r
+package org.simantics.modeling.ui.diagram.style;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Paint;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.PossibleTypedParent;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.diagram.connection.RouteGraph;
+import org.simantics.diagram.connection.RouteGraphConnectionClass;
+import org.simantics.diagram.connection.RouteTerminal;
+import org.simantics.diagram.content.ConnectionUtil;
+import org.simantics.diagram.handler.Paster;
+import org.simantics.diagram.handler.Paster.RouteLine;
+import org.simantics.diagram.profile.ProfileKeys;
+import org.simantics.diagram.profile.StyleBase;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.diagram.handler.DataElementMap;
+import org.simantics.g2d.element.ElementUtils;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.element.handler.SelectionOutline;
+import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.ParentNode;
+import org.simantics.scenegraph.g2d.IdentityAffineTransform;
+import org.simantics.scenegraph.g2d.nodes.ConnectionNode;
+import org.simantics.scenegraph.g2d.nodes.DecorationShapeNode;
+import org.simantics.scenegraph.g2d.nodes.ShapeNode;
+import org.simantics.scenegraph.profile.DataNodeMap;
+import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.common.ProfileVariables;
+import org.simantics.scenegraph.utils.GeometryUtils;
+import org.simantics.scl.runtime.tuple.Tuple5;
+import org.simantics.structural.stubs.StructuralResource2;
+
+import gnu.trove.set.TLongSet;
+import gnu.trove.set.hash.TLongHashSet;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class TypicalInheritanceStyle extends StyleBase<TypicalInheritanceResult> {
+
+ private static final TypicalInheritanceResult NOT_INHERITED = new TypicalInheritanceResult(Boolean.FALSE, null, null, Boolean.FALSE, null);
+
+ private static final Paint PAINT = new Color(128, 128, 128, 64);
+ private static final Paint PAINT_WITHOUT_SOURCE = new Color(255, 128, 128, 64);
+ private static final Stroke STROKE = new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
+
+ @Override
+ public TypicalInheritanceResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+
+ boolean templatized = graph.hasStatement(element, MOD.IsTemplatized);
+ boolean hasElementSource = graph.hasStatement(element, MOD.HasElementSource);
+ if (templatized) {
+ if (graph.isInstanceOf(element, DIA.RouteGraphConnection)) {
+ Collection<Resource> connectors = graph.getObjects(element, DIA.HasConnector);
+ Collection<Resource> routeNodes = graph.getObjects(element, DIA.HasInteriorRouteNode);
+ TLongHashSet nonTemplatizedConnectors = null;
+
+ // This is needed to make this query result change every time the underlying element changes visually.
+ Set<Object> identifier = new HashSet<Object>(connectors.size() + routeNodes.size());
+
+ for (Resource connector : connectors) {
+ for (Resource connectedTo : graph.getObjects(connector, STR.Connects)) {
+ if (!connectedTo.equals(element)) {
+ AffineTransform at = DiagramGraphUtil.getDynamicAffineTransform(graph, runtimeDiagram, connectedTo, DIA.HasDynamicTransform, false);
+ identifier.add(at);
+
+ boolean connectedToTemplatized = graph.hasStatement(connectedTo, MOD.IsTemplatized);
+ if (!connectedToTemplatized) {
+ if (nonTemplatizedConnectors == null)
+ nonTemplatizedConnectors = new TLongHashSet();
+ nonTemplatizedConnectors.add(connector.getResourceId());
+ }
+ break;
+ }
+ }
+ }
+ if (!routeNodes.isEmpty()) {
+ for (Resource routeLine : routeNodes) {
+ RouteLine rl = Paster.readRouteLine(graph, routeLine);
+ identifier.add(rl);
+ }
+ }
+ return new TypicalInheritanceResult(templatized, nonTemplatizedConnectors, IdentityAffineTransform.INSTANCE, hasElementSource, identifier);
+ } else if (graph.isInstanceOf(element, DIA.Monitor)) {
+ AffineTransform worldTransform = DiagramGraphUtil.getWorldTransform(graph, element);
+ Resource monitoredComponent = graph.getPossibleObject(element, DIA.HasMonitorComponent);
+
+ if (monitoredComponent != null) {
+ Resource monitoredElement = graph.getPossibleObject(monitoredComponent, MOD.ComponentToElement);
+ if (graph.isInstanceOf(monitoredElement, DIA.Connection)) {
+ Resource tailNode = ConnectionUtil.getConnectionTailNode(graph, monitoredElement);
+ if (tailNode != null) {
+ monitoredElement = tailNode;
+ }
+ }
+
+ if (monitoredElement != null) {
+ Resource diagram = graph.syncRequest(new PossibleTypedParent(element, DIA.Diagram));
+ if (diagram != null) {
+ Resource monitoredDiagram = graph.syncRequest(new PossibleTypedParent(monitoredElement, DIA.Diagram));
+ if (diagram.equals(monitoredDiagram)) {
+ AffineTransform monitoredElementWorldTransform = DiagramGraphUtil.getWorldTransform(graph, monitoredElement);
+ worldTransform.preConcatenate(monitoredElementWorldTransform);
+ }
+ }
+ }
+ }
+
+ return new TypicalInheritanceResult(templatized, null, worldTransform, hasElementSource, null);
+ }
+
+ AffineTransform worldTransform = DiagramGraphUtil.getDynamicWorldTransform(graph, runtimeDiagram, element);
+ return new TypicalInheritanceResult(templatized, null, worldTransform, hasElementSource, null);
+ }
+
+ return NOT_INHERITED;
+ }
+
+ public void applyStyleForItem(EvaluationContext context, DataNodeMap map, Object item, TypicalInheritanceResult result) {
+ final INode _node = map.getNode(item);
+
+ if (result != null && Boolean.TRUE.equals(result.isTemplatized())) {
+ boolean fill = true;
+ Stroke stroke = null;
+ ShapeNode node = null;
+
+ if (_node instanceof ParentNode<?>) {
+ node = ProfileVariables.claimChild(_node, "", "typical", DecorationShapeNode.class, context);
+ } else {
+ // Ignore, cannot create decoration.
+ return;
+ }
+
+ if (_node instanceof ConnectionNode) {
+ fill = false;
+ stroke = STROKE;
+ }
+
+ Shape shape = null;
+ IDiagram diagram = context.getConstant(ProfileKeys.DIAGRAM);
+ if (diagram != null) {
+ DataElementMap dem = diagram.getDiagramClass().getAtMostOneItemOfClass(DataElementMap.class);
+ if (dem != null) {
+ IElement element = dem.getElement(diagram, item);
+ if (element != null) {
+ SelectionOutline so = element.getElementClass().getAtMostOneItemOfClass(SelectionOutline.class);
+ if (so != null) {
+ RouteGraph rg = element.getHint(RouteGraphConnectionClass.KEY_ROUTEGRAPH);
+ if (rg != null) {
+ RouteGraph rgc = rg;
+ TLongSet nonTemplatizedConnectors = result.getNonTemplatizedConnectors();
+ if (nonTemplatizedConnectors != null) {
+ rgc = rg.copy();
+ // Must copy the RouteTerminal to an array before
+ // invoking rgc.remove(RouteTerminal), otherwise
+ // ConcurrentModificationExceptions will arise.
+ Collection<RouteTerminal> rtc = rgc.getTerminals();
+ if (nonTemplatizedConnectors.size() > (rtc.size() - 2)) {
+ // Cannot make a RouteGraph any simpler
+ // than a simple connection between two
+ // terminals.
+ // Fall back to highlighting the whole
+ // connection.
+ } else {
+ RouteTerminal[] rts = rtc.toArray(new RouteTerminal[rtc.size()]);
+ for (RouteTerminal rt : rts) {
+ Object data = rt.getData();
+ if (data instanceof Long) {
+ if (nonTemplatizedConnectors.contains(((Long) data).longValue()))
+ rgc.remove(rt);
+ }
+ }
+ }
+ }
+
+ Path2D path = rgc.getPath2D();
+ Stroke connectionStroke = ConnectionSelectionOutline.INSTANCE.resolveStroke(element, ConnectionSelectionOutline.defaultStroke);
+ shape = connectionStroke.createStrokedShape(path);
+ } else {
+ shape = so.getSelectionShape(element);
+ }
+ } else {
+ Rectangle2D rect = ElementUtils.getElementBounds(element);
+ shape = GeometryUtils.expandRectangle( rect, 0.5 );
+ }
+ }
+ }
+ }
+
+ AffineTransform at = result.getWorldTransform();
+ if (at != null)
+ node.setTransform(at);
+
+ node.setZIndex(-1000);
+ node.setColor(result.hasElementSource() ? PAINT : PAINT_WITHOUT_SOURCE);
+ node.setFill(fill);
+ node.setScaleStroke(false);
+ node.setScaleShape(false);
+ node.setStroke(stroke);
+ node.setShape(shape);
+ } else {
+ cleanupStyleForNode(context, _node);
+ }
+ }
+
+ @Override
+ protected void cleanupStyleForNode(EvaluationContext context, INode node) {
+ ProfileVariables.denyChild(node, "*", "typical");
+ ProfileVariables.denyChild(node, "", "typical");
+ }
+
+}
+
+class TypicalInheritanceResult extends Tuple5 {
+ public TypicalInheritanceResult(Boolean templatized, TLongSet nonTemplatizedConnectors, AffineTransform worldTransform, Boolean hasElementSource, Set<Object> queryIdentifier) {
+ super(templatized, nonTemplatizedConnectors, worldTransform, hasElementSource, queryIdentifier);
+ }
+ public boolean isTemplatized() {
+ return (Boolean) get(0);
+ }
+ public TLongSet getNonTemplatizedConnectors() {
+ return (TLongSet) get(1);
+ }
+ public AffineTransform getWorldTransform() {
+ return (AffineTransform) get(2);
+ }
+ public boolean hasElementSource() {
+ return (Boolean) get(3);
+ }
+}