package org.xmind.ui.internal.branch; import java.util.List; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Insets; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.xmind.gef.GEF; import org.xmind.gef.draw2d.IReferencedFigure; import org.xmind.gef.part.IPart; import org.xmind.ui.mindmap.IBranchPart; import org.xmind.ui.mindmap.ISummaryPart; import org.xmind.ui.mindmap.ITopicPart; import org.xmind.ui.tools.ParentSearchKey; import org.xmind.ui.util.MindMapUtils; public class AntiClockwiseRadialStructure extends BaseRadialStructure { @Override public boolean isChildLeft(IBranchPart branch, IBranchPart child) { if (branch.isCentral()) { Point pos = (Point) MindMapUtils.getCache(child, IBranchPart.CACHE_PREF_POSITION); if (pos != null) { return RadialUtils.isLeft(0, pos.x); } } if (calculatingBranches.contains(branch)) { // avoid recursively calling return false; } calculatingBranches.add(branch); boolean left; int index = branch.getSubBranches().indexOf(child); if (index >= 0) { left = !(index >= getRadialData(branch).getNumRight()); } else if (branch.getSummaryBranches().contains(child)) { left = !(isSummaryChildLeft(branch, child)); } else if (branch.getCalloutBranches().contains(child)) { left = isChildLeft(branch.getParentBranch(), branch); } else { left = RadialUtils.isLeft(getReference(branch).x, getReference(child).x); } calculatingBranches.remove(branch); return left; } @Override protected void doFillSubBranches(IBranchPart branch, List<IBranchPart> subBranches, LayoutInfo info) { RadialData cache = getRadialData(branch); int numRight = cache.getNumRight(); int[] childrenSpacings = cache.getChildrenSpacings(); int num = subBranches.size(); boolean right = false; RadiationInsertion insertion = getCurrentInsertion(branch); int insHeight = insertion == null ? 0 : insertion.getSize().height; int y = -cache.getRightSumSpacing() / 2; if (insertion != null && !insertion.right) { y -= insHeight / 2; } Point ref = info.getReference(); // the Center Topic's location for (int i = 0; i < num; i++) { if (i == numRight) { y = cache.getLeftSumSpacing() / 2; if (insertion != null) if (insertion.right) { y += insHeight / 2; } right = true; } if (insertion != null && i == insertion.getIndex()) { if (i != numRight || insertion.right) { Point p = ref.getTranslated(cache.getX(y, right), y); Rectangle insBounds = RadialUtils.getPrefBounds( insertion.getSize(), p, right); info.add(insBounds); if (insertion.right) y -= insHeight; else y += insHeight; } } IBranchPart subBranch = subBranches.get(i); // to obtain the i st subTopic's bracnch. Rectangle r; Dimension offset = getOffset(subBranch); IFigure subFigure = subBranch.getFigure(); // the SubTopic's figure if (offset != null && subFigure instanceof IReferencedFigure) { Point subRef = ref.getTranslated(offset); r = ((IReferencedFigure) subFigure).getPreferredBounds(subRef); } else { int x = cache.getX(y, right); Point subRef = ref.getTranslated(x, y); r = RadialUtils.getPrefBounds(subBranch, subRef, right); } info.put(subFigure, r); if (i < numRight) y += childrenSpacings[i]; else y -= childrenSpacings[i]; if (insertion != null) { if ((i == numRight - 1 && insertion.getIndex() == numRight && !insertion.right) || i == num) { Point p = ref.getTranslated(cache.getX(y, right), y); Rectangle insBounds = RadialUtils.getPrefBounds( insertion.getSize(), p, right); info.add(insBounds); y += insHeight; } } } } protected int calcInsIndex(IBranchPart branch, ParentSearchKey key, boolean withDisabled) { List<IBranchPart> subBranches = branch.getSubBranches(); if (subBranches.isEmpty()) return withDisabled ? 0 : -1; if (branch.isFolded()) return withDisabled ? 0 : -1; ITopicPart topic = branch.getTopicPart(); if (topic == null) return withDisabled ? 0 : -1; Point childRef = key.getFigure().getReference(); Point ref = ((IReferencedFigure) topic.getFigure()).getReference(); RadialData cache = getRadialData(branch); int numRight = cache.getNumRight(); int[] childrenSpacings = cache.getChildrenSpacings(); int num = subBranches.size(); boolean right = true; Dimension insSize = calcInsSize(branch, key); int insHeight = insSize.height; boolean insRight = calcInsSide(branch, ref, key); int startY = ref.y; int y = startY - cache.getRightSumSpacing() / 2; if (!insRight) { y -= insHeight / 2; } int ret = 0; for (int i = 0; i < num; i++) { if (i == numRight) { y = startY + cache.getLeftSumSpacing() / 2; if (insRight) { y += insHeight / 2; } //ret = num - 1; right = false; } IBranchPart subbranch = subBranches.get(i); IFigure subFigure = subbranch.getFigure(); Insets refIns = RadialUtils.getRefInsets(subFigure, right); int hint; if (i < numRight) { hint = y - refIns.top + (refIns.getHeight() + insHeight) / 2; } else { hint = y + refIns.top - (refIns.getHeight() + insHeight) / 2; } if (i < numRight) { if (!insRight && childRef.y <= hint) return ret; if (withDisabled || subFigure.isEnabled()) ret++; if (i == numRight - 1 && childRef.x < ref.x && childRef.y >= hint) return ret; } else { if (insRight && childRef.y > hint)//childRef.y >= hint) return ret; if (withDisabled || subFigure.isEnabled()) ret++; // if (i == numRight && childRef.x > ref.x && childRef.y >= hint) // return ret; } if (i < numRight) y += childrenSpacings[i]; else y -= childrenSpacings[i]; } return withDisabled ? num : -1; } public IPart calcChildNavigation(IBranchPart branch, // centre Topic IBranchPart sourceChild, String navReqType, boolean sequential) { int numRight = getRadialData(branch).getNumRight(); int numLeft = getRadialData(branch).getNumLeft(); int index = sourceChild.getBranchIndex(); int num = branch.getSubBranches().size(); if (GEF.REQ_NAV_UP.equals(navReqType)) { //UP if (index == 0) return getSubTopicPart(branch, num - 1); else if (index == numRight - 1) return getSubTopicPart(branch, index - 1); else if (index == numRight) return getSubTopicPart(branch, index + 1); else if (index > numRight) { if (index == num - 1) return getSubTopicPart(branch, 0); else return getSubTopicPart(branch, index + 1); } else return getSubTopicPart(branch, index - 1); } else if (GEF.REQ_NAV_DOWN.equals(navReqType)) { // DOWN if (index == 0) return getSubTopicPart(branch, index + 1); else if (index == numRight - 1) return getSubTopicPart(branch, index + 1); else if (index == numRight) return getSubTopicPart(branch, index - 1); else if (index > numRight) return getSubTopicPart(branch, index - 1); else return getSubTopicPart(branch, index + 1); } else if (GEF.REQ_NAV_LEFT.equals(navReqType)) { if (index < numRight) return null; else return branch.getTopicPart(); } else if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { if (index >= numLeft) return null; else return branch.getTopicPart(); } else if (!sequential) { if (GEF.REQ_NAV_RIGHT.equals(navReqType)) { int numFirst = getRadialData(branch).getNumRight(); if (sourceChild.getBranchIndex() >= numFirst) { return branch.getTopicPart(); } } else if (GEF.REQ_NAV_LEFT.equals(navReqType)) { int numFirst = getRadialData(branch).getNumRight(); if (sourceChild.getBranchIndex() < numFirst) { return branch.getTopicPart(); } } } return super.calcChildNavigation(branch, sourceChild, navReqType, sequential); } public IPart calcNavigation(IBranchPart branch, String navReqType) { int num = branch.getSubBranches().size(); if (GEF.REQ_NAV_LEFT.equals(navReqType)) { if (!branch.getSubBranches().isEmpty()) return getSubTopicPart(branch, 0); } else if (GEF.REQ_NAV_RIGHT.equals(navReqType)) return getSubTopicPart(branch, num - 1); return super.calcNavigation(branch, navReqType); } public Dimension calcInsSize(IBranchPart branch, ParentSearchKey key) { return key.getFigure().getSize(); } public boolean calcInsSide(IBranchPart branch, Point branchRef, ParentSearchKey key) { Point childRef = key.getFigure().getReference(); return childRef.x > branchRef.x; // if Child on the right of Branch, return true; } public int getSummaryDirection(IBranchPart branch, ISummaryPart summary) { List<IBranchPart> enclosingBranches = summary.getEnclosingBranches(); if (!enclosingBranches.isEmpty()) { IBranchPart subBranch = enclosingBranches.get(0); int index = subBranch.getBranchIndex(); if (index >= 0) { if (index >= getRadialData(branch).getNumRight()) { return PositionConstants.EAST; } } } return PositionConstants.WEST; } @Override protected Point calcInsertPosition(IBranchPart branch, IBranchPart child, ParentSearchKey key) { List<IBranchPart> subBranches = branch.getSubBranches(); Point firstLoc = calcFirstChildPosition(branch, key); if (subBranches.isEmpty()) return firstLoc; int index = calcInsIndex(branch, key, true); RadialData cache = getRadialData(branch); int subSize = subBranches.size(); int left = cache.getNumRight(); int right = subSize - left; Dimension insSize = key.getFigure().getSize(); Dimension inventSize = key.getInvent().getSize(); IBranchPart first = subBranches.get(0); Rectangle fBounds = first.getFigure().getBounds(); if (index == 0) { int x = fBounds.right() - inventSize.width / 2; int y = fBounds.y - (insSize.height + inventSize.height) / 2; return new Point(x, y); } if (index == subSize || index == -1) { if (subSize == 1 && isWithinThreshold(first)) { if (fBounds.bottom() > 0) { int x = fBounds.right() - inventSize.width / 2; int y = fBounds.bottom() + (insSize.height + inventSize.height) / 2; return new Point(x, y); } else { return new Point(firstLoc.x, -firstLoc.y); } } if (right == 0) return firstLoc.getNegated(); IBranchPart sub = subBranches.get(subSize - 1); Rectangle bounds = sub.getFigure().getBounds(); if (right == 1 && bounds.y > 0) return new Point(-firstLoc.x, firstLoc.y); int x = bounds.x + inventSize.width / 2; int y = bounds.y - (insSize.height + inventSize.height) / 2; return new Point(x, y); } if (index == left) { boolean isLeft = (left == 1 && right == 1) || isRight(subBranches, child, left); IBranchPart sub = isLeft ? subBranches.get(index - 1) : subBranches .get(index); Rectangle bounds = sub.getFigure().getBounds(); int x; if (isLeft) x = bounds.right() - inventSize.width / 2; else x = bounds.x + inventSize.width / 2; int y = bounds.bottom() + (insSize.height + inventSize.height) / 2; return new Point(x, y); } boolean isLeft = index < left; return calcInventPosition(subBranches.get(isLeft ? index - 1 : index), subBranches.get(isLeft ? index : index - 1), key, !isLeft); } @Override protected Point calcMovePosition(IBranchPart branch, IBranchPart child, ParentSearchKey key) { List<IBranchPart> subBranches = branch.getSubBranches(); List<Integer> disables = getDisableBranches(branch); int index = calcInsIndex(branch, key, true); int oldIndex = getOldIndex(branch, child); if (disables != null) { if (disables.contains(index - 1)) { index--; oldIndex = index; } else if (disables.contains(index)) { oldIndex = index; } } RadialData cache = getRadialData(branch); int left = cache.getNumRight(); Dimension inventSize = key.getInvent().getSize(); if (index == oldIndex) { if (index == left - 1 && key.getCursorPos().x > 0 && (!subBranches.get(left).getFigure().isEnabled())) index += 1; int delta = getTopicSize(subBranches.get(index)).width / 2 - inventSize.width / 2; int deltaX = index < left ? delta : -delta; return getReference(subBranches.get(index)) .getTranslated(deltaX, 0); } return calcInsertPosition(branch, child, key); } protected Point calcFirstChildPosition(IBranchPart branch, ParentSearchKey key) { int y = -(getMinorSpacing(branch) * 3 / 4 + 8) * 4; int x = getRadialData(branch).getX(y, true); return getReference(branch).getTranslated(-x, y).getTranslated( -key.getInvent().getSize().width / 2, 0); } }