diff --git a/plugins/de.cau.cs.kieler.klighd.lsp/src/de/cau/cs/kieler/klighd/lsp/model/KGraphModel.xtend b/plugins/de.cau.cs.kieler.klighd.lsp/src/de/cau/cs/kieler/klighd/lsp/model/KGraphModel.xtend index 3b6affa4e..6cc81eb50 100644 --- a/plugins/de.cau.cs.kieler.klighd.lsp/src/de/cau/cs/kieler/klighd/lsp/model/KGraphModel.xtend +++ b/plugins/de.cau.cs.kieler.klighd.lsp/src/de/cau/cs/kieler/klighd/lsp/model/KGraphModel.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2018,2019 by + * Copyright 2018-2022 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -32,6 +32,15 @@ import org.eclipse.sprotty.SNode import org.eclipse.sprotty.SPort import org.eclipse.xtend.lib.annotations.Accessors +/** + * Abstract base class for Sprotty-based KGraph Elements. + */ +abstract interface SKElement { + def List getData() + def void setData(List data) + def HashMap getProperties() +} + /** * Sprotty node with additional fields needed by the translation from a * {@link KNode KNode}. @@ -39,7 +48,7 @@ import org.eclipse.xtend.lib.annotations.Accessors * @author nre */ @Accessors -class SKNode extends SNode { +class SKNode extends SNode implements SKElement { List data HashMap properties = newHashMap Direction direction @@ -53,7 +62,7 @@ class SKNode extends SNode { * @author nre */ @Accessors -class SKLabel extends SLabel { +class SKLabel extends SLabel implements SKElement { List data String tooltip HashMap properties = newHashMap @@ -66,7 +75,7 @@ class SKLabel extends SLabel { * @author nre */ @Accessors -class SKEdge extends SEdge { +class SKEdge extends SEdge implements SKElement { List data String tooltip KVectorChain junctionPoints @@ -80,7 +89,7 @@ class SKEdge extends SEdge { * @author nre */ @Accessors -class SKPort extends SPort { +class SKPort extends SPort implements SKElement { List data String tooltip HashMap properties = newHashMap @@ -93,7 +102,7 @@ class SKPort extends SPort { * @author nre */ @Accessors -class SKGraph extends SGraph { +class SKGraph extends SGraph implements SKElement { List data HashMap properties = newHashMap } diff --git a/plugins/de.cau.cs.kieler.klighd.lsp/src/de/cau/cs/kieler/klighd/lsp/utils/KGraphMappingUtil.xtend b/plugins/de.cau.cs.kieler.klighd.lsp/src/de/cau/cs/kieler/klighd/lsp/utils/KGraphMappingUtil.xtend index 6a32d7700..1162d4244 100644 --- a/plugins/de.cau.cs.kieler.klighd.lsp/src/de/cau/cs/kieler/klighd/lsp/utils/KGraphMappingUtil.xtend +++ b/plugins/de.cau.cs.kieler.klighd.lsp/src/de/cau/cs/kieler/klighd/lsp/utils/KGraphMappingUtil.xtend @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright 2018,2019 by + * Copyright 2018-2022 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -16,29 +16,30 @@ */ package de.cau.cs.kieler.klighd.lsp.utils +import de.cau.cs.kieler.klighd.KlighdDataManager import de.cau.cs.kieler.klighd.kgraph.KEdge -import de.cau.cs.kieler.klighd.kgraph.KEdgeLayout import de.cau.cs.kieler.klighd.kgraph.KGraphElement import de.cau.cs.kieler.klighd.kgraph.KLabel import de.cau.cs.kieler.klighd.kgraph.KNode import de.cau.cs.kieler.klighd.kgraph.KPort import de.cau.cs.kieler.klighd.kgraph.KShapeLayout import de.cau.cs.kieler.klighd.lsp.model.SKEdge +import de.cau.cs.kieler.klighd.lsp.model.SKElement import de.cau.cs.kieler.klighd.lsp.model.SKLabel import de.cau.cs.kieler.klighd.lsp.model.SKNode import de.cau.cs.kieler.klighd.lsp.model.SKPort import java.util.ArrayList +import java.util.List import java.util.Map +import org.eclipse.elk.core.math.KVector +import org.eclipse.elk.core.math.KVectorChain import org.eclipse.elk.core.options.CoreOptions +import org.eclipse.elk.graph.properties.IProperty import org.eclipse.sprotty.Dimension import org.eclipse.sprotty.Point import org.eclipse.sprotty.SModelElement import org.eclipse.sprotty.SShapeElement -import de.cau.cs.kieler.klighd.KlighdDataManager -import org.eclipse.elk.core.math.KVectorChain -import org.eclipse.elk.core.math.KVector -import org.eclipse.elk.graph.properties.IProperty -import java.util.List +import de.cau.cs.kieler.klighd.kgraph.util.KGraphUtil /** * A helper class containing static methods for mapping of KGraph and SGraph bounds. @@ -59,10 +60,9 @@ class KGraphMappingUtil { mapLayout(kGraphElement as KNode, sModelElement as SKNode) } else if (kGraphElement instanceof KEdge && sModelElement instanceof SKEdge) { mapLayout(kGraphElement as KEdge, sModelElement as SKEdge) - } else if (kGraphElement instanceof KPort && sModelElement instanceof SKPort) { - mapLayout(kGraphElement as KPort, sModelElement as SKPort) - } else if (kGraphElement instanceof KLabel && sModelElement instanceof SKLabel) { - mapLayout(kGraphElement as KLabel, sModelElement as SKLabel) + } else if (kGraphElement instanceof KPort && sModelElement instanceof SKPort + || kGraphElement instanceof KLabel && sModelElement instanceof SKLabel) { + mapLayout(kGraphElement as KShapeLayout, sModelElement as SShapeElement) } else { throw new IllegalArgumentException("The KGraph and SGraph classes do not map to each other: " + kGraphElement.class + ", " + sModelElement.class) @@ -73,49 +73,50 @@ class KGraphMappingUtil { /** * Maps an edge from KGraph to SGraph * - * @param kedge The KGraph edge - * @param skedge The SkGraph edge + * @param kEdge The KGraph edge + * @param skEdge The SkGraph edge */ - private static def mapLayout(KEdgeLayout kedge, SKEdge skedge) { - var leftInset = 0.0; - var topInset = 0.0; - if (kedge instanceof KEdge) { - var parent = kedge.getSource().getParent(); - var inset = parent.getInsets(); - leftInset = inset.left; - topInset = inset.top; + private static def mapLayout(KEdge kEdge, SKEdge skEdge) { + var KNode parent + if (KGraphUtil.isDescendant(kEdge.target, kEdge.source)) { + parent = kEdge.source + } else { + parent = kEdge.source.parent } + var inset = parent.getInsets(); + val leftInset = inset.left; + val topInset = inset.top; // Copy all routing points. var ArrayList routingPoints = new ArrayList - val sourcePoint = kedge.sourcePoint - val targetPoint = kedge.targetPoint + val sourcePoint = kEdge.sourcePoint + val targetPoint = kEdge.targetPoint if (sourcePoint !== null) { routingPoints.add(new Point(sourcePoint.x + leftInset, sourcePoint.y + topInset)) } - for (bendPoint : kedge.bendPoints) { + for (bendPoint : kEdge.bendPoints) { routingPoints.add(new Point(bendPoint.x + leftInset, bendPoint.y + topInset)) } if (targetPoint !== null) { routingPoints.add(new Point(targetPoint.x + leftInset, targetPoint.y + topInset)) } - skedge.routingPoints = routingPoints + skEdge.routingPoints = routingPoints // Copy the bend points. - skedge.junctionPoints = new KVectorChain() - skedge.junctionPoints.addAllAsCopies(0,kedge.getProperty(CoreOptions.JUNCTION_POINTS)) - skedge.junctionPoints.offset(new KVector(leftInset, topInset)) + skEdge.junctionPoints = new KVectorChain() + skEdge.junctionPoints.addAllAsCopies(0, kEdge.getProperty(CoreOptions.JUNCTION_POINTS)) + skEdge.junctionPoints.offset(new KVector(leftInset, topInset)) // map all properties excepts those that are blacklisted - var properties = kedge.allProperties; + var properties = kEdge.allProperties; var blackList = KlighdDataManager.instance.blacklistedProperties; for (propertyKVPair : properties.entrySet()) { if (!containsPropertyWithId(blackList, propertyKVPair.key.id)) { // TODO: remove this check once https://github.com/kieler/semantics/pull/13 has been merged if (!propertyKVPair.key.id.equals("de.cau.cs.kieler.sccharts.ui.tracker")) { - skedge.properties.put(propertyKVPair.key.id, propertyKVPair.value) + skEdge.properties.put(propertyKVPair.key.id, propertyKVPair.value) } } } @@ -175,56 +176,36 @@ class KGraphMappingUtil { * @param kElement The KGraph shape * @param sElement The SGraph shape */ - private static def mapLayout(KShapeLayout kElement, SShapeElement sElement) { + private static def mapLayout(KShapeLayout kElement, SShapeElement /*& SKElement*/ sElement) { var leftInset = 0.0; var topInset = 0.0; + // Edge labels behave differently: the reference point for the position is the source node child area if the + // target node is directly or indirectly contained by the source node, the source node's parent child area + // otherwise + if (kElement instanceof KLabel && (kElement as KLabel).parent instanceof KEdge) { + val kEdge = (kElement as KLabel).parent as KEdge + var KNode parent + if (KGraphUtil.isDescendant(kEdge.target, kEdge.source)) { + parent = kEdge.source + } else { + parent = kEdge.source.parent + } + var inset = parent.getInsets(); + leftInset = inset.left; + topInset = inset.top; + } var properties = kElement.allProperties; var blackList = KlighdDataManager.instance.blacklistedProperties; - if (kElement instanceof KLabel){ - var parent = kElement.getParent(); - var KNode grandParent = null; - - if (parent instanceof KNode) { - grandParent = parent.getParent(); - } else if (parent instanceof KEdge) { - grandParent = parent.getSource().getParent(); - } else if (parent instanceof KPort) { - grandParent = parent.getNode().getParent(); - } - - if (grandParent !== null) { - var inset = grandParent.getInsets(); - leftInset = inset.left; - topInset = inset.top; - } - - for (propertyKVPair : properties.entrySet()) { - if (!containsPropertyWithId(blackList, propertyKVPair.key.id)) { - // TODO: remove this check once https://github.com/kieler/semantics/pull/13 has been merged - if (!propertyKVPair.key.id.equals("de.cau.cs.kieler.sccharts.ui.tracker")) { - (sElement as SKLabel).properties.put(propertyKVPair.key.id, propertyKVPair.value) - } - } - } - } else if (kElement instanceof KPort) { - var parent = kElement.getNode().getParent(); - if (parent !== null) { - var inset = parent.getInsets(); - leftInset = inset.left; - topInset = inset.top; - } - - for (propertyKVPair : properties.entrySet()) { - if (!containsPropertyWithId(blackList, propertyKVPair.key.id)) { - // TODO: remove this check once https://github.com/kieler/semantics/pull/13 has been merged - if (!propertyKVPair.key.id.equals("de.cau.cs.kieler.sccharts.ui.tracker")) { - (sElement as SKPort).properties.put(propertyKVPair.key.id, propertyKVPair.value) - } + for (propertyKVPair : properties.entrySet()) { + if (!containsPropertyWithId(blackList, propertyKVPair.key.id)) { + // TODO: remove this check once https://github.com/kieler/semantics/pull/13 has been merged + if (!propertyKVPair.key.id.equals("de.cau.cs.kieler.sccharts.ui.tracker")) { + (sElement as SKElement).properties.put(propertyKVPair.key.id, propertyKVPair.value) } } - } + } sElement.position = new Point(kElement.xpos + leftInset, kElement.ypos + topInset) sElement.size = new Dimension(kElement.width, kElement.height)