/* ******************************************************************************
* 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.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.mindmap.IBranchPart;
import org.xmind.ui.mindmap.IPlusMinusPart;
import org.xmind.ui.util.MindMapUtils;
public class NorthEastNormal extends AbstractSubFishboneDirection {
public NorthEastNormal() {
super(false, false, false, EAST, WEST);
}
public ISubDirection getSubDirection() {
return NER;
}
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();
PrecisionPoint joint = origin.getTranslated(
h.ti(data.branchRefIns).right, hTopicIns.bottom);
IPlusMinusPart plusMinus = branch.getPlusMinus();
if (plusMinus != null) {
joint.x += plusMinus.getFigure().getPreferredSize().width;
}
PrecisionPoint joint2 = joint.getCopy();
IInsertion insertion = (IInsertion) MindMapUtils.getCache(branch,
IInsertion.CACHE_INSERTION);
int insIndex = insertion == null ? -1 : 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);
//to track record the longest topic's length while it in horizon direction
double dxT = 0.0;
double width = 0.0;
double len = 0.0;
for (int i = 0; i < subbranches.size(); i++) {
IBranchPart subBranch = subbranches.get(i);
IFigure subBranchFigure = subBranch.getFigure();
PrecisionInsets hChildBranch;
PrecisionInsets rhChildBranch;
Insets ins = helper.getInsets(subBranch);
PrecisionInsets hChildBorder = h.t(new PrecisionInsets(ins));
PrecisionInsets rhChildBorder = r.ti(hChildBorder);
IStructure bsa = subBranch.getBranchPolicy()
.getStructure(subBranch);
if (bsa instanceof SubFishboneStructure) {
SubFishboneStructure sfsa = (SubFishboneStructure) bsa;
FishboneData subData = sfsa.getCastedData(subBranch)
.getFishboneData();
hChildBranch = h.ti(subData.branchRefIns);
rhChildBranch = h.ti(subData.rBranchRefIns);
} else {
PrecisionInsets childBranchNormal = new PrecisionInsets(
((IReferencedFigure) subBranchFigure)
.getReferenceDescription());
rhChildBranch = h.ti(childBranchNormal);
hChildBranch = r.ti(rhChildBranch);
}
double dy = -rhChildBranch.bottom - hChildBorder.bottom;
double dx1 = Math.abs(dy * ctg);
double dx;
if (hChildBorder.right != 0) {
dx = hChildBorder.right + rhChildBranch.left;
} else {
double dx2 = Math.abs(hChildBranch.top / sin);
dx = dx1 + dx2;
}
if (insIndex >= 0 && i == insIndex) {
dx += Math.abs(insHeight / sin);
}
PrecisionPoint hChildRef;
if (hChildBorder.right != 0) {
joint.x = joint2.x;
hChildRef = joint2.getTranslated(dx, dy);
} else {
joint2.x = joint.x;
hChildRef = joint.getTranslated(dx, dy);
}
hChildRef.y -= hChildBorder.bottom;
if (hChildBorder.getHeight() != 0) {
if (dxT <= hChildBranch.getWidth() * r.cos() + joint.x)
//the longest topic's length while it in horizon direction
dxT = hChildBranch.getWidth() * r.cos() + joint.x;
if (width <= rhChildBranch.right) {
width = rhChildBranch.right;
len = joint.x + dx + width;
}
}
PrecisionPoint rhChildRef = r.tp(hChildRef);
hBranchBounds.union(rhChildBranch.getBounds(hChildRef).expand(
hChildBorder));
rhBranchBounds.union(hChildBranch.getBounds(rhChildRef).expand(
rhChildBorder));
data.addChildOffset(subBranch, h.rp(hChildRef));
double jdx;
if (hChildBorder.left != 0) {
double dx3 = Math.abs(hChildBranch.bottom / sin);
//the whole boundary's length in horizon direction
double dxB = joint.x + dx1 - dx3 + rhChildBranch.right
+ hChildBorder.left;
if (dxT < dxB)
dx += hChildBorder.left + rhChildBranch.right;
else {
double d = joint.x + dx;
double cha = len - d;
dx += rhChildBorder.left + cha;
}
jdx = dx;
} else {
double dx3 = Math.abs(hChildBranch.bottom / sin);
jdx = dx - dx1 + dx3;
dx += rhChildBranch.right;
}
joint2.x += dx + spacing;
joint.x += jdx + 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);
PrecisionRectangle hBranchBounds = h.ti(data.branchRefIns).getBounds(
origin);
PrecisionRectangle rhBranchBounds = h.ti(data.rBranchRefIns).getBounds(
origin);
double tan = r.sin() / r.cos();
double pBottomLineX = hTopicBounds.x;
double pBottomLineY = hTopicBounds.y;
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 : position.x;
double dy = originPosition ? -10 - calloutTopicSize.height / 2
- hTopicIns.getHeight() : position.y;
PrecisionPoint hChildRef = origin.getTranslated(h.tp(dx, dy));
PrecisionRectangle hChildBounds = hChildBranchIns
.getBounds(hChildRef);
boolean touchParentTopic = hChildBounds.intersects(hTopicBounds);
if (touchParentTopic) {
hChildRef = origin
.getTranslated(hChildRef.x,
dy > 0 ? hChildBranchIns.top + hTopicIns.bottom
+ 10 : -(hChildBranchIns.bottom
+ hTopicIns.top + 10));
hChildBounds = hChildBranchIns.getBounds(hChildRef);
}
double distBottom = (-tan * (hChildBounds.x - pBottomLineX)
+ pBottomLineY - hChildBounds.y)
/ Math.sqrt(tan * tan + 1);
if (distBottom > 0) {
hChildRef = hChildRef.getTranslated(distBottom / r.sin(), 0);
hChildBounds = hChildBranchIns.getBounds(hChildRef);
}
PrecisionPoint rhChildRef = r.tp(hChildRef);
data.addChildOffset(calloutBranch, h.rp(hChildRef));
hBranchBounds.union(hChildBranchIns.getBounds(hChildRef));
rhBranchBounds.union(rhChildBranchIns.getBounds(rhChildRef));
}
data.branchRefIns = h.rr(hBranchBounds).getInsets(origin);
data.rBranchRefIns = h.rr(rhBranchBounds).getInsets(origin);
}
}