Skip to content

Commit

Permalink
[2516] Improve the diagram core API to hide the header separator
Browse files Browse the repository at this point in the history
Bug: #2516
Signed-off-by: Guillaume Coutable <guillaume.coutable@obeo.fr>
  • Loading branch information
gcoutable committed Nov 7, 2023
1 parent ef92c03 commit 649a0be
Show file tree
Hide file tree
Showing 29 changed files with 77 additions and 30 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.adoc
Expand Up @@ -39,6 +39,11 @@ It requires to add a `isHeaderProvider` to the _LabelDescription_ of Node.
Replace only for the programmatic API the _LabelDescription_ type in _NodeDescription_ by _InsideLabelDescription_ and add the inside label location.
Update the graphql API accordingly.
- https://github.com/eclipse-sirius/sirius-web/issues/2444[#2444] [form] `ViewFormDescriptionConverterSwitch` now extends `FormSwitch<Optional<AbstractControlDescription>>`
- https://github.com/eclipse-sirius/sirius-web/issues/2516[#2516] [diagram] Add to the diagram core API the possibility to display the header separator when the inside label is a header.
It requires to add a `displayHeaderSeparatorProvider` to the _InsideLabelDescription_.
For the compatibility layer, the separator will always be displayed if the label is inside a node displaying its children has a list.
In a near future it will be possible to customize that value using the View DSL, but for now, the `displayHeaderSeparatorProvider` has the same value as `isHeaderProvider`.
Add the attribute `displayHeaderSeparator` to the graphql API.

=== Dependency update

