/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.ui.notations.map.layouts;
import java.util.List;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.whole.lang.ui.figures.AnchorFactory;
import org.whole.lang.ui.figures.DistanceMetric;
import org.whole.lang.ui.figures.IEntityFigure;
import org.whole.lang.ui.figures.INodeFigure;
import org.whole.lang.ui.layout.AbstractEntityLayout;
import org.whole.lang.ui.layout.Alignment;
import org.whole.lang.ui.layout.ColumnLayout;
import org.whole.lang.ui.layout.ICompositeEntityLayout;
import org.whole.lang.ui.layout.IEntityLayout;
import org.whole.lang.ui.layout.RowLayout;
import org.whole.lang.ui.notations.map.borders.UnderlineStyledBorder;
import org.whole.lang.ui.notations.map.figures.IStyledFigure;
/**
* @author Riccardo Solmi
*/
public abstract class AbstractStyledLayout extends AbstractEntityLayout implements IStyledLayout {
public int TOGGLE_INDENT = 16;
public int CHILDREN_GAP = 10;
public int CHILDREN_INDENT = 22;
public int CHILDREN_SPACING = 5;
public int CHILD_LINE_GAP = 1;
private IEntityLayout childrenLayoutManager;
public IEntityLayout getChildrenLayoutManager() {
if (childrenLayoutManager == null)
childrenLayoutManager = createChildrenLayoutManager();
return childrenLayoutManager;
}
protected IEntityLayout createChildrenLayoutManager() {
ICompositeEntityLayout layout = isHorizontal() ?
new RowLayout().withMarginLeft(4).withMarginRight(4) :
new ColumnLayout().withMarginTop(5).withMarginBottom(5);
return layout.withSpacing(CHILDREN_SPACING).withMinorAlignment(getMinorAlignment());
}
public boolean isHorizontal() {
return false;
}
protected Alignment getMinorAlignment() {
return Alignment.LEADING;
}
private ConnectionAnchor[] targetAnchors;
public ConnectionAnchor[] getTargetAnchors(IStyledFigure styledFigure) {
if (targetAnchors == null)
targetAnchors = createRootTargetAnchors(styledFigure);
return targetAnchors;
}
protected ConnectionAnchor[] createRootTargetAnchors(IStyledFigure styledFigure) {
if (styledFigure.getShape() instanceof UnderlineStyledBorder)
return new ConnectionAnchor[] {
AnchorFactory.createLeftOrRightBottomAnchor(childFigure[0]),
AnchorFactory.createBottomMiddleAnchor(childFigure[0])
};
else
return new ConnectionAnchor[] {
AnchorFactory.createLeftOrRightMiddleAnchor(childFigure[0]),
AnchorFactory.createTopOrBottomMiddleAnchor(childFigure[0])
};
}
public void invalidateTargetAnchors() {
targetAnchors = null;
}
@Override
public void invalidate() {
super.invalidate();
if (childFigure != null)
for (IEntityFigure child : childFigure)
child.invalidate();
}
@SuppressWarnings("unchecked")
public void paintConnections(Graphics graphics) {
IFigure childrenFigure = (IFigure) childFigure[1].getChildren().get(0);
Point[] childrenPoints = null;
List<IFigure> children = childrenFigure.getChildren();
int childrenSize = children.size();
if (childrenSize == 0) {
childrenPoints = new Point[1];
childrenPoints[0] = getChildPoint(0, childrenFigure);
} else {
childrenPoints = new Point[childrenSize];
for (int i=0; i<childrenSize; i++)
childrenPoints[i] = getChildPoint(i, children.get(i));
}
paintConnections(graphics, childrenPoints);
}
protected abstract void paintConnections(Graphics graphics, Point... childrenPoints);
protected abstract Point getRootPoint();
protected Point getChildPoint(int index, IFigure childFigure) {
if (childFigure instanceof INodeFigure) {
Point absoluteRootPoint = new Point(getRootPoint());
childFigure.translateToAbsolute(absoluteRootPoint);
ConnectionAnchor targetAnchor = ((INodeFigure) childFigure).getClosestTargetAnchor(
absoluteRootPoint, getDistanceMetric());
if (targetAnchor != null) {
Point childPoint = targetAnchor.getLocation(absoluteRootPoint);
childFigure.translateToRelative(childPoint);
return childPoint;
}
}
return getChildPoint2(index, childFigure);
}
protected DistanceMetric getDistanceMetric() {
return DistanceMetric.Orizontal;
}
protected abstract Point getChildPoint2(int index, IFigure childFigure);
protected Point getChildUpPoint(IFigure childFigure) {
return childFigure.getBounds().getTop().translate(0, -CHILD_LINE_GAP);
}
protected Point getChildDownPoint(IFigure childFigure) {
return childFigure.getBounds().getBottom().translate(0, +CHILD_LINE_GAP);
}
protected Point getChildLeftPoint(IFigure childFigure) {
if (childFigure instanceof IEntityFigure)
return childFigure.getBounds().getTopLeft().translate(-CHILD_LINE_GAP,
((IEntityFigure) childFigure).getAscent());
else
return childFigure.getBounds().getLeft().translate(-CHILD_LINE_GAP, 0);
}
protected Point getChildRightPoint(IFigure childFigure) {
if (childFigure instanceof IEntityFigure)
return childFigure.getBounds().getTopRight().translate(+CHILD_LINE_GAP,
((IEntityFigure) childFigure).getAscent());
else
return childFigure.getBounds().getRight().translate(+CHILD_LINE_GAP, 0);
}
}