/* ******************************************************************************
* 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.gallery;
import java.util.List;
import org.eclipse.draw2d.geometry.Rectangle;
import org.xmind.gef.GEF;
import org.xmind.gef.Request;
import org.xmind.gef.part.IPart;
import org.xmind.gef.policy.NavigablePolicy;
/**
* @author frankshaka
*
*/
public class GalleryNavigablePolicy extends NavigablePolicy {
/*
* (non-Javadoc)
*
* @see
* org.xmind.gef.policy.NavigablePolicy#findNavParts(org.xmind.gef.Request,
* java.lang.String, java.util.List, java.util.List)
*/
@Override
protected void findNavParts(Request request, String navType,
List<IPart> sources, List<IPart> result) {
FramePart sourceFrame = findSourceFrame(sources, navType);
if (sourceFrame != null) {
IPart p = findNavFrame(request, navType, sourceFrame);
if (p != null) {
result.add(p);
return;
}
}
super.findNavParts(request, navType, sources, result);
}
/**
* @param request
* @param navType
* @param sourceFrame
* @param result
*/
protected IPart findNavFrame(Request request, String navType,
FramePart sourceFrame) {
IPart parent = sourceFrame.getParent();
if (parent == null)
return null;
if (GEF.REQ_NAV_BEGINNING.equals(navType)) {
return findFirstFrameChild(parent);
} else if (GEF.REQ_NAV_END.equals(navType)) {
return findLastFrameChild(parent);
}
int index = parent.getChildren().indexOf(sourceFrame);
if (GEF.REQ_NAV_UP.equals(navType) || GEF.REQ_NAV_LEFT.equals(navType)) {
IPart p = findFrameChildBackwards(navType, parent, index,
sourceFrame);
if (p != null)
return p;
return findFrameChildForwards(navType, parent, index, sourceFrame);
} else if (GEF.REQ_NAV_DOWN.equals(navType)
|| GEF.REQ_NAV_RIGHT.equals(navType)) {
IPart p = findFrameChildForwards(navType, parent, index,
sourceFrame);
if (p != null)
return p;
return findFrameChildBackwards(navType, parent, index, sourceFrame);
}
return null;
}
/**
* @param navType
* @param parent
* @param index
* @param sourceFrame
* @param result
* @return
*/
private IPart findFrameChildForwards(String navType, IPart parent,
int index, FramePart sourceFrame) {
List<IPart> children = parent.getChildren();
for (int i = index + 1; i < children.size(); i++) {
IPart p = children.get(i);
if (p instanceof FramePart) {
FramePart frame = (FramePart) p;
if (isNavFrame(navType, frame, sourceFrame))
return frame;
}
}
return null;
}
/**
* @param navType
* @param parent
* @param index
* @param sourceFrame
* @param result
* @return
*/
private IPart findFrameChildBackwards(String navType, IPart parent,
int index, FramePart sourceFrame) {
List<IPart> children = parent.getChildren();
for (int i = index - 1; i >= 0; i--) {
IPart p = children.get(i);
if (p instanceof FramePart) {
FramePart frame = (FramePart) p;
if (isNavFrame(navType, frame, sourceFrame))
return frame;
}
}
return null;
}
/**
* @param navType
* @param frame
* @param sourceFrame
* @return
*/
private boolean isNavFrame(String navType, FramePart frame,
FramePart sourceFrame) {
Rectangle bounds = frame.getFigure().getBounds();
Rectangle sourceBounds = sourceFrame.getFigure().getBounds();
if (GEF.REQ_NAV_UP.equals(navType)) {
int x = sourceBounds.x + sourceBounds.width / 2;
return bounds.y < sourceBounds.y
&& bounds.bottom() < sourceBounds.bottom() && bounds.x < x
&& bounds.right() > x;
} else if (GEF.REQ_NAV_DOWN.equals(navType)) {
int x = sourceBounds.x + sourceBounds.width / 2;
return bounds.y > sourceBounds.y
&& bounds.bottom() > sourceBounds.bottom() && bounds.x < x
&& bounds.right() > x;
} else if (GEF.REQ_NAV_LEFT.equals(navType)) {
int y = sourceBounds.y + sourceBounds.height / 2;
return bounds.x < sourceBounds.x
&& bounds.right() < sourceBounds.right() && bounds.y < y
&& bounds.bottom() > y;
} else if (GEF.REQ_NAV_RIGHT.equals(navType)) {
int y = sourceBounds.y + sourceBounds.height / 2;
return bounds.x > sourceBounds.x
&& bounds.right() > sourceBounds.right() && bounds.y < y
&& bounds.bottom() > y;
}
return false;
}
/**
* @param parent
* @param result
* @return
*/
private IPart findLastFrameChild(IPart parent) {
List<IPart> children = parent.getChildren();
for (int i = children.size() - 1; i >= 0; i--) {
IPart p = children.get(i);
if (p instanceof FramePart) {
return p;
}
}
return null;
}
/**
* @param parent
* @param result
* @return
*/
private IPart findFirstFrameChild(IPart parent) {
List<IPart> children = parent.getChildren();
for (int i = 0; i < children.size(); i++) {
IPart p = children.get(i);
if (p instanceof FramePart) {
return p;
}
}
return null;
}
/**
*
* @param sources
* @param navType
* @return
*/
private FramePart findSourceFrame(List<IPart> sources, String navType) {
if (sources.isEmpty())
return null;
IPart source = sources.get(0);
return source instanceof FramePart ? (FramePart) source : null;
}
}