/* ******************************************************************************
* 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 static org.xmind.ui.gallery.NavigationViewer.BIG_HEIGHT;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.draw2d.AbstractLayout;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
/**
* @author Frank Shaka
*
*/
public class NavigationItemLayout extends AbstractLayout {
private static final int H_SPACING = 10;
private static final int BIG_TOP_MARGIN = 10;
private static final int SMALL_TOP_MARGIN = 25;
private IFigure center = null;
private Map<IFigure, Rectangle> cache = null;
private int centerX = -1;
private int childrenWidth = -1;
private int offset = 0;
private int maxOffset = -1;
private int minOffset = -1;
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.LayoutManager#layout(org.eclipse.draw2d.IFigure)
*/
public void layout(IFigure container) {
buildCache(container);
Rectangle r = container.getClientArea(Rectangle.SINGLETON);
int x = r.x + r.width / 2 - centerX + offset;
int y = r.y + BIG_TOP_MARGIN;
for (Entry<IFigure, Rectangle> en : cache.entrySet()) {
IFigure child = en.getKey();
Rectangle b = en.getValue();
child.setBounds(b.getTranslated(x, y));
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.draw2d.AbstractLayout#calculatePreferredSize(org.eclipse.
* draw2d.IFigure, int, int)
*/
@Override
protected Dimension calculatePreferredSize(IFigure container, int wHint,
int hHint) {
if (wHint >= 0 && hHint >= 0)
return new Dimension(wHint, hHint);
buildCache(container);
int width = childrenWidth + H_SPACING + H_SPACING;
int height = BIG_HEIGHT + BIG_TOP_MARGIN + BIG_TOP_MARGIN;
return new Dimension(width, height);
}
private void buildCache(IFigure container) {
if (cache != null)
return;
cache = new HashMap<IFigure, Rectangle>();
List children = container.getChildren();
int x = 0;
int min = 1000;
int max = 0;
for (int i = 0; i < children.size(); i++) {
IFigure child = (IFigure) children.get(i);
Dimension size = child.getPreferredSize();
int cx = x + size.width / 2;
int y;
if (child == center) {
centerX = cx;
y = 0;
} else {
y = SMALL_TOP_MARGIN - BIG_TOP_MARGIN;
}
cache.put(child, new Rectangle(x, y, size.width, size.height));
x += size.width + H_SPACING;
min = Math.min(min, cx);
max = Math.max(max, cx);
}
childrenWidth = x - H_SPACING;
if (centerX < 0) {
centerX = childrenWidth / 2;
}
minOffset = centerX - max;
maxOffset = centerX - min;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.draw2d.AbstractLayout#setConstraint(org.eclipse.draw2d.IFigure
* , java.lang.Object)
*/
@Override
public void setConstraint(IFigure child, Object constraint) {
if (child == constraint) {
this.center = child;
}
super.setConstraint(child, constraint);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.AbstractLayout#invalidate()
*/
@Override
public void invalidate() {
super.invalidate();
cache = null;
centerX = -1;
childrenWidth = -1;
maxOffset = -1;
minOffset = -1;
}
/**
* @param offset
* the offset to set
*/
public void addOffset(IFigure container, int offset) {
offset += this.offset;
buildCache(container);
this.offset = Math.max(minOffset, Math.min(maxOffset, offset));
}
/**
*
*/
public void resetOffset(IFigure container) {
this.offset = 0;
}
}