X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2Fdiagram%2Fstyle%2FTypicalInheritanceStyle.java;h=fbec1abec13d169d982df9251fe89aa2104a33c9;hp=c0de412678315b21ceb99ba0832e6bf281295131;hb=28438fa467ae60dd63515be2df724c6ff9c299c9;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/style/TypicalInheritanceStyle.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/style/TypicalInheritanceStyle.java index c0de41267..fbec1abec 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/style/TypicalInheritanceStyle.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/style/TypicalInheritanceStyle.java @@ -1,250 +1,250 @@ -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 { - - 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 connectors = graph.getObjects(element, DIA.HasConnector); - Collection 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 identifier = new HashSet(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.getWorldTransform(graph, 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 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 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); - } -} +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.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.g2d.elementclass.RouteGraphConnectionClass; +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 { + + 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 connectors = graph.getObjects(element, DIA.HasConnector); + Collection 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 identifier = new HashSet(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); //$NON-NLS-1$ //$NON-NLS-2$ + } 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 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"); //$NON-NLS-1$ //$NON-NLS-2$ + ProfileVariables.denyChild(node, "", "typical"); //$NON-NLS-1$ //$NON-NLS-2$ + } + +} + +class TypicalInheritanceResult extends Tuple5 { + public TypicalInheritanceResult(Boolean templatized, TLongSet nonTemplatizedConnectors, AffineTransform worldTransform, Boolean hasElementSource, Set 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); + } +}