/***************************************************************************** * Copyright (c) 2011 Atos Origin. * * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Atos Origin - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.activity.draw2d; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.eclipse.draw2d.FlowLayout; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Rectangle; /** * Layout to create a row (or colunm) layout All children will be displayer * under the previous one You can add constraint with {@link FlowLayoutAdvancedConstraint} * * @author arthur daussy - arthur.daussy@atosorigin.com * */ public class FlowLayoutAdvanced extends FlowLayout { /*** * Orientation of the layout * * @author adaussy * */ public enum Orientation { HORIZONTAL, VERTICAL } /** * Not implemented yet TODO */ private Orientation orientation = Orientation.VERTICAL; private Map<IFigure, Object> constraints = new HashMap<IFigure, Object>(); protected void setBoundsOfChild(IFigure parent, IFigure child, Rectangle bounds) { parent.getClientArea(Rectangle.SINGLETON); bounds.translate(Rectangle.SINGLETON.x, Rectangle.SINGLETON.y); Dimension childDim = this.getChildSize(child, Rectangle.SINGLETON.width, Rectangle.SINGLETON.height).getCopy(); bounds.setSize(childDim); Object _constraint = getConstraint(child); if(_constraint instanceof FlowLayoutAdvancedConstraint) { FlowLayoutAdvancedConstraint constraint = (FlowLayoutAdvancedConstraint)_constraint; if(constraint != null) { if(constraint.isFill()) { if(Orientation.VERTICAL.equals(orientation)) { bounds.setSize(bounds.getSize().getCopy().width, getAvailableSpaceForFilledElement(child, Rectangle.SINGLETON.getSize().getCopy()).getCopy().height); } else { bounds.setSize(getAvailableSpaceForFilledElement(child, Rectangle.SINGLETON.getSize().getCopy()).getCopy().width, bounds.getSize().getCopy().height); } } if(constraint.isFull()) { bounds.setSize(Rectangle.SINGLETON.getSize().getCopy()); bounds.setLocation(Rectangle.SINGLETON.getLocation().getCopy()); } } } child.setBounds(bounds); } public Object getConstraint(IFigure child) { return constraints.get(child); } /** * * @see org.eclipse.draw2d.AbstractLayout#setConstraint(org.eclipse.draw2d.IFigure, java.lang.Object) Use this kind of constraint * {@link FlowLayoutAdvancedConstraint} * @param child * @param constraint */ public void setConstraint(IFigure child, Object constraint) { if(constraint instanceof FlowLayoutAdvancedConstraint || constraint == null) { constraints.put(child, constraint); } } private Dimension getAvailableSpaceForFilledElement(IFigure currentChild, Dimension parentDim) { Set<IFigure> children = constraints.keySet(); if(children.isEmpty()) { throw new RuntimeException("Current layout is not set on any figure");// TODO // externalize } int numberOfFilledElement = 0; for(Object _child : children) { if(_child instanceof IFigure) { IFigure child = (IFigure)_child; if(constraints.containsKey(child)) { FlowLayoutAdvancedConstraint localConstraint = (FlowLayoutAdvancedConstraint)constraints.get(child); if(localConstraint != null && localConstraint.isFill()) { numberOfFilledElement++; } } /* * TODO set with the orientation attribute */ if(!child.equals(currentChild)) { parentDim = parentDim.getShrinked(0, getChildSize(child, Rectangle.SINGLETON.width, Rectangle.SINGLETON.height).height); } } } if(Orientation.VERTICAL.equals(orientation)) { parentDim.setHeight((int)((float)parentDim.height / (float)numberOfFilledElement)); // parentDim.setWidth(0); } else { parentDim.setWidth((int)((float)parentDim.width / (float)numberOfFilledElement)); // parentDim.setHeight(0); } return parentDim; } public Orientation getOrientation() { return orientation; } public void setOrientation(Orientation orientation) { this.orientation = orientation; } @Override public Dimension getMinimumSize(IFigure container, int w, int h) { Dimension minDim = null; for(IFigure figure : constraints.keySet()) { Object _c = constraints.get(figure); if(_c instanceof FlowLayoutAdvancedConstraint) { FlowLayoutAdvancedConstraint constraint = (FlowLayoutAdvancedConstraint)_c; if(constraint.isHasMinsize()) { if(minDim == null) { minDim = figure.getMinimumSize(); } else { minDim = Dimension.min(minDim, figure.getMinimumSize()); } } } } if(minDim == null) { minDim = new Dimension(0, 0); } return minDim; } }