| /********************************************************************* |
| * Copyright (c) 2005, 2019 SAP SE |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * Contributors: |
| * SAP SE - initial API, implementation and documentation |
| * mwenz - Bug 355347 - Remove setters of Graphiti's Font Interface |
| * cbrand - Bug 376585 - Clean-up deprecations in Graphiti |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| **********************************************************************/ |
| package org.eclipse.graphiti.examples.common.pattern.grid; |
| |
| import java.util.List; |
| |
| import org.eclipse.graphiti.features.IReason; |
| import org.eclipse.graphiti.features.context.IAddContext; |
| import org.eclipse.graphiti.features.context.ILayoutContext; |
| import org.eclipse.graphiti.features.context.IUpdateContext; |
| import org.eclipse.graphiti.features.impl.Reason; |
| import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; |
| import org.eclipse.graphiti.mm.algorithms.Polyline; |
| import org.eclipse.graphiti.mm.algorithms.Rectangle; |
| import org.eclipse.graphiti.mm.algorithms.Text; |
| import org.eclipse.graphiti.mm.algorithms.styles.Orientation; |
| import org.eclipse.graphiti.mm.algorithms.styles.Point; |
| import org.eclipse.graphiti.mm.pictograms.ContainerShape; |
| import org.eclipse.graphiti.mm.pictograms.PictogramElement; |
| import org.eclipse.graphiti.mm.pictograms.PictogramLink; |
| import org.eclipse.graphiti.mm.pictograms.Shape; |
| import org.eclipse.graphiti.pattern.AbstractPattern; |
| import org.eclipse.graphiti.pattern.mapping.ILinkCreationInfo; |
| import org.eclipse.graphiti.pattern.mapping.IStructureMapping; |
| import org.eclipse.graphiti.pattern.mapping.IStructureMappingGrid; |
| import org.eclipse.graphiti.pattern.mapping.IStructureMappingMulti; |
| import org.eclipse.graphiti.pattern.mapping.data.IDataMapping; |
| import org.eclipse.graphiti.pattern.mapping.data.ITextDataMapping; |
| import org.eclipse.graphiti.services.Graphiti; |
| import org.eclipse.graphiti.services.IGaService; |
| |
| /** |
| * The Class GridPattern. |
| */ |
| public abstract class GridPattern extends AbstractPattern { |
| |
| private IStructureMappingGrid gridMapping; |
| |
| /** |
| * Instantiates a new grid pattern. |
| */ |
| public GridPattern() { |
| super(new DefaultGridPatternConfiguration()); |
| } |
| |
| @Override |
| final public PictogramElement add(IAddContext context) { |
| Object mainBusinessObject = context.getNewObject(); |
| ContainerShape parentContainerShape = context.getTargetContainer(); |
| |
| // CONTAINER SHAPE WITH RECTANGLE |
| ContainerShape containerShape = Graphiti.getPeCreateService().createContainerShape(parentContainerShape, true); |
| |
| // check whether valid size is available, e.g. if called from the create |
| // feature |
| int minWidth = getConfiguration().getMinimumWidth(); |
| int minHeight = getConfiguration().getMinimumHeight(); |
| |
| int width = context.getWidth() <= minWidth ? minWidth : context.getWidth(); |
| int height = context.getHeight() <= minHeight ? minHeight : context.getHeight(); |
| |
| IGaService gaService = Graphiti.getGaService(); |
| { |
| // create and set graphics algorithm |
| Rectangle rectangle = gaService.createRectangle(containerShape); |
| rectangle.setForeground(manageColor(getConfiguration().getForegroundColor())); |
| rectangle.setBackground(manageColor(getConfiguration().getBackgroundColor())); |
| rectangle.setLineWidth(getConfiguration().getLineWidth() * 2); |
| rectangle.setTransparency(getConfiguration().getTransparency()); |
| gaService.setLocationAndSize(rectangle, context.getX(), context.getY(), width, height); |
| |
| // create link and wire it |
| link(containerShape, mainBusinessObject); |
| |
| // create cell separators |
| createSeparators(rectangle, getColumnCount() - 1, getConfiguration().getMajorUnitX()); |
| createSeparators(rectangle, getRowCount() - 1, getConfiguration().getMajorUnitY()); |
| } |
| |
| updatePictogramElement(containerShape); |
| |
| return containerShape; |
| } |
| |
| private void createSeparators(GraphicsAlgorithm parentGraphicsAlgorithm, int separators, int majorUnit) { |
| for (int i = 1; i <= separators; i++) { |
| Polyline polyline = Graphiti.getGaCreateService().createPolyline(parentGraphicsAlgorithm, new int[] { 0, 0, 0, 0 }); |
| polyline.setForeground(manageColor(getConfiguration().getForegroundColor())); |
| int lineWidth; |
| if (majorUnit > 0 && (i % majorUnit) == 0) { |
| lineWidth = getConfiguration().getMajorUnitSeparatorWidth(); |
| } else { |
| lineWidth = getConfiguration().getMinorSeparatorWidth(); |
| } |
| polyline.setLineWidth(lineWidth); |
| } |
| } |
| |
| @Override |
| public boolean layout(ILayoutContext context) { |
| boolean ret = true; |
| IGaService gaService = Graphiti.getGaService(); |
| ContainerShape containerShape = (ContainerShape) context.getPictogramElement(); |
| |
| int cellWidth = containerShape.getGraphicsAlgorithm().getWidth() / getColumnCount(); |
| int cellHeight = containerShape.getGraphicsAlgorithm().getHeight() / getRowCount(); |
| |
| List<Shape> children = containerShape.getChildren(); |
| for (int x = 0; x < getColumnCount(); x++) { |
| for (int y = 0; y < getRowCount(); y++) { |
| int cellIndex = (y * getColumnCount()) + x; |
| PictogramElement cellShape = children.get(cellIndex); |
| int xPos = x * cellWidth; |
| int yPos = y * cellHeight; |
| gaService.setLocationAndSize(cellShape.getGraphicsAlgorithm(), xPos, yPos, cellWidth, cellHeight); |
| } |
| } |
| |
| List<GraphicsAlgorithm> polylines = containerShape.getGraphicsAlgorithm().getGraphicsAlgorithmChildren(); |
| |
| int xSep = getColumnCount() - 1; |
| int currentX = cellWidth; |
| |
| for (int i = 0; i < xSep; i++) { |
| List<Point> points = ((Polyline) polylines.get(i)).getPoints(); |
| points.set(0, gaService.createPoint(currentX, 0)); |
| points.set(1, gaService.createPoint(currentX, containerShape.getGraphicsAlgorithm().getHeight())); |
| currentX += cellWidth; |
| } |
| |
| int currentY = cellHeight; |
| |
| for (int i = xSep; i < polylines.size(); i++) { |
| List<Point> points = ((Polyline) polylines.get(i)).getPoints(); |
| points.set(0, gaService.createPoint(0, currentY)); |
| points.set(1, gaService.createPoint(containerShape.getGraphicsAlgorithm().getWidth(), currentY)); |
| currentY += cellHeight; |
| } |
| |
| return ret; |
| } |
| |
| @Override |
| public boolean update(IUpdateContext context) { |
| boolean ret = false; |
| |
| PictogramElement pe = context.getPictogramElement(); |
| |
| if (isPatternRoot(pe)) { |
| ret = updateRoot((ContainerShape) pe); |
| } else { |
| ContainerShape rootContainer = getPatternRoot(pe); |
| if (rootContainer != null) { |
| ret = updateRoot(rootContainer); |
| } |
| } |
| |
| return ret; |
| } |
| |
| @Override |
| public IReason updateNeeded(IUpdateContext context) { |
| |
| // check only if the given pictogram element is the outer container |
| // shape |
| |
| PictogramElement pe = context.getPictogramElement(); |
| |
| if (isPatternRoot(pe)) { |
| |
| ContainerShape containerShape = (ContainerShape) pe; |
| |
| List<Shape> shapes = containerShape.getChildren(); |
| |
| // check cell structure |
| int cells = getRowCount() * getColumnCount(); |
| if (cells != shapes.size()) { |
| return Reason.createTrueReason(); |
| } |
| |
| // check cell content |
| for (Shape shape : shapes) { |
| IReason ret = updateCellNeeded(shape, getGridMapping()); |
| if (ret.toBoolean()) { |
| return ret; |
| } |
| } |
| } |
| |
| return Reason.createFalseReason(); |
| } |
| |
| /** |
| * Creates the grid mapping. |
| * |
| * @return the i structure mapping grid |
| */ |
| abstract protected IStructureMappingGrid createGridMapping(); |
| |
| private IStructureMappingGrid getGridMapping() { |
| if (gridMapping == null) { |
| gridMapping = createGridMapping(); |
| } |
| return gridMapping; |
| } |
| |
| private ContainerShape getPatternRoot(PictogramElement pe) { |
| ContainerShape ret = null; |
| // Check that a pictogram element was provided and that it is alive |
| if (pe != null && pe.eResource() != null) { |
| int i = 0; |
| do { |
| if (isPatternRoot(pe)) { |
| ret = (ContainerShape) pe; |
| } else if (pe instanceof Shape) { |
| pe = ((Shape) pe).getContainer(); |
| } |
| i++; |
| } while (ret == null && i < 2); |
| } |
| return ret; |
| } |
| |
| @Override |
| protected boolean isPatternControlled(PictogramElement pictogramElement) { |
| ContainerShape patternRoot = getPatternRoot(pictogramElement); |
| return patternRoot != null; |
| } |
| |
| @Override |
| protected boolean isPatternRoot(PictogramElement pe) { |
| boolean ret = false; |
| // Check if not null, of right instance and alive |
| if (pe instanceof ContainerShape && pe.eResource() != null) { |
| GraphicsAlgorithm ga = pe.getGraphicsAlgorithm(); |
| if (ga instanceof Rectangle) { |
| Object bo = getBusinessObjectForPictogramElement(pe); |
| ret = isMainBusinessObjectApplicable(bo); |
| } |
| } |
| return ret; |
| } |
| |
| private IReason updateCellNeeded(Shape shape, IStructureMappingMulti mapping) { |
| IReason ret = Reason.createFalseReason(); |
| |
| PictogramLink linkForPictogramElement = Graphiti.getLinkService().getLinkForPictogramElement(shape); |
| if (linkForPictogramElement != null) { |
| Text textGa = (Text) shape.getGraphicsAlgorithm(); |
| boolean booleanRet = !getText(mapping, linkForPictogramElement).equals(textGa.getValue()); |
| if (booleanRet) { |
| ret = Reason.createTrueReason(mapping.getDataMapping().getUpdateWarning(linkForPictogramElement)); |
| } |
| } |
| return ret; |
| } |
| |
| private boolean updateRoot(ContainerShape outerContainerShape) { |
| boolean ret = false; |
| Object mainBusinessObject = getBusinessObjectForPictogramElement(outerContainerShape); |
| |
| // check cell structure |
| int cells = getRowCount() * getColumnCount(); |
| if (cells != outerContainerShape.getChildren().size()) { |
| // remove old cells |
| Object[] a = outerContainerShape.getChildren().toArray(); |
| for (int i = 0; i < a.length; i++) { |
| Graphiti.getPeService().deletePictogramElement((PictogramElement) a[i]); |
| } |
| // create new cells |
| createCellShapes(outerContainerShape, getGridMapping().getLinkCreationInfos(mainBusinessObject)); |
| } |
| |
| updateCellShapes(outerContainerShape); |
| |
| return ret; |
| } |
| |
| private void updateCellShapes(ContainerShape outerContainerShape) { |
| |
| List<Shape> shapes = outerContainerShape.getChildren(); |
| for (Shape shape : shapes) { |
| PictogramLink linkForPictogramElement = Graphiti.getLinkService().getLinkForPictogramElement(shape); |
| if (linkForPictogramElement != null) { |
| Text textGa = (Text) shape.getGraphicsAlgorithm(); |
| textGa.setValue(getText(getGridMapping(), linkForPictogramElement)); |
| } |
| } |
| } |
| |
| private void createCellShapes(ContainerShape containerShape, List<ILinkCreationInfo> linkCreationInfos) { |
| |
| IGaService gaService = Graphiti.getGaService(); |
| |
| // add text shapes for each BO |
| for (ILinkCreationInfo linkCreationInfo : linkCreationInfos) { |
| |
| Shape shape = Graphiti.getPeCreateService().createShape(containerShape, false); |
| |
| Text text = Graphiti.getGaService().createText(shape); |
| text.setForeground(manageColor(getConfiguration().getTextColor())); |
| text.setHorizontalAlignment(Orientation.ALIGNMENT_CENTER); |
| text.setVerticalAlignment(Orientation.ALIGNMENT_CENTER); |
| text.setFont(gaService.manageFont(getDiagram(), "Baskerville Old Face", 10, true, false)); //$NON-NLS-1$ |
| |
| // create link and wire it |
| link(shape, linkCreationInfo.getBusinessObjects()); |
| String linkProperty = linkCreationInfo.getProperty(); |
| if (linkProperty != null) { |
| Graphiti.getLinkService().setLinkProperty(shape, linkProperty); |
| } |
| } |
| } |
| |
| /** |
| * Gets the configuration. |
| * |
| * @return the configuration |
| */ |
| protected IGridPatternConfiguration getConfiguration() { |
| return (IGridPatternConfiguration) getPatternConfiguration(); |
| } |
| |
| private int getColumnCount() { |
| return getGridMapping().getColumns(); |
| } |
| |
| private int getRowCount() { |
| return getGridMapping().getRows(); |
| } |
| |
| /** |
| * Gets the text. |
| * |
| * @param structureMapping |
| * the structure mapping |
| * @param link |
| * the pictogram link |
| * @return the text |
| */ |
| protected String getText(IStructureMapping structureMapping, PictogramLink link) { |
| String ret = null; |
| IDataMapping dm = structureMapping.getDataMapping(); |
| if (dm instanceof ITextDataMapping) { |
| ret = ((ITextDataMapping) dm).getText(link); |
| } |
| return ret; |
| } |
| } |