Skip to content

Commit d10143b

Browse files
committed
[6060] Add new ClosedArrowWith4Dots edge marker
Bug: #6060 Signed-off-by: Axel RICHARD <axel.richard@obeo.fr>
1 parent 4f05c0d commit d10143b

File tree

17 files changed

+195
-51
lines changed

17 files changed

+195
-51
lines changed

CHANGELOG.adoc

Lines changed: 17 additions & 14 deletions
Large diffs are not rendered by default.

packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/i18n/en/sirius-components-diagrams.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@
135135
"close": "Close"
136136
},
137137
"manageVisibilityModalMenuCheckBox": {
138-
"all": "All"
138+
"all": "All"
139139
},
140140
"labelAppearancePart": {
141141
"hide": "Hide",
@@ -201,7 +201,8 @@
201201
"fillCircle": "Fill Circle",
202202
"crossedCircle": "Crossed Circle",
203203
"closedArrowWithVerticalBar": "Closed Arrow with Vertical Bar",
204-
"closedArrowWithDots": "Closed Arrow with Dots",
204+
"closedArrowWithDots": "Closed Arrow with two Dots",
205+
"closedArrowWith4Dots": "Closed Arrow with four Dots",
205206
"manhattan": "Manhattan",
206207
"smartManhattan": "Smart Manhattan",
207208
"oblique": "Oblique",

packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/i18n/fr/sirius-components-diagrams.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@
135135
"close": "Fermer"
136136
},
137137
"manageVisibilityModalMenuCheckBox": {
138-
"all": "Tous"
138+
"all": "Tous"
139139
},
140140
"labelAppearancePart": {
141141
"hide": "Masquer",
@@ -201,7 +201,8 @@
201201
"fillCircle": "Cercle plein",
202202
"crossedCircle": "Cercle croisé",
203203
"closedArrowWithVerticalBar": "Flèche de sortie avec barre verticale",
204-
"closedArrowWithDots": "Flèche de sortie avec points",
204+
"closedArrowWithDots": "Flèche de sortie avec deux points",
205+
"closedArrowWith4Dots": "Flèche de sortie avec quatre points",
205206
"manhattan": "Manhattan",
206207
"smartManhattan": "Manhattan intelligent",
207208
"oblique": "Oblique",

packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/schema/diagram.graphqls

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ enum ArrowStyle {
342342
CrossedCircle
343343
ClosedArrowWithVerticalBar
344344
ClosedArrowWithDots
345+
ClosedArrowWith4Dots
345346
}
346347

347348
enum EdgeType {

packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/ArrowStyle.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2019, 2023 Obeo.
2+
* Copyright (c) 2019, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -18,5 +18,5 @@
1818
* @author hmarchadour
1919
*/
2020
public enum ArrowStyle {
21-
None, OutputArrow, InputArrow, OutputClosedArrow, InputClosedArrow, OutputFillClosedArrow, InputFillClosedArrow, Diamond, FillDiamond, InputArrowWithDiamond, InputArrowWithFillDiamond, Circle, FillCircle, CrossedCircle, ClosedArrowWithVerticalBar, ClosedArrowWithDots
21+
None, OutputArrow, InputArrow, OutputClosedArrow, InputClosedArrow, OutputFillClosedArrow, InputFillClosedArrow, Diamond, FillDiamond, InputArrowWithDiamond, InputArrowWithFillDiamond, Circle, FillCircle, CrossedCircle, ClosedArrowWithVerticalBar, ClosedArrowWithDots, ClosedArrowWith4Dots
2222
}

packages/diagrams/frontend/sirius-components-diagrams/src/renderer/edge/MarkerDefinitions.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2023, 2025 Obeo.
2+
* Copyright (c) 2023, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -94,6 +94,8 @@ const getMarker = (markerProps: MarkerProps) => {
9494
return <ClosedArrowWithVerticalBar {...markerProps} key={markerProps.id} />;
9595
case 'ClosedArrowWithDots':
9696
return <ClosedArrowWithDots {...markerProps} key={markerProps.id} />;
97+
case 'ClosedArrowWith4Dots':
98+
return <ClosedArrowWith4Dots {...markerProps} key={markerProps.id} />;
9799
default:
98100
return <InputFillClosedArrow {...markerProps} key={markerProps.id} />;
99101
}
@@ -291,6 +293,25 @@ const ClosedArrowWithDots = ({ id, edgeColor }: MarkerProps) => {
291293
);
292294
};
293295

296+
const ClosedArrowWith4Dots = ({ id, edgeColor }: MarkerProps) => {
297+
const theme = useTheme();
298+
const strokeColor: string = getSelectedColor(id, edgeColor, theme);
299+
return (
300+
<marker {...buildMarkerAttributes(id, 15, 10, 14, 5)}>
301+
<path
302+
strokeWidth={1}
303+
fill={theme.palette.background.default}
304+
d={'m 7 1 L 14 5 L 7 9 L 7 1 z'}
305+
stroke={strokeColor}
306+
/>
307+
<circle r={1} cx={1} cy={2} fill={strokeColor} stroke={'none'} />
308+
<circle r={1} cx={1} cy={8} fill={strokeColor} stroke={'none'} />
309+
<circle r={1} cx={4} cy={2} fill={strokeColor} stroke={'none'} />
310+
<circle r={1} cx={4} cy={8} fill={strokeColor} stroke={'none'} />
311+
</marker>
312+
);
313+
};
314+
294315
const getSelectedColor = (id: string, edgeColor: string, theme: Theme): string => {
295316
const selectedColor: string =
296317
id.endsWith('--selected') && theme.palette.selected ? theme.palette.selected : getCSSColor(edgeColor, theme);

packages/diagrams/frontend/sirius-components-diagrams/src/renderer/palette/appearance/edge/EdgeAppearancePart.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ const getArrowOption = (t: TFunction) => [
5757
{ value: 'CrossedCircle', label: t('crossedCircle') },
5858
{ value: 'ClosedArrowWithVerticalBar', label: t('closedArrowWithVerticalBar') },
5959
{ value: 'ClosedArrowWithDots', label: t('closedArrowWithDots') },
60+
{ value: 'ClosedArrowWith4Dots', label: t('closedArrowWith4Dots') },
6061
];
6162

6263
const getEdgeTypeOptions = (t: TFunction) => [

packages/sirius-web/backend/sirius-web/src/test/java/org/eclipse/sirius/web/application/controllers/views/DiagramViewControllerIntegrationTests.java

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2024, 2025 Obeo.
2+
* Copyright (c) 2024, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -26,8 +26,12 @@
2626

2727
import org.eclipse.sirius.components.collaborative.dto.CreateChildInput;
2828
import org.eclipse.sirius.components.collaborative.dto.CreateChildSuccessPayload;
29+
import org.eclipse.sirius.components.collaborative.forms.dto.EditSelectInput;
2930
import org.eclipse.sirius.components.collaborative.forms.dto.FormRefreshedEventPayload;
31+
import org.eclipse.sirius.components.core.api.SuccessPayload;
3032
import org.eclipse.sirius.components.forms.AbstractWidget;
33+
import org.eclipse.sirius.components.forms.Select;
34+
import org.eclipse.sirius.components.forms.tests.graphql.EditSelectMutationRunner;
3135
import org.eclipse.sirius.web.AbstractIntegrationTests;
3236
import org.eclipse.sirius.web.application.views.details.dto.DetailsEventInput;
3337
import org.eclipse.sirius.web.data.StudioIdentifiers;
@@ -61,6 +65,9 @@ public class DiagramViewControllerIntegrationTests extends AbstractIntegrationTe
6165
@Autowired
6266
private CreateChildMutationRunner createChildMutationRunner;
6367

68+
@Autowired
69+
private EditSelectMutationRunner editSelectMutationRunner;
70+
6471
@Autowired
6572
private DetailsEventSubscriptionRunner detailsEventSubscriptionRunner;
6673

@@ -149,4 +156,96 @@ public void givenAViewWhenADiagramDescriptionIsCreatedThenItIsCreatedProperly()
149156
}
150157

151158

159+
@Test
160+
@GivenSiriusWebServer
161+
@DisplayName("Given a diagram description, when an edge style is edited, then it is possible to select the ClosedArrowWith4Dots arrow style")
162+
public void givenADiagramDescriptionWhenAEdgeStyleIsEditedThenItIsPossibleToSelectTheClosedArrowWith4DotsArrowStyle() {
163+
var objectId = "a2a3713f-57bc-422b-92e8-b22ed69e94a8"; // The edge style of the sample studio
164+
var detailsRepresentationId = this.representationIdBuilder.buildDetailsRepresentationId(List.of(objectId));
165+
var input = new DetailsEventInput(UUID.randomUUID(), StudioIdentifiers.SAMPLE_STUDIO_EDITING_CONTEXT_ID, detailsRepresentationId);
166+
var flux = this.detailsEventSubscriptionRunner.run(input)
167+
.flux()
168+
.filter(FormRefreshedEventPayload.class::isInstance);
169+
170+
var sourceArrowStyleWidgetId = new AtomicReference<String>();
171+
var targetArrowStyleWidgetId = new AtomicReference<String>();
172+
var closedArrowWith4DotsValue = new AtomicReference<String>();
173+
174+
Consumer<Object> formContentBeforeEdit = assertRefreshedFormThat(form -> {
175+
var firstPage = form.getPages().get(0);
176+
var firstGroup = firstPage.getGroups().get(0);
177+
var sourceArrowStyleWidget = firstGroup.getWidgets().stream()
178+
.filter(Select.class::isInstance)
179+
.map(Select.class::cast)
180+
.filter(selectWidget -> Objects.equals("Source Arrow Style", selectWidget.getLabel()))
181+
.findFirst();
182+
assertThat(sourceArrowStyleWidget).isPresent();
183+
assertThat(sourceArrowStyleWidget.get().getValue()).isEqualTo("0");
184+
var sourceArrowStyleWidgetOptions = sourceArrowStyleWidget.get().getOptions();
185+
var optClosedArrowWith4Dots = sourceArrowStyleWidgetOptions.stream()
186+
.filter(selectOption -> Objects.equals("ClosedArrowWith4Dots", selectOption.getLabel()))
187+
.findFirst();
188+
assertThat(optClosedArrowWith4Dots).isPresent();
189+
sourceArrowStyleWidgetId.set(sourceArrowStyleWidget.get().getId());
190+
closedArrowWith4DotsValue.set(optClosedArrowWith4Dots.get().getId());
191+
192+
var targetArrowStyleWidget = firstGroup.getWidgets().stream()
193+
.filter(Select.class::isInstance)
194+
.map(Select.class::cast)
195+
.filter(selectWidget -> Objects.equals("Target Arrow Style", selectWidget.getLabel()))
196+
.findFirst();
197+
assertThat(targetArrowStyleWidget).isPresent();
198+
assertThat(targetArrowStyleWidget.get().getValue()).isEqualTo("2");
199+
assertThat(targetArrowStyleWidget.get().getOptions()).anyMatch(selectOption -> Objects.equals("ClosedArrowWith4Dots", selectOption.getLabel()));
200+
targetArrowStyleWidgetId.set(targetArrowStyleWidget.get().getId());
201+
});
202+
203+
Runnable editSourceArrowStyle = () -> {
204+
var editSelectSourceArrowStyleInput = new EditSelectInput(UUID.randomUUID(), StudioIdentifiers.SAMPLE_STUDIO_EDITING_CONTEXT_ID, detailsRepresentationId, sourceArrowStyleWidgetId.get(), closedArrowWith4DotsValue.get());
205+
var result = this.editSelectMutationRunner.run(editSelectSourceArrowStyleInput);
206+
var typename = JsonPath.read(result.data(), "$.data.editSelect.__typename");
207+
assertThat(typename).isEqualTo(SuccessPayload.class.getSimpleName());
208+
};
209+
210+
Consumer<Object> formContentAfterSourceArrowStyleEdit = assertRefreshedFormThat(form -> {
211+
var firstPage = form.getPages().get(0);
212+
var firstGroup = firstPage.getGroups().get(0);
213+
var sourceArrowStyleWidget = firstGroup.getWidgets().stream()
214+
.filter(Select.class::isInstance)
215+
.map(Select.class::cast)
216+
.filter(selectWidget -> Objects.equals("Source Arrow Style", selectWidget.getLabel()))
217+
.findFirst();
218+
assertThat(sourceArrowStyleWidget).isPresent();
219+
assertThat(sourceArrowStyleWidget.get().getValue()).isEqualTo(closedArrowWith4DotsValue.get());
220+
});
221+
222+
Runnable editTargetArrowStyle = () -> {
223+
var editSelectTargetArrowStyleInput = new EditSelectInput(UUID.randomUUID(), StudioIdentifiers.SAMPLE_STUDIO_EDITING_CONTEXT_ID, detailsRepresentationId, targetArrowStyleWidgetId.get(), closedArrowWith4DotsValue.get());
224+
var result = this.editSelectMutationRunner.run(editSelectTargetArrowStyleInput);
225+
var typename = JsonPath.read(result.data(), "$.data.editSelect.__typename");
226+
assertThat(typename).isEqualTo(SuccessPayload.class.getSimpleName());
227+
};
228+
229+
Consumer<Object> formContentAfterTargetArrowStyleEdit = assertRefreshedFormThat(form -> {
230+
var firstPage = form.getPages().get(0);
231+
var firstGroup = firstPage.getGroups().get(0);
232+
233+
var targetArrowStyleWidget = firstGroup.getWidgets().stream()
234+
.filter(Select.class::isInstance)
235+
.map(Select.class::cast)
236+
.filter(selectWidget -> Objects.equals("Target Arrow Style", selectWidget.getLabel()))
237+
.findFirst();
238+
assertThat(targetArrowStyleWidget).isPresent();
239+
assertThat(targetArrowStyleWidget.get().getValue()).isEqualTo(closedArrowWith4DotsValue.get());
240+
});
241+
242+
StepVerifier.create(flux)
243+
.consumeNextWith(formContentBeforeEdit)
244+
.then(editSourceArrowStyle)
245+
.consumeNextWith(formContentAfterSourceArrowStyleEdit)
246+
.then(editTargetArrowStyle)
247+
.consumeNextWith(formContentAfterTargetArrowStyleEdit)
248+
.thenCancel()
249+
.verify(Duration.ofSeconds(100));
250+
}
152251
}

packages/view/backend/sirius-components-view-diagram-edit/src/main/java/org/eclipse/sirius/components/view/diagram/provider/FreeFormLayoutStrategyDescriptionItemProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2021, 2025 Obeo.
2+
* Copyright (c) 2021, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -88,7 +88,7 @@ protected void addOnWestAtCreationBorderNodesPropertyDescriptor(Object object) {
8888
protected ItemPropertyDescriptor createItemPropertyDescriptor(AdapterFactory adapterFactory, ResourceLocator resourceLocator, String displayName, String description, EStructuralFeature feature,
8989
boolean isSettable, boolean multiLine, boolean sortChoices, Object staticImage, String category, String[] filterFlags) {
9090
if (List.of(DiagramPackage.Literals.LAYOUT_STRATEGY_DESCRIPTION__ON_WEST_AT_CREATION_BORDER_NODES, DiagramPackage.Literals.LAYOUT_STRATEGY_DESCRIPTION__ON_EAST_AT_CREATION_BORDER_NODES,
91-
DiagramPackage.Literals.LAYOUT_STRATEGY_DESCRIPTION__ON_SOUTH_AT_CREATION_BORDER_NODES, DiagramPackage.Literals.LAYOUT_STRATEGY_DESCRIPTION__ON_NORTH_AT_CREATION_BORDER_NODES)
91+
DiagramPackage.Literals.LAYOUT_STRATEGY_DESCRIPTION__ON_SOUTH_AT_CREATION_BORDER_NODES, DiagramPackage.Literals.LAYOUT_STRATEGY_DESCRIPTION__ON_NORTH_AT_CREATION_BORDER_NODES)
9292
.contains(feature)) {
9393
return new ItemPropertyDescriptor(adapterFactory, resourceLocator, displayName, description, feature, isSettable, multiLine, sortChoices, staticImage, category, filterFlags, null) {
9494
@Override

packages/view/backend/sirius-components-view-diagram-edit/src/main/java/org/eclipse/sirius/components/view/diagram/provider/ListLayoutStrategyDescriptionItemProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2021, 2025 Obeo.
2+
* Copyright (c) 2021, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -94,7 +94,7 @@ protected void addOnWestAtCreationBorderNodesPropertyDescriptor(Object object) {
9494
protected ItemPropertyDescriptor createItemPropertyDescriptor(AdapterFactory adapterFactory, ResourceLocator resourceLocator, String displayName, String description, EStructuralFeature feature,
9595
boolean isSettable, boolean multiLine, boolean sortChoices, Object staticImage, String category, String[] filterFlags) {
9696
if (List.of(DiagramPackage.Literals.LAYOUT_STRATEGY_DESCRIPTION__ON_WEST_AT_CREATION_BORDER_NODES, DiagramPackage.Literals.LAYOUT_STRATEGY_DESCRIPTION__ON_EAST_AT_CREATION_BORDER_NODES,
97-
DiagramPackage.Literals.LAYOUT_STRATEGY_DESCRIPTION__ON_SOUTH_AT_CREATION_BORDER_NODES, DiagramPackage.Literals.LAYOUT_STRATEGY_DESCRIPTION__ON_NORTH_AT_CREATION_BORDER_NODES)
97+
DiagramPackage.Literals.LAYOUT_STRATEGY_DESCRIPTION__ON_SOUTH_AT_CREATION_BORDER_NODES, DiagramPackage.Literals.LAYOUT_STRATEGY_DESCRIPTION__ON_NORTH_AT_CREATION_BORDER_NODES)
9898
.contains(feature)) {
9999
return new ItemPropertyDescriptor(adapterFactory, resourceLocator, displayName, description, feature, isSettable, multiLine, sortChoices, staticImage, category, filterFlags, null) {
100100
@Override

0 commit comments

Comments
 (0)