Expand Down
Expand Up @@ -106,6 +106,7 @@ private NodeDescription createNodeDescription(String id) {
.textProvider(variableManager -> "")
.styleDescriptionProvider(variableManager -> styleDescription)
.isHeaderProvider(vm -> false)
.displayHeaderSeparatorProvider(vm -> false)
.insideLabelLocation(InsideLabelLocation.TOP_CENTER)
.build();

Expand Down
Expand Up @@ -199,6 +199,7 @@ private NodeDescription getNodeDescription(String nodeDescriptionId) {
.textProvider(variableManager -> "Node")
.styleDescriptionProvider(variableManager -> labelStyleDescription)
.isHeaderProvider(vm -> false)
.displayHeaderSeparatorProvider(vm -> false)
.insideLabelLocation(InsideLabelLocation.TOP_CENTER)
.build();

Expand Down
Expand Up @@ -107,6 +107,7 @@ public void initialize() {
.alignment(Position.at(0, 0))
.style(LabelStyle.newLabelStyle().color("").fontSize(0).iconURL(List.of()).build())
.isHeader(false)
.displayHeaderSeparator(false)
.build())
.style(ImageNodeStyle.newImageNodeStyle().imageURL("").scalingFactor(0).build())
.position(Position.at(0, 0))
Expand Down Expand Up @@ -176,6 +177,7 @@ private NodeDescription getNodeDescription(String nodeDescriptionId) {
.textProvider(variableManager -> "Node")
.styleDescriptionProvider(variableManager -> labelStyleDescription)
.isHeaderProvider(vm -> false)
.displayHeaderSeparatorProvider(vm -> false)
.insideLabelLocation(InsideLabelLocation.TOP_CENTER)
.build();

Expand Down
Expand Up @@ -90,6 +90,7 @@ public NodeDescription convert(AbstractNodeMapping abstractNodeMapping, AQLInter
.textProvider(labelExpressionProvider)
.styleDescriptionProvider(labelStyleDescriptionProvider)
.isHeaderProvider(isHeaderProvider)
.displayHeaderSeparatorProvider(isHeaderProvider)
.insideLabelLocation(InsideLabelLocation.TOP_CENTER)
.build();

Expand Down
Expand Up @@ -80,6 +80,7 @@ type InsideLabel {
position: Position!
size: Size!
isHeader: Boolean!
displayHeaderSeparator: Boolean!
}

enum InsideLabelLocation {
Expand Down
Expand Up @@ -109,6 +109,7 @@ private Node getNode(String id, String targetObjectId) {
.alignment(Position.UNDEFINED)
.style(labelStyle)
.isHeader(false)
.displayHeaderSeparator(false)
.build();

return Node.newNode(id)
Expand Down
Expand Up @@ -390,6 +390,7 @@ private Node createNode(String nodeId, String nodeDescriptionId, String targetOb
.alignment(Position.UNDEFINED)
.style(labelStyle)
.isHeader(false)
.displayHeaderSeparator(false)
.build();

return Node.newNode(nodeId)
Expand Down Expand Up @@ -427,6 +428,7 @@ private NodeDescription createNodeDescription(String nodeDescriptionId) {
.styleDescriptionProvider(vm -> styleDescription)
.textProvider(vm -> "")
.isHeaderProvider(vm -> false)
.displayHeaderSeparatorProvider(vm -> false)
.insideLabelLocation(InsideLabelLocation.TOP_CENTER)
.build();

Expand Down
Expand Up @@ -65,7 +65,6 @@ public Diagram getLayoutedDiagram(Diagram diagram, ElkNode elkDiagram, Map<Strin
Size size = Size.of(elkDiagram.getWidth(), elkDiagram.getHeight());
Position position = Position.at(elkDiagram.getX(), elkDiagram.getY());

// @formatter:off
List<Node> nodes = this.getLayoutedNodes(diagram.getNodes(), id2ElkGraphElements, layoutConfigurator);
List<Edge> edges = this.getLayoutedEdges(diagram.getEdges(), id2ElkGraphElements);

Expand All @@ -75,19 +74,16 @@ public Diagram getLayoutedDiagram(Diagram diagram, ElkNode elkDiagram, Map<Strin
.nodes(nodes)
.edges(edges)
.build();
// @formatter:on
}

private List<Node> getLayoutedNodes(List<Node> nodes, Map<String, ElkGraphElement> id2ElkGraphElements, ISiriusWebLayoutConfigurator layoutConfigurator) {
// @formatter:off
return nodes.stream().flatMap(node -> {
return Optional.ofNullable(id2ElkGraphElements.get(node.getId().toString()))
.filter(ElkConnectableShape.class::isInstance)
.map(ElkConnectableShape.class::cast)
.map(elkNode -> this.getLayoutedNode(node, elkNode, id2ElkGraphElements, layoutConfigurator))
.stream();
}).collect(Collectors.toUnmodifiableList());
// @formatter:on
}

private Node getLayoutedNode(Node node, ElkConnectableShape elkConnectableShape, Map<String, ElkGraphElement> id2ElkGraphElements, ISiriusWebLayoutConfigurator layoutConfigurator) {
Expand All @@ -103,7 +99,6 @@ private Node getLayoutedNode(Node node, ElkConnectableShape elkConnectableShape,
// Reset the "custom size" flag if the ELK layout decided on a different size.
customizedProperties = customizedProperties.stream().filter(property -> !CustomizableProperties.Size.equals(property)).collect(Collectors.toSet());
}
// @formatter:off
return Node.newNode(node)
.insideLabel(label)
.size(size)
Expand All @@ -112,19 +107,16 @@ private Node getLayoutedNode(Node node, ElkConnectableShape elkConnectableShape,
.borderNodes(borderNodes)
.customizedProperties(customizedProperties)
.build();
// @formatter:on
}

private List<Edge> getLayoutedEdges(List<Edge> edges, Map<String, ElkGraphElement> id2ElkGraphElements) {
// @formatter:off
return edges.stream().flatMap(edge -> {
return Optional.ofNullable(id2ElkGraphElements.get(edge.getId().toString()))
.filter(ElkEdge.class::isInstance)
.map(ElkEdge.class::cast)
.map(elkEdge -> this.getLayoutedEdge(edge, elkEdge, id2ElkGraphElements))
.stream();
}).collect(Collectors.toUnmodifiableList());
// @formatter:on
}

private Edge getLayoutedEdge(Edge edge, ElkEdge elkEdge, Map<String, ElkGraphElement> id2ElkGraphElements) {
Expand Down Expand Up @@ -183,7 +175,6 @@ private Edge getLayoutedEdge(Edge edge, ElkEdge elkEdge, Map<String, ElkGraphEle
endLabel = this.getLayoutedLabel(endLabel, id2ElkGraphElements, xOffset, yOffset);
}

// @formatter:off
return Edge.newEdge(edge)
.beginLabel(beginLabel)
.centerLabel(centerLabel)
Expand All @@ -192,7 +183,6 @@ private Edge getLayoutedEdge(Edge edge, ElkEdge elkEdge, Map<String, ElkGraphEle
.sourceAnchorRelativePosition(sourceAnchorRatio)
.targetAnchorRelativePosition(targetAnchorRatio)
.build();
// @formatter:on
}

private Ratio getSectionRatio(ElkNode node, double sectionX, double sectionY) {
Expand Down Expand Up @@ -228,7 +218,6 @@ private Label getLayoutedLabel(Label label, Map<String, ElkGraphElement> id2ElkG

Position position = Position.at(xOffset + elkLabel.getX(), yOffset + elkLabel.getY());

// @formatter:off
Position alignment = elkLabel.eAdapters().stream()
.findFirst()
.filter(AlignmentHolder.class::isInstance)
Expand All @@ -241,7 +230,6 @@ private Label getLayoutedLabel(Label label, Map<String, ElkGraphElement> id2ElkG
.position(position)
.alignment(alignment)
.build();
// @formatter:on
}
return layoutedLabel;
}
Expand All @@ -260,7 +248,6 @@ private InsideLabel getNodeLayoutedLabel(Node node, Map<String, ElkGraphElement>
nodeLabelType = this.elkPropertiesService.getNodeLabelType(node, layoutConfigurator);
}

// @formatter:off
Position position = Optional.of(elkLabel.getParent())
.filter(ElkNode.class::isInstance)
.map(ElkNode.class::cast)
Expand Down Expand Up @@ -294,7 +281,6 @@ private InsideLabel getNodeLayoutedLabel(Node node, Map<String, ElkGraphElement>
.position(position)
.alignment(alignment)
.build();
// @formatter:on
}
return layoutedInsideLabel;
}
Expand All @@ -304,12 +290,10 @@ private Position getAbsolutePosition(ElkNode node) {
Position absolutePosition = Position.at(node.getX(), node.getY());
while (currentNode.getParent() != null) {
currentNode = currentNode.getParent();
// @formatter:off
absolutePosition = Position.newPosition()
.x(absolutePosition.getX() + currentNode.getX())
.y(absolutePosition.getY() + currentNode.getY())
.build();
// @formatter:on
}
return absolutePosition;
}
Expand Down
Expand Up @@ -45,26 +45,22 @@ public Diagram getLayoutedDiagram(Diagram diagram, DiagramLayoutData diagramLayo
List<Node> nodes = this.getLayoutedNodes(diagram.getNodes(), id2LayoutData);
List<Edge> edges = this.getLayoutedEdges(diagram.getEdges(), id2LayoutData);

// @formatter:off
return Diagram.newDiagram(diagram)
.position(diagramLayoutData.getPosition())
.size(diagramLayoutData.getSize())
.nodes(nodes)
.edges(edges)
.build();
// @formatter:on
}

private List<Node> getLayoutedNodes(List<Node> nodes, Map<String, ILayoutData> id2LayoutData) {
// @formatter:off
return nodes.stream().flatMap(node -> {
return Optional.ofNullable(id2LayoutData.get(node.getId()))
.filter(NodeLayoutData.class::isInstance)
.map(NodeLayoutData.class::cast)
.map(nodeLayoutData -> this.getLayoutedNode(node, nodeLayoutData, id2LayoutData))
.stream();
}).collect(Collectors.toUnmodifiableList());
// @formatter:on
}

private Node getLayoutedNode(Node node, NodeLayoutData nodeLayoutData, Map<String, ILayoutData> id2LayoutData) {
Expand All @@ -79,7 +75,6 @@ private Node getLayoutedNode(Node node, NodeLayoutData nodeLayoutData, Map<Strin
} else {
customizableProperties.remove(CustomizableProperties.Size);
}
// @formatter:off
return Node.newNode(node)
.insideLabel(insideLabel)
.size(nodeLayoutData.getSize())
Expand All @@ -89,19 +84,16 @@ private Node getLayoutedNode(Node node, NodeLayoutData nodeLayoutData, Map<Strin
.borderNodes(borderNodes)
.customizedProperties(customizableProperties)
.build();
// @formatter:on
}

private List<Edge> getLayoutedEdges(List<Edge> edges, Map<String, ILayoutData> id2LayoutData) {
// @formatter:off
return edges.stream().flatMap(edge -> {
return Optional.ofNullable(id2LayoutData.get(edge.getId()))
.filter(EdgeLayoutData.class::isInstance)
.map(EdgeLayoutData.class::cast)
.map(edgeLayoutData -> this.getLayoutedEdge(edge, edgeLayoutData, id2LayoutData))
.stream();
}).collect(Collectors.toUnmodifiableList());
// @formatter:on
}

private Edge getLayoutedEdge(Edge edge, EdgeLayoutData edgeLayoutData, Map<String, ILayoutData> id2LayoutData) {
Expand All @@ -118,7 +110,6 @@ private Edge getLayoutedEdge(Edge edge, EdgeLayoutData edgeLayoutData, Map<Strin
endLabel = this.getLayoutedLabel(endLabel, id2LayoutData);
}

// @formatter:off
return Edge.newEdge(edge)
.beginLabel(beginLabel)
.centerLabel(centerLabel)
Expand All @@ -127,7 +118,6 @@ private Edge getLayoutedEdge(Edge edge, EdgeLayoutData edgeLayoutData, Map<Strin
.sourceAnchorRelativePosition(edgeLayoutData.getSourceAnchorRelativePosition())
.targetAnchorRelativePosition(edgeLayoutData.getTargetAnchorRelativePosition())
.build();
// @formatter:on
}

private Label getLayoutedLabel(Label label, Map<String, ILayoutData> id2LayoutData) {
Expand All @@ -136,14 +126,12 @@ private Label getLayoutedLabel(Label label, Map<String, ILayoutData> id2LayoutDa
if (optionalLabelLayoutData.isPresent()) {
LabelLayoutData labelLayoutData = optionalLabelLayoutData.get();

// @formatter:off
layoutedLabel = Label.newLabel(label)
.size(labelLayoutData.getTextBounds().getSize())
.position(labelLayoutData.getPosition())
.alignment(labelLayoutData.getTextBounds().getAlignment())
.type(labelLayoutData.getLabelType())
.build();
// @formatter:on
}
return layoutedLabel;
}
Expand Down
Expand Up @@ -421,6 +421,7 @@ private InsideLabelDescription getDefaultInsideLabelDescription() {
.build();
})
.isHeaderProvider(this.isHeaderProvider)
.displayHeaderSeparatorProvider(this.isHeaderProvider)
.insideLabelLocation(InsideLabelLocation.TOP_CENTER)
.build();
}
Expand Down
Expand Up @@ -110,6 +110,7 @@ public Node getNode(String id, boolean withLabel) {
.alignment(Position.UNDEFINED)
.style(labelStyle)
.isHeader(false)
.displayHeaderSeparator(false)
.build();
nodeBuilder.insideLabel(insideLabel);
}
Expand Down
Expand Up @@ -105,6 +105,7 @@ public NodeDescription getNodeDescription(String nodeDescriptionId, Function<Var
.textProvider(variableManager -> "Node")
.styleDescriptionProvider(variableManager -> labelStyleDescription)
.isHeaderProvider(vm -> false)
.displayHeaderSeparatorProvider(vm -> false)
.insideLabelLocation(InsideLabelLocation.TOP_CENTER)
.build();

Expand Down
Expand Up @@ -72,6 +72,7 @@ public InsideLabel basicInsideLabel(String text, LabelType labelType, boolean is
.size(Size.UNDEFINED)
.style(labelStyle)
.isHeader(isHeader)
.displayHeaderSeparator(isHeader)
.build();
}

Expand Down
Expand Up @@ -42,6 +42,8 @@ public final class InsideLabel {

private boolean isHeader;

private boolean displayHeaderSeparator;

private InsideLabel() {
// Prevent instantiation
}
Expand Down Expand Up @@ -82,6 +84,10 @@ public boolean isIsHeader() {
return this.isHeader;
}

public boolean isDisplayHeaderSeparator() {
return this.displayHeaderSeparator;
}

public static Builder newLabel(String id) {
return new Builder(id);
}
Expand Down Expand Up @@ -121,6 +127,8 @@ public static final class Builder {

private boolean isHeader;

private boolean displayHeaderSeparator;

private Builder(String id) {
this.id = Objects.requireNonNull(id);
}
Expand All @@ -135,6 +143,8 @@ public Builder(InsideLabel insideLabel) {
this.alignment = insideLabel.getAlignment();
this.style = insideLabel.getStyle();
this.isHeader = insideLabel.isIsHeader();
this.displayHeaderSeparator = insideLabel.isDisplayHeaderSeparator();

}

public Builder type(String type) {
Expand Down Expand Up @@ -177,6 +187,11 @@ public Builder isHeader(boolean isHeader) {
return this;
}

public Builder displayHeaderSeparator(boolean displayHeaderSeparator) {
this.displayHeaderSeparator = displayHeaderSeparator;
return this;
}

public InsideLabel build() {
InsideLabel label = new InsideLabel();
label.id = Objects.requireNonNull(this.id);
Expand All @@ -188,6 +203,7 @@ public InsideLabel build() {
label.alignment = Objects.requireNonNull(this.alignment);
label.style = Objects.requireNonNull(this.style);
label.isHeader = this.isHeader;
label.displayHeaderSeparator = this.displayHeaderSeparator;
return label;
}
}
Expand Down
Expand Up @@ -53,8 +53,10 @@ public Element render() {
String text = insideLabelDescription.getTextProvider().apply(variableManager);

boolean isHeader = insideLabelDescription.getIsHeaderProvider().apply(variableManager);
boolean displayHeaderSeparator = false;
if (isHeader) {
type = LabelType.INSIDE_CENTER.getValue();
displayHeaderSeparator = insideLabelDescription.getDisplayHeaderSeparatorProvider().apply(variableManager);
}

LabelStyleDescription labelStyleDescription = insideLabelDescription.getStyleDescriptionProvider().apply(variableManager);
Expand Down Expand Up @@ -91,6 +93,7 @@ public Element render() {
.alignment(aligment)
.style(labelStyle)
.isHeader(isHeader)
.displayHeaderSeparator(displayHeaderSeparator)
.build();
return new Element(InsideLabelElementProps.TYPE, insideLabelElementProps);
}
Expand Down

0 comments on commit 649a0be

Please sign in to comment.