/* ****************************************************************************** * 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.fishbone.structures; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Insets; import org.xmind.gef.draw2d.IReferencedFigure; import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; import org.xmind.gef.draw2d.geometry.PrecisionInsets; import org.xmind.gef.draw2d.geometry.PrecisionPoint; import org.xmind.gef.draw2d.geometry.PrecisionRectangle; import org.xmind.gef.draw2d.geometry.PrecisionRotator; import org.xmind.gef.graphicalpolicy.IStructure; import org.xmind.ui.branch.BoundaryLayoutHelper; import org.xmind.ui.branch.IInsertion; import org.xmind.ui.internal.fishbone.Fishbone; import org.xmind.ui.mindmap.IBranchPart; import org.xmind.ui.mindmap.IPlusMinusPart; import org.xmind.ui.util.MindMapUtils; public class NorthEastRotated extends AbstractSubFishboneDirection { public NorthEastRotated() { super(-Fishbone.RotateAngle, false, false, true, EAST, WEST); } public ISubDirection getSubDirection() { return NE; } public void fillFishboneData(IBranchPart branch, FishboneData data, IPrecisionTransformer h, PrecisionRotator r, double spacing, List<IBranchPart> subbranches) { PrecisionPoint origin = h.getOrigin(); PrecisionInsets hTopicIns = h.ti(data.topicRefIns); PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( origin); PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( origin); double sin = r.sin(); double ctg = r.cos() / r.sin(); subbranches = new ArrayList<IBranchPart>(subbranches); Collections.reverse(subbranches); PrecisionPoint joint = origin.getTranslated(0, hTopicIns.bottom); IPlusMinusPart plusMinus = branch.getPlusMinus(); if (plusMinus != null) { joint.x += plusMinus.getFigure().getPreferredSize().width; } IInsertion insertion = (IInsertion) MindMapUtils.getCache(branch, IInsertion.CACHE_INSERTION); int insIndex = insertion == null ? -1 : subbranches.size() - insertion.getIndex(); Dimension insSize = insertion == null ? null : insertion.getSize(); double insHeight = insSize == null ? 0 : insSize.height; IStructure structure = branch.getBranchPolicy().getStructure(branch); BoundaryLayoutHelper helper = ((SubFishboneStructure) structure) .getBoundaryLayoutHelper(branch); for (int i = 0; i < subbranches.size(); i++) { IBranchPart subBranch = subbranches.get(i); IFigure subBranchFigure = subBranch.getFigure(); PrecisionInsets hChildBranchIns; PrecisionInsets rhChildBranchIns; // PrecisionInsets hChildBorder = h.ti(new PrecisionInsets( // subBranchFigure.getInsets())); Insets ins = helper.getInsets(subBranch); // PrecisionInsets preciseIns = h.ri(new PrecisionInsets(ins)); PrecisionInsets hChildBorder = h.ti(new PrecisionInsets(ins)); PrecisionInsets rhChildBorder = r.ti(hChildBorder); IStructure bsa = subBranch.getBranchPolicy() .getStructure(subBranch); if (bsa instanceof SubFishboneStructure) { SubFishboneStructure sa = (SubFishboneStructure) bsa; FishboneData subData = sa.getCastedData(subBranch) .getFishboneData(); hChildBranchIns = h.ti(subData.branchRefIns); rhChildBranchIns = h.ti(subData.rBranchRefIns); } else { PrecisionInsets childBranchNormal = new PrecisionInsets( ((IReferencedFigure) subBranchFigure) .getReferenceDescription()); hChildBranchIns = h.ti(childBranchNormal); rhChildBranchIns = r.ti(hChildBranchIns); } double dy = rhChildBranchIns.top; double dx1 = Math .abs((hChildBorder.bottom + hChildBranchIns.bottom) / sin); if (insIndex >= 0 && i == insIndex) { dx1 += Math.abs(insHeight / sin); } double dx2 = Math.abs(dy * ctg); double dx = dx1 + dx2; PrecisionPoint hChildRef = joint.getTranslated(dx, dy); PrecisionPoint rhChildRef = r.rp(hChildRef); data.addChildOffset(subBranch, h.rp(rhChildRef)); hBranchBounds.union(rhChildBranchIns.getBounds(hChildRef).expand( rhChildBorder)); rhBranchBounds.union(hChildBranchIns.getBounds(rhChildRef).expand( hChildBorder)); double dx3 = Math.abs((hChildBorder.top + hChildBranchIns.top) / sin); joint.x += dx1 + dx3 + spacing; } data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); } @Override public void fillFishboneExtraData(IBranchPart branch, FishboneData data, IPrecisionTransformer h, PrecisionRotator r, double spacing, boolean extraBranch) { if (!extraBranch) return; List<IBranchPart> calloutBranches = branch.getCalloutBranches(); PrecisionPoint origin = h.getOrigin(); PrecisionInsets hTopicIns = h.ti(data.topicRefIns); // PrecisionRectangle hTopicBounds = hTopicIns.getBounds(origin); PrecisionRectangle rhTopicBounds = h.ti(data.rTopicRefIns).getBounds( origin); double tan = r.sin() / r.cos(); double bottomLineX = hTopicIns.bottom / r.sin(); double bottomLineY = 0; double topLineX = -hTopicIns.top / r.sin(); double topLineY = 0; PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds( origin); PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds( origin); for (int i = 0; i < calloutBranches.size(); i++) { IBranchPart calloutBranch = calloutBranches.get(i); Dimension calloutTopicSize = calloutBranch.getTopicPart() .getFigure().getPreferredSize(); IReferencedFigure calloutBranchFigure = (IReferencedFigure) calloutBranch .getFigure(); PrecisionInsets hChildBranchIns; PrecisionInsets rhChildBranchIns; IStructure structure = calloutBranch.getBranchPolicy() .getStructure(calloutBranch); if (structure instanceof SubFishboneStructure) { FishboneData calloutData = ((SubFishboneStructure) structure) .getCastedData(calloutBranch).getFishboneData(); hChildBranchIns = h.ti(calloutData.branchRefIns); rhChildBranchIns = h.ti(calloutData.rBranchRefIns); } else { PrecisionInsets childBranchNormal = new PrecisionInsets( calloutBranchFigure.getReferenceDescription()); hChildBranchIns = h.ti(childBranchNormal); rhChildBranchIns = r.ti(hChildBranchIns); } org.xmind.core.util.Point position = calloutBranch.getTopic() .getPosition(); if (position == null) position = new org.xmind.core.util.Point(); boolean originPosition = position.x == 0 && position.y == 0; double dx = originPosition ? -(0.5 * hTopicIns.getHeight() / r.sin() + calloutTopicSize.width / 2) : position.x; double dy = originPosition ? -10 - calloutTopicSize.height : position.y; PrecisionPoint rhChildRef = origin.getTranslated(h.tp(dx, dy)); PrecisionRectangle hChildBounds = hChildBranchIns .getBounds(rhChildRef); double distTop = (-tan * (hChildBounds.getBottomRight().x - topLineX) + topLineY - hChildBounds .getBottomRight().y) / Math.sqrt(tan * tan + 1); double distBottom = (-tan * (hChildBounds.getBottomRight().x - bottomLineX) + bottomLineY - hChildBounds.getBottomRight().y) / Math.sqrt(tan * tan + 1); double distLimit = hChildBounds.bottom() - rhTopicBounds.bottom(); if (distLimit > 0) { rhChildRef = rhChildRef.getTranslated(0, -distLimit); hChildBounds = hChildBranchIns.getBounds(rhChildRef); } // boolean upDown = distUP > 0; if (distBottom < 0) { rhChildRef = rhChildRef.getTranslated(distBottom / r.sin(), 0); hChildBounds = hChildBranchIns.getBounds(rhChildRef); } if (hChildBounds.toDraw2DRectangle().touches( rhTopicBounds.toDraw2DRectangle()) && distTop < 0) { rhChildRef = rhChildRef.getTranslated(distTop / r.sin(), 0); } PrecisionPoint hChildRef = r.tp(rhChildRef); data.addChildOffset(calloutBranch, h.rp(rhChildRef)); hBranchBounds.union(rhChildBranchIns.getBounds(hChildRef)); rhBranchBounds.union(hChildBranchIns.getBounds(rhChildRef)); } data.branchRefIns = h.rr(hBranchBounds).getInsets(origin); data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin); } }