/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.ui.internal.layouts;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.xmind.core.IPositioned;
import org.xmind.gef.draw2d.IReferencedFigure;
import org.xmind.gef.draw2d.geometry.DelegatingIntersectionSolver;
import org.xmind.gef.draw2d.geometry.IIntersectionSolver;
import org.xmind.gef.draw2d.geometry.IPositionSolver;
import org.xmind.gef.draw2d.geometry.SplitIntersectionSolver;
import org.xmind.gef.part.IGraphicalPart;
import org.xmind.gef.policy.GraphicalPartBoundsProvider;
import org.xmind.ui.mindmap.IBranchPart;
import org.xmind.ui.mindmap.ILegendPart;
import org.xmind.ui.mindmap.ISheetPart;
import org.xmind.ui.mindmap.ITopicPart;
import org.xmind.ui.util.MindMapUtils;
public class SheetIntersectionSolver extends DelegatingIntersectionSolver {
private static class SteadyBoundsProvider extends
GraphicalPartBoundsProvider {
public Rectangle getPrefBounds(Object host, Point reference) {
if (host instanceof IBranchPart) {
IBranchPart branch = (IBranchPart) host;
if (branch.getBoundaries().isEmpty()
&& branch.getSummaries().isEmpty()) {
ITopicPart topicPart = branch.getTopicPart();
if (topicPart != null)
host = topicPart.getFigure();
}
}
return super.getPrefBounds(host, reference);
}
}
private static final SteadyBoundsProvider STEADY_BOUNDS_PROVIDER_INSTANCE = new SteadyBoundsProvider();
public void recordInitPositions(ISheetPart sheet,
boolean useModelOrGraphicalPosition) {
IBranchPart centralBranch = sheet.getCentralBranch();
if (centralBranch != null) {
recordBranchPosition(centralBranch, sheet, false,
useModelOrGraphicalPosition);
}
for (IBranchPart floatingBranch : sheet.getFloatingBranches()) {
recordFreePosition(floatingBranch, useModelOrGraphicalPosition,
sheet);
}
ILegendPart legend = sheet.getLegend();
if (legend != null) {
recordFreePosition(legend, useModelOrGraphicalPosition, sheet);
}
}
private void recordBranchPosition(IBranchPart branch, ISheetPart sheet,
boolean freeable, boolean useModelOrGraphicalPosition) {
IFigure figure = branch.getFigure();
if (!figure.isVisible() || !figure.isEnabled())
return;
// if (freeable && MindMapUtils.isBranchFreeable(branch)) {
// recordFreePosition(branch, useModelOrGraphicalPosition);
// } else {
recordInitPosition(branch, getPosition(branch, sheet), CATEGORY_STEADY,
false);
if (!branch.isFolded() && !takesEntireBranch(branch)) {
boolean childrenFreeable = MindMapUtils
.isSubBranchesFreeable(branch);
for (IBranchPart sub : branch.getSubBranches()) {
recordBranchPosition(sub, sheet, childrenFreeable,
useModelOrGraphicalPosition);
}
for (IBranchPart sum : branch.getSummaryBranches()) {
recordBranchPosition(sum, sheet, childrenFreeable,
useModelOrGraphicalPosition);
}
}
// }
}
private boolean takesEntireBranch(IBranchPart branch) {
//TODO check whether it takes the entire branch area to avoid intersection
return false;
}
private void recordFreePosition(IGraphicalPart part,
boolean useModelOrGraphicalPosition, ISheetPart sheet) {
IFigure figure = part.getFigure();
if (!figure.isVisible() || !figure.isEnabled())
return;
Point position = null;
if (useModelOrGraphicalPosition) {
Object model = MindMapUtils.getRealModel(part);
if (model instanceof IPositioned) {
Point offset = MindMapUtils
.toGraphicalPosition(((IPositioned) model)
.getPosition());
if (offset != null) {
position = getOrigin().getTranslated(offset);
}
}
}
if (position == null) {
position = getPosition(part, sheet);
}
recordInitPosition(part, position, CATEGORY_FREE, false);
}
private Point getPosition(IGraphicalPart part, ISheetPart sheet) {
Point position = getActualPosition(part);
Point lastRef = getLastSheetReference(sheet);
return position.getTranslated(-lastRef.x, -lastRef.y);
}
private Point getLastSheetReference(ISheetPart sheet) {
if (sheet.getFigure() instanceof IReferencedFigure)
return ((IReferencedFigure) sheet.getFigure()).getLastReference();
return sheet.getFigure().getBounds().getLocation();
}
private Point getActualPosition(IGraphicalPart part) {
IFigure figure = part.getFigure();
if (figure instanceof IReferencedFigure)
return ((IReferencedFigure) figure).getReference();
return figure.getBounds().getCenter();
}
protected IPositionSolver createDelegate() {
IIntersectionSolver solver = new SplitIntersectionSolver(false);
solver.setDefaultBoundsProvider(GraphicalPartBoundsProvider
.getDefault());
solver.setGeneralBoundsProvider(CATEGORY_STEADY,
STEADY_BOUNDS_PROVIDER_INSTANCE);
solver.setSpacing(15);
return solver;
}
}