Skip to content

Commit

Permalink
[596] Add Items in Interconnection View
Browse files Browse the repository at this point in the history
Bug: eclipse-syson#596
Signed-off-by: Gwendal Daniel <gwendal.daniel@obeosoft.com>
  • Loading branch information
gdaniel committed Jul 25, 2024
1 parent 73147cb commit a512c78
Show file tree
Hide file tree
Showing 19 changed files with 278 additions and 61 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ The second one shows a dialog allowing to select an existing _State_ to associat
The selected _State_ will be added to the diagram, not the new _ExhibitState_.
- https://github.com/eclipse-syson/syson/issues/587[#587] [interconnection-view] Handle _FlowConnectionUsage_ between _PortUsages_ in Interconnection View.
A new edge tool allows to create a flow between two ports.
- https://github.com/eclipse-syson/syson/issues/596[#596] [interconnection-view] Handle _ItemUsage_ in Interconnection View and _FlowConnectionUsage_ involving items

== v2024.7.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.eclipse.syson.diagram.interconnection.view.nodes.CompartmentNodeDescriptionProvider;
import org.eclipse.syson.diagram.interconnection.view.nodes.FakeNodeDescriptionProvider;
import org.eclipse.syson.diagram.interconnection.view.nodes.FirstLevelChildUsageNodeDescriptionProvider;
import org.eclipse.syson.diagram.interconnection.view.nodes.ItemUsageBorderNodeDescriptionProvider;
import org.eclipse.syson.diagram.interconnection.view.nodes.PortUsageBorderNodeDescriptionProvider;
import org.eclipse.syson.diagram.interconnection.view.nodes.RootNodeDescriptionProvider;
import org.eclipse.syson.diagram.interconnection.view.nodes.RootPortUsageBorderNodeDescriptionProvider;
Expand Down Expand Up @@ -106,6 +107,7 @@ public RepresentationDescription create(IColorProvider colorProvider) {
new ChildUsageNodeDescriptionProvider(SysmlPackage.eINSTANCE.getPerformActionUsage(), colorProvider, this.getDescriptionNameGenerator()),
new RootPortUsageBorderNodeDescriptionProvider("getPortUsages", colorProvider, this.getDescriptionNameGenerator()),
new PortUsageBorderNodeDescriptionProvider(colorProvider, this.getDescriptionNameGenerator()),
new ItemUsageBorderNodeDescriptionProvider(colorProvider, this.getDescriptionNameGenerator()),
new BindingConnectorAsUsageEdgeDescriptionProvider(colorProvider, this.getDescriptionNameGenerator()),
new AllocateEdgeDescriptionProvider(colorProvider, this.getDescriptionNameGenerator()),
new InterfaceUsageEdgeDescriptionProvider(colorProvider, this.getDescriptionNameGenerator()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,20 @@ public void link(DiagramDescription diagramDescription, IViewDiagramElementFinde
var optEdgeDescription = cache.getEdgeDescription(this.getName());
var optRootPortUsageBorderNodeDescription = cache.getNodeDescription(RootPortUsageBorderNodeDescriptionProvider.NAME);
var optPortUsageBorderNodeDescription = cache.getNodeDescription(this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage()));
var optItemUsageBorderNodeDescription = cache.getNodeDescription(this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage()));

if (optEdgeDescription.isPresent() && optRootPortUsageBorderNodeDescription.isPresent() && optPortUsageBorderNodeDescription.isPresent()) {
if (optEdgeDescription.isPresent()
&& optRootPortUsageBorderNodeDescription.isPresent()
&& optPortUsageBorderNodeDescription.isPresent()
&& optItemUsageBorderNodeDescription.isPresent()) {
EdgeDescription edgeDescription = optEdgeDescription.get();
diagramDescription.getEdgeDescriptions().add(edgeDescription);
edgeDescription.getSourceNodeDescriptions().add(optRootPortUsageBorderNodeDescription.get());
edgeDescription.getSourceNodeDescriptions().add(optPortUsageBorderNodeDescription.get());
edgeDescription.getSourceNodeDescriptions().add(optItemUsageBorderNodeDescription.get());
edgeDescription.getTargetNodeDescriptions().add(optRootPortUsageBorderNodeDescription.get());
edgeDescription.getTargetNodeDescriptions().add(optPortUsageBorderNodeDescription.get());
edgeDescription.getTargetNodeDescriptions().add(optItemUsageBorderNodeDescription.get());
edgeDescription.setPalette(this.createEdgePalette(List.of(this.createSourceReconnectTool(), this.createTargetReconnectTool())));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,17 @@ public void link(DiagramDescription diagramDescription, IViewDiagramElementFinde
var optEdgeDescription = cache.getEdgeDescription(this.getName());
var optRootPortUsageBorderNodeDescription = cache.getNodeDescription(RootPortUsageBorderNodeDescriptionProvider.NAME);
var optPortUsageBorderNodeDescription = cache.getNodeDescription(this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage()));
var optItemUsageBorderNodeDescription = cache.getNodeDescription(this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage()));

if (optEdgeDescription.isPresent() && optRootPortUsageBorderNodeDescription.isPresent() && optPortUsageBorderNodeDescription.isPresent()) {
EdgeDescription edgeDescription = optEdgeDescription.get();
diagramDescription.getEdgeDescriptions().add(edgeDescription);
edgeDescription.getSourceNodeDescriptions().add(optRootPortUsageBorderNodeDescription.get());
edgeDescription.getSourceNodeDescriptions().add(optPortUsageBorderNodeDescription.get());
edgeDescription.getSourceNodeDescriptions().add(optItemUsageBorderNodeDescription.get());
edgeDescription.getTargetNodeDescriptions().add(optRootPortUsageBorderNodeDescription.get());
edgeDescription.getTargetNodeDescriptions().add(optPortUsageBorderNodeDescription.get());
edgeDescription.getTargetNodeDescriptions().add(optItemUsageBorderNodeDescription.get());
edgeDescription.setPalette(this.createEdgePalette(List.of(this.createSourceReconnectTool(), this.createTargetReconnectTool())));
}
}
Expand All @@ -107,7 +110,7 @@ private EdgeStyle createEdgeStyle() {
.edgeWidth(1)
.lineStyle(LineStyle.SOLID)
.sourceArrowStyle(ArrowStyle.NONE)
.targetArrowStyle(ArrowStyle.NONE)
.targetArrowStyle(ArrowStyle.INPUT_FILL_CLOSED_ARROW)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,11 @@ public void link(DiagramDescription diagramDescription, IViewDiagramElementFinde
});

var optPortUsageBorderNodeDescription = cache.getNodeDescription(this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage()));

