use of org.osate.ge.internal.diagram.runtime.DiagramNodePredicates in project osate2 by osate.
the class DiagramElementLayoutUtil method layoutIncrementally.
/**
* Performs layout on elements in the specified diagram which have not been laid out.
* @param diagram the diagram for which to perform the incremental layout
* @param mod the modification to use to modify the diagram
* @param layoutInfoProvider the layout info provider which provides additional information required for laying out the diagram
*/
public static void layoutIncrementally(final AgeDiagram diagram, final DiagramModification mod, final LayoutInfoProvider layoutInfoProvider) {
Objects.requireNonNull(diagram, "diagram must not be null");
Objects.requireNonNull(mod, "mod must not be null");
Objects.requireNonNull(layoutInfoProvider, "layoutInfoProvider must not be null");
final IncrementalLayoutMode currentLayoutMode = LayoutPreferences.getCurrentIncrementalLayoutMode();
// Get all the nodes that need to be layed out.
final Set<DiagramNode> unfilteredNodesToLayout = getNodesToLayoutIncrementally(diagram, currentLayoutMode, new HashSet<>());
if (unfilteredNodesToLayout.size() == 0) {
return;
}
// Lay our flow indicators. In the container is eventually layed out, this will be replaced but in cases where that is not the case,
// we provide a default layout. Flow indicators are connections and as such will be filtered in the next step.
layoutFlowIndicators(mod, unfilteredNodesToLayout.stream().filter(DiagramNodePredicates::isFlowIndicator).map(DiagramElement.class::cast), layoutInfoProvider);
final Collection<DiagramNode> nodesToLayout = DiagramElementLayoutUtil.filterUnnecessaryNodes(unfilteredNodesToLayout, currentLayoutMode == IncrementalLayoutMode.LAYOUT_DIAGRAM);
if (nodesToLayout.size() == 0) {
// If the filtered node list is empty then the unfiltered list still contain feature self loop connections that need to be layed out.
unfilteredNodesToLayout.stream().filter(DiagramElementLayoutUtil::isFeatureSelfLoopConnection).map(DiagramElement.class::cast).forEachOrdered(de -> layoutFeatureSelfLoopConnection(de, mod, layoutInfoProvider));
return;
}
final LayoutOptions layoutOptions = LayoutOptions.createFromPreferences();
if (currentLayoutMode == IncrementalLayoutMode.LAYOUT_DIAGRAM) {
layout(INCREMENTAL_LAYOUT_LABEL, diagram, layoutInfoProvider, layoutOptions);
} else {
layout(mod, nodesToLayout, new StyleCalculator(diagram.getConfiguration(), StyleProvider.EMPTY), layoutInfoProvider, layoutOptions);
// Set Positions of elements which do not have a position set.
for (final DiagramNode dn : nodesToLayout) {
if (dn instanceof DiagramElement) {
final DiagramElement de = (DiagramElement) dn;
if (!de.hasPosition()) {
if (de.getDockArea() == null) {
mod.setPosition(de, new Point(0.0, 0.0));
} else if (de.getDockArea() != DockArea.GROUP && de.getParent() instanceof DiagramElement) {
final DiagramElement parent = (DiagramElement) de.getParent();
final DockingPosition defaultDockingPosition = de.getGraphicalConfiguration().getDefaultDockingPosition();
final DockArea defaultDockArea = DockArea.fromDockingPosition(defaultDockingPosition);
if (parent.hasSize()) {
final Stream<DiagramElement> otherElementsAlongSide = parent.getChildren().stream().filter(c -> c.hasPosition() && c.hasSize() && c.getDockArea() == defaultDockArea);
// Determine the position of the new element along it's preferred docking position.
double locationAlongSide;
if (defaultDockingPosition == DockingPosition.TOP || defaultDockingPosition == DockingPosition.BOTTOM) {
locationAlongSide = otherElementsAlongSide.max(Comparator.comparingDouble(c -> c.getY())).map(c -> c.getX() + c.getWidth()).orElse(0.0);
} else {
locationAlongSide = otherElementsAlongSide.max(Comparator.comparingDouble(c -> c.getY())).map(c -> c.getY() + c.getHeight()).orElse(0.0);
}
// Set position based on the docking position
switch(defaultDockingPosition) {
case TOP:
mod.setPosition(de, new Point(locationAlongSide, 0));
break;
case BOTTOM:
mod.setPosition(de, new Point(locationAlongSide, parent.getHeight()));
break;
case LEFT:
mod.setPosition(de, new Point(0, locationAlongSide));
break;
case RIGHT:
mod.setPosition(de, new Point(parent.getWidth(), locationAlongSide));
break;
default:
break;
}
}
mod.setDockArea(de, defaultDockArea);
}
}
}
}
}
}
Aggregations