Home » Eclipse Projects » Sirius » [Sirius-ELK] Wrong layout result with show/hide ports operation
[Sirius-ELK] Wrong layout result with show/hide ports operation [message #1795243] |
Wed, 19 September 2018 06:44 |
lee lucky Messages: 26 Registered: October 2017 |
Junior Member |
|
|
Hi,
I am using layered algorithm to layout my diagram in Sirius editor.
When I do the following operations, I found the layout result is wrong:
Steps
1). Execute layered algorithm on my diagram in Sirius editor, it works well.
2). Hide ports.
3). Relayout on this diagram after doing 2), it works well, too.
4). Show these hidden ports.
5). Execute layered layout on this diagram again.
The result in step 5) is messed-up, it looks like these ports which are shown after hidden are not placed in their places. But, when I close this diagram, and then reopen it, the diagram is shown well as the step 1) shows.
Analyse
I check ELK's source codes in GmfLayoutCommand.java file of project "org.eclipse.sirius.diagram.elk".
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info)
throws ExecutionException {
monitor.beginTask(getLabel(), 1);
// process shape layout data
for (ShapeLayoutData shapeLayout : shapeLayouts) {
// set new location of the element
if (shapeLayout.location != null) {
ViewUtil.setStructuralFeatureValue(shapeLayout.view, NotationPackage.eINSTANCE.getLocation_X(),
Integer.valueOf(shapeLayout.location.x));
ViewUtil.setStructuralFeatureValue(shapeLayout.view, NotationPackage.eINSTANCE.getLocation_Y(),
Integer.valueOf(shapeLayout.location.y));
}
// set new size of the element
if (shapeLayout.size != null) {
ViewUtil.setStructuralFeatureValue(shapeLayout.view, NotationPackage.eINSTANCE.getSize_Width(),
Integer.valueOf(shapeLayout.size.width));
ViewUtil.setStructuralFeatureValue(shapeLayout.view, NotationPackage.eINSTANCE.getSize_Height(),
Integer.valueOf(shapeLayout.size.height));
}
}
shapeLayouts.clear();
......
The ELK layout results are saved by this method, and due to the changes of ports' position and size, the corresponding refreshBounds method will be called in AbstractBorderItemEditPart.java.
protected void refreshBounds() {
if (getBorderItemLocator() != null) {
int x = ((Integer) getStructuralFeatureValue(NotationPackage.eINSTANCE
.getLocation_X())).intValue();
int y = ((Integer) getStructuralFeatureValue(NotationPackage.eINSTANCE
.getLocation_Y())).intValue();
Point loc = new Point(x, y);
int width = ((Integer) getStructuralFeatureValue(NotationPackage.eINSTANCE.getSize_Width())).intValue();
int height = ((Integer) getStructuralFeatureValue(NotationPackage.eINSTANCE.getSize_Height())).intValue();
Dimension size = new Dimension(width, height);
[color=red][b]getBorderItemLocator().setConstraint(new Rectangle(
loc, size));[/b][/color]
} else {
super.refreshBounds();
}
}]
The position and size set in method doExecuteWithResult is the input in getBorderItemLocator().setConstraint(new Rectangle(loc, size)).
In sirius, the relocate method in DBorderItemLocator.java is called to relocate ports on their parents.
@Override
public void relocate(final IFigure borderItem) {
Rectangle parentBounds = getParentFigure().getBounds().getCopy();
// If the relocate is called before that the figure have been
// "initialized", it is by-passed.
if (!(parentBounds.x == 0 && parentBounds.y == 0 && parentBounds.width <= 0 && parentBounds.height <= 0)) {
final Dimension size = getSize(borderItem);
final Rectangle rectSuggested = new Rectangle(getPreferredLocation(borderItem), size);
BitSet authorizedSides = getAuthorizedSides(borderItem);
// If the border item has moved, we change the preferred side,
// otherwise we let the current side enabled
if (borderItemHasMoved) {
final int closestSide = DBorderItemLocator.findClosestSideOfParent(rectSuggested, getParentBorder(),
authorizedSides);
setPreferredSideOfParent(closestSide);
borderItemHasMoved = false;
} else {
// We use the notion if figuresToIgnoreDuringNextRelocate only
// if bordered node is moved.
figuresToIgnoreDuringNextRelocate.clear();
}
Point ptNewLocation = locateOnBorder(rectSuggested, getCurrentSideOfParent(),
NB_SIDES - getNumberOfAuthorizedSides(authorizedSides), borderItem,
figuresToIgnoreDuringNextRelocate, new ArrayList<IFigure>());
borderItem.setLocation(ptNewLocation);
figuresToIgnoreDuringNextRelocate.clear();
borderItem.setSize(size);
this.located = true;
}
}
The field borderItemHasMoved is false which is set by the method called setConstraint in DBorderItemLocator.java
@Override
public void setConstraint(final Rectangle theConstraint) {
if (!theConstraint.equals(getConstraint())) {
borderItemHasMoved = true;
}
super.setConstraint(theConstraint);
}
Therefore, in method relocate, borderItemHasMoved is false, the position and size are kept in the old ones, the ports are not relocated with their new values. This is why the result in step 5) is messed up as step 4) does. And these new values will be taken effect after reopen the diagram.
I want to fix this problem, Can you give some suggestions?
Hope for your reply, and thanks in advance.
|
|
| | | | | | | |
Re: [Sirius-ELK] Wrong layout result with show/hide ports operation [message #1796720 is a reply to message #1796625] |
Thu, 18 October 2018 06:53 |
lee lucky Messages: 26 Registered: October 2017 |
Junior Member |
|
|
Hi,
Quote:Last question are you using option override for the ELK layout algorithm you defined?
yes, I used the old way to configure my layered algorithm.
private void configLayered(LayoutConfigurator layoutConfigurator, LayoutMapping layoutMapping) {
layoutConfigurator.configure(ElkNode.class)
.setProperty(LayeredOptions.PORT_LABELS_PLACEMENT, PortLabelPlacement.INSIDE)
.setProperty(LayeredOptions.PORT_CONSTRAINTS, PortConstraints.UNDEFINED)
.setProperty(LayeredOptions.NODE_SIZE_OPTIONS,
EnumSet.of(SizeOptions.MINIMUM_SIZE_ACCOUNTS_FOR_PADDING))
.setProperty(LayeredOptions.NODE_SIZE_CONSTRAINTS, EnumSet.allOf(SizeConstraint.class))
.setProperty(LayeredOptions.NODE_LABELS_PLACEMENT, NodeLabelPlacement.insideTopCenter())
.setProperty(LayeredOptions.MERGE_EDGES, true).setProperty(LayeredOptions.MERGE_HIERARCHY_EDGES, true)
.setProperty(LayeredOptions.HIERARCHY_HANDLING, HierarchyHandling.INCLUDE_CHILDREN)
.setProperty(LayeredOptions.CROSSING_MINIMIZATION_GREEDY_SWITCH_TYPE, GreedySwitchType.OFF)
.setProperty(LayeredOptions.CONTENT_ALIGNMENT, ContentAlignment.topLeft())
.setProperty(LayeredOptions.EDGE_LABEL_SIDE_SELECTION, EdgeLabelSideSelection.ALWAYS_DOWN)
.setProperty(LayeredOptions.SPACING_NODE_NODE, 10.0).setProperty(LayeredOptions.SPACING_PORT_PORT, 30.0)
.setProperty(LayeredOptions.SPACING_EDGE_EDGE, 20.0).setProperty(LayeredOptions.THOROUGHNESS, 1)
.setProperty(LayeredOptions.SPACING_LABEL_LABEL, 20.0)
.setProperty(LayeredOptions.SPACING_EDGE_LABEL, 5.0)
.setProperty(LayeredOptions.INSIDE_SELF_LOOPS_ACTIVATE, true);
layoutConfigurator.configure(ElkEdge.class).setProperty(LayeredOptions.INSIDE_SELF_LOOPS_YO, true);
}
I called this function in method layoutEditParts of ELKLayoutNodeProvider.java.
public Command layoutEditParts(final List selectedObjects, final IAdaptable layoutHint) {
.........
ElkDiagramLayoutConnector connector = injector.getInstance(ElkDiagramLayoutConnector.class);
LayoutMapping layoutMapping = connector.buildLayoutGraph(null, container.getParent());
configLayered();
......
}
I am sorry that my company can't access to bugzilla recently, so I can't trace the ticket in bugzilla.
|
|
|
Goto Forum:
Current Time: Mon Jun 10 10:13:37 GMT 2024
Powered by FUDForum. Page generated in 0.04180 seconds
|