var optItemUsageBorderNodeDescription = cache.getNodeDescription(this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage()));
NodeDescription nodeDescription = optChildUsageNodeDescription.get();
nodeDescription.getReusedChildNodeDescriptions().addAll(reusedChildren);
nodeDescription.getReusedBorderNodeDescriptions().add(optPortUsageBorderNodeDescription.get());
nodeDescription.getReusedBorderNodeDescriptions().add(optItemUsageBorderNodeDescription.get());
nodeDescription.setPalette(this.createNodePalette(nodeDescription, cache));

List<NodeDescription> growableNodes = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ protected List<NodeDescription> getChildrenDescription(IViewDiagramElementFinder
});
cache.getNodeDescription(this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage()))
.ifPresent(childrenNodes::add);
cache.getNodeDescription(this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage()))
.ifPresent(childrenNodes::add);
cache.getNodeDescription(this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getActionUsage()))
.ifPresent(childrenNodes::add);
cache.getNodeDescription(this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getAcceptActionUsage()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,12 @@ public void link(DiagramDescription diagramDescription, IViewDiagramElementFinde
});

var optPortUsageBorderNodeDescription = cache.getNodeDescription(this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage()));
var optItemUsageBorderNodeDescription = cache.getNodeDescription(this.descriptionNameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage()));

NodeDescription nodeDescription = optChildUsageNodeDescription.get();
nodeDescription.getReusedChildNodeDescriptions().addAll(reusedChildren);
nodeDescription.getReusedBorderNodeDescriptions().add(optPortUsageBorderNodeDescription.get());
nodeDescription.getReusedBorderNodeDescriptions().add(optItemUsageBorderNodeDescription.get());
nodeDescription.setPalette(this.createNodePalette(cache));

