/** * @param currentElement * @param precedingElements * @param context * @return cellOfElement */ private Cell<BPMNElement> placeElement( BPMNElement currentElement, List<LayoutingElement> precedingElements, GridContext context) { Cell<BPMNElement> newCell; if (precedingElements.isEmpty()) { // StartEvents context.startCell.setValue(currentElement); newCell = context.startCell; context.startCell = context.startCell.beneath(); } else { Cell<BPMNElement> leftCell; newCell = context.grid.getCellOfItem(currentElement); // not // null // if // join if (currentElement.isJoin()) { Point tmp; boolean splitFound = false; BPMNElement split = (BPMNElement) currentElement.prevSplit(); if (split != null) { // get all close splits Queue<BPMNElement> splits = new PriorityQueue<BPMNElement>( precedingElements.size() / 2, // should be a // good rule of // thumb new BackwardDistanceComperator(currentElement)); splits.add(split); for (LayoutingElement elem : precedingElements) { split = (BPMNElement) elem.prevSplit(); if (split != null && !splits.contains(split)) { splits.add(split); } } split = null; // get split with most connections int maxCon = 0; for (BPMNElement target : splits) { if (target == currentElement) { // beeing my own splits only makes trouble continue; } else if (target.getParent() != currentElement.getParent()) { continue; } int curCon = 0; for (LayoutingElement elem : precedingElements) { if (elem.backwardDistanceTo(target) < Integer.MAX_VALUE) { curCon++; } } if (curCon > maxCon) { maxCon = curCon; split = target; } } splitFound = split != null; } int x = 0; int yAcc = 0; int yCnt = 0; for (LayoutingElement el : precedingElements) { BPMNElement elem = (BPMNElement) el; tmp = context.grid.find(context.grid.getCellOfItem(elem)); if (tmp == null) { Grid<BPMNElement> preGrid = getContextByElement(elem).grid; tmp = preGrid.find(preGrid.getCellOfItem(elem)); if (tmp == null) { tmp = new Point(0, 0); } } else { yAcc += tmp.y; yCnt++; } x = Math.max(x, tmp.x); } if (splitFound) { leftCell = context.grid.getCellOfItem(split).getParent().get(x); // set path to split unpackable for (Cell<BPMNElement> cCell = leftCell; cCell.getValue() != split; cCell = cCell.getPrevCell()) { cCell.setPackable(false); } } else { if (yCnt == 0) { leftCell = context.grid.getFirstRow().above().get(x); } else { leftCell = context.grid.get(yAcc / yCnt).get(x); } } if (newCell != null && newCell.getValue() == currentElement) { newCell.setValue(null); } newCell = leftCell.after(); // set all incoming pathes unpackable for (LayoutingElement e : precedingElements) { BPMNElement el = (BPMNElement) e; Cell<BPMNElement> target = context.grid.getCellOfItem(el); if (target == null) { // don't set unpackable in other grids (other edge // layout) continue; } Cell<BPMNElement> start = target.getParent().get(x + 1); for (Cell<BPMNElement> cCell = start; cCell != target; cCell = cCell.getPrevCell()) { cCell.setPackable(false); } } // if not prelayouted } else if (newCell == null) { BPMNElement preElem = (BPMNElement) precedingElements.get(0); leftCell = context.grid.getCellOfItem(preElem); if (leftCell == null) { Grid<BPMNElement> preGrid = getContextByElement(preElem).grid; Cell<BPMNElement> preCell = preGrid.getCellOfItem(preElem); if (preCell == null) { System.err.println("Cannot find Cell for " + preElem); } List<Grid<BPMNElement>> grids = superGrid.getGrids(); Row<BPMNElement> newRow = null; if (grids.indexOf(preGrid) < grids.indexOf(context.grid)) { newRow = context.grid.addFirstRow(); } else { newRow = context.grid.addLastRow(); } leftCell = newRow.get(Math.max(0, preCell.getParent().find(preCell))); } newCell = leftCell.after(); } if (newCell.isFilled() && !newCell.getValue().equals(currentElement)) { newCell.getParent().insertRowBeneath(); newCell = newCell.beneath(); } newCell.setValue(currentElement); } return newCell; }
public void doLayout() { superGrid = new SuperGrid<BPMNElement>(); parent2Context.clear(); lane2LaneChilds.clear(); maxLaneDepth = 0; if (parent == null) { for (LayoutingElement pool : diagram.getElementsOfType(BPMNType.Pool)) { prepareLanes((BPMNElement) pool, 1); } } layoutElements(); if (parent == null) { // set collapsed pools List<LayoutingElement> collapsedPools = this.diagram.getElementsOfType(BPMNType.CollapsedPool); Grid<BPMNElement> cpGrid = new Grid<BPMNElement>(); superGrid.add(0, cpGrid); for (LayoutingElement collapsedPool : collapsedPools) { // make them small to not disturb finding the biggest ones in // each row / column collapsedPool.setGeometry(new LayoutingBoundsImpl(0, 0, 0, COLLAPSED_POOL_HEIGHT)); for (Cell<BPMNElement> insertCell : cpGrid.addLastRow()) { insertCell.setValue((BPMNElement) collapsedPool); } } calcGeometry(superGrid); poolWidth = Math.max(poolWidth, COLLAPSED_POOL_MIN_WIDTH); // place Lanes for (LayoutingElement pool : diagram.getElementsOfType(BPMNType.Pool)) { Grid<BPMNElement> firstGrid = findFirstGridOfPool((BPMNElement) pool); int firstGridFirstRowIndex = superGrid.findRow(firstGrid.getFirstRow()); double poolY = 0; for (int i = 0; i < firstGridFirstRowIndex; i++) { poolY += heightOfRow[i]; } placeLane((BPMNElement) pool, poolY, 0); } writeGeometry(superGrid); // set pools to start at x = CELL_MARGIN & correct size for (LayoutingElement collapsedPool : collapsedPools) { collapsedPool.setGeometry( new LayoutingBoundsImpl( CELL_MARGIN, collapsedPool.getGeometry().getY(), poolWidth, COLLAPSED_POOL_HEIGHT)); ((BPMNElement) collapsedPool).updateDataModel(); } // convert Coordinates of Elements in Lanes from absolut to // realitive for (LayoutingElement pool : diagram.getElementsOfType(BPMNType.Pool)) { correctLaneElements((BPMNElement) pool, pool.getGeometry().getY(), 0); } } else { calcGeometry(superGrid); writeGeometry(superGrid); } }