List<NodeDescription> growableNodes = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/*******************************************************************************
* Copyright (c) 2023, 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.syson.diagram.interconnection.view.nodes;

import java.util.List;
import java.util.Objects;

import org.eclipse.sirius.components.diagrams.description.EdgeDescription;
import org.eclipse.sirius.components.view.builder.IViewDiagramElementFinder;
import org.eclipse.sirius.components.view.builder.providers.IColorProvider;
import org.eclipse.sirius.components.view.diagram.ConditionalNodeStyle;
import org.eclipse.sirius.components.view.diagram.DiagramDescription;
import org.eclipse.sirius.components.view.diagram.EdgeTool;
import org.eclipse.sirius.components.view.diagram.NodeDescription;
import org.eclipse.sirius.components.view.diagram.NodePalette;
import org.eclipse.sirius.components.view.diagram.NodeStyleDescription;
import org.eclipse.sirius.components.view.diagram.OutsideLabelDescription;
import org.eclipse.sirius.components.view.diagram.OutsideLabelPosition;
import org.eclipse.sirius.components.view.diagram.OutsideLabelStyle;
import org.eclipse.sirius.components.view.diagram.SynchronizationPolicy;
import org.eclipse.sirius.components.view.diagram.UserResizableDirection;
import org.eclipse.syson.diagram.common.view.nodes.AbstractNodeDescriptionProvider;
import org.eclipse.syson.sysml.SysmlPackage;
import org.eclipse.syson.util.AQLConstants;
import org.eclipse.syson.util.AQLUtils;
import org.eclipse.syson.util.IDescriptionNameGenerator;
import org.eclipse.syson.util.SysMLMetamodelHelper;
import org.eclipse.syson.util.ViewConstants;

/**
* Used to create the item usage border node description.
*
* @author gdaniel
*/
public class ItemUsageBorderNodeDescriptionProvider extends AbstractNodeDescriptionProvider {

private final IDescriptionNameGenerator nameGenerator;

public ItemUsageBorderNodeDescriptionProvider(IColorProvider colorProvider, IDescriptionNameGenerator nameGenerator) {
super(colorProvider);
this.nameGenerator = Objects.requireNonNull(nameGenerator);
}

@Override
public NodeDescription create() {
String domainType = SysMLMetamodelHelper.buildQualifiedName(SysmlPackage.eINSTANCE.getItemUsage());
return this.diagramBuilderHelper.newNodeDescription()
.defaultHeightExpression("10")
.defaultWidthExpression("10")
.domainType(domainType)
.outsideLabels(this.createOutsideLabelDescription())
.name(this.getName())
.semanticCandidatesExpression(AQLConstants.AQL_SELF + "." + SysmlPackage.eINSTANCE.getUsage_NestedItem().getName())
.style(this.createItemUnsetNodeStyle())
.conditionalStyles(this.createItemUsageConditionalNodeStyles().toArray(ConditionalNodeStyle[]::new))
.userResizable(UserResizableDirection.NONE)
.synchronizationPolicy(SynchronizationPolicy.SYNCHRONIZED)
.build();
}

@Override
public void link(DiagramDescription diagramDescription, IViewDiagramElementFinder cache) {
var optItemUsageBorderNodeDescription = cache.getNodeDescription(this.getName());

NodeDescription nodeDescription = optItemUsageBorderNodeDescription.get();
nodeDescription.setPalette(this.createNodePalette(cache, nodeDescription));
}

public String getName() {
return this.nameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getItemUsage());
}

private NodeStyleDescription createItemUnsetNodeStyle() {
return this.diagramBuilderHelper.newRectangularNodeStyleDescription()
.borderColor(this.colorProvider.getColor(ViewConstants.DEFAULT_BORDER_COLOR))
.borderRadius(0)
.background(this.colorProvider.getColor(ViewConstants.DEFAULT_BACKGROUND_COLOR))
.build();
}

private OutsideLabelDescription createOutsideLabelDescription() {
return this.diagramBuilderHelper.newOutsideLabelDescription()
.labelExpression(AQLUtils.getSelfServiceCallExpression("getBorderNodeUsageLabel"))
.position(OutsideLabelPosition.BOTTOM_CENTER)
.style(this.createOutsideLabelStyle())
.build();
}

private OutsideLabelStyle createOutsideLabelStyle() {
return this.diagramBuilderHelper.newOutsideLabelStyle()
.bold(false)
.borderSize(0)
.fontSize(12)
.italic(false)
.labelColor(this.colorProvider.getColor(ViewConstants.DEFAULT_LABEL_COLOR))
.showIconExpression("aql:false")
.strikeThrough(false)
.underline(false)
.build();
}

private List<ConditionalNodeStyle> createItemUsageConditionalNodeStyles() {
var borderColor = this.colorProvider.getColor(ViewConstants.DEFAULT_BORDER_COLOR);
return List.of(
this.diagramBuilderHelper.newConditionalNodeStyle()
.condition(AQLUtils.getSelfServiceCallExpression("isInFeature"))
.style(this.createImageNodeStyleDescription("/images/Feature_In.svg", borderColor, true))
.build(),
this.diagramBuilderHelper.newConditionalNodeStyle()
.condition(AQLUtils.getSelfServiceCallExpression("isOutFeature"))
.style(this.createImageNodeStyleDescription("/images/Feature_Out.svg", borderColor, true))
.build(),
this.diagramBuilderHelper.newConditionalNodeStyle()
.condition(AQLUtils.getSelfServiceCallExpression("isInOutFeature"))
.style(this.createImageNodeStyleDescription("/images/Feature_Inout.svg", borderColor, true))
.build()
);
}

private NodePalette createNodePalette(IViewDiagramElementFinder cache, NodeDescription nodeDescription) {
var changeContext = this.viewBuilderHelper.newChangeContext()
.expression(AQLUtils.getSelfServiceCallExpression("deleteFromModel"));

var deleteTool = this.diagramBuilderHelper.newDeleteTool()
.name("Delete from Model")
.body(changeContext.build());

var callEditService = this.viewBuilderHelper.newChangeContext()
.expression(AQLUtils.getSelfServiceCallExpression("directEdit", "newLabel"));

var editTool = this.diagramBuilderHelper.newLabelEditTool()
.name("Edit")
.initialDirectEditLabelExpression(AQLUtils.getSelfServiceCallExpression("getDefaultInitialDirectEditLabel"))
.body(callEditService.build());

NodeDescription portBorderNodeDescription = cache.getNodeDescription(this.nameGenerator.getBorderNodeName(SysmlPackage.eINSTANCE.getPortUsage())).get();
NodeDescription rootPortBorderNode = cache.getNodeDescription(RootPortUsageBorderNodeDescriptionProvider.NAME).get();

return this.diagramBuilderHelper.newNodePalette()
.deleteTool(deleteTool.build())
.labelEditTool(editTool.build())
.toolSections(this.defaultToolsFactory.createDefaultHideRevealNodeToolSection())
.edgeTools(
this.createBindingConnectorAsUsageEdgeTool(List.of(nodeDescription)),
this.createFlowConnectionUsageEdgeTool(List.of(nodeDescription, portBorderNodeDescription, rootPortBorderNode)))
.build();
}

private EdgeTool createBindingConnectorAsUsageEdgeTool(List<NodeDescription> targetElementDescriptions) {
var builder = this.diagramBuilderHelper.newEdgeTool();

var body = this.viewBuilderHelper.newChangeContext()
.expression(AQLUtils.getServiceCallExpression(EdgeDescription.SEMANTIC_EDGE_SOURCE, "createBindingConnectorAsUsage", EdgeDescription.SEMANTIC_EDGE_TARGET));

return builder
.name(this.nameGenerator.getCreationToolName(SysmlPackage.eINSTANCE.getBindingConnectorAsUsage()))
.iconURLsExpression("/icons/full/obj16/" + SysmlPackage.eINSTANCE.getBindingConnectorAsUsage().getName() + ".svg")
.body(body.build())
.targetElementDescriptions(targetElementDescriptions.toArray(NodeDescription[]::new))
.build();
}

private EdgeTool createFlowConnectionUsageEdgeTool(List<NodeDescription> targetElementDescriptions) {
var builder = this.diagramBuilderHelper.newEdgeTool();

var body = this.viewBuilderHelper.newChangeContext()
.expression(AQLUtils.getServiceCallExpression(EdgeDescription.SEMANTIC_EDGE_SOURCE, "createFlowConnectionUsage", EdgeDescription.SEMANTIC_EDGE_TARGET));

return builder
.name(this.nameGenerator.getCreationToolName(SysmlPackage.eINSTANCE.getFlowConnectionUsage()))
.iconURLsExpression("/icons/full/obj16/" + SysmlPackage.eINSTANCE.getFlowConnectionUsage().getName() + ".svg")
.body(body.build())
.targetElementDescriptions(targetElementDescriptions.toArray(NodeDescription[]::new))
.build();
}
}
Loading

0 comments on commit a512c78

Please sign in to comment.