blob: cd81a03b7860f3d27bba6625684feeb32fe7a7af [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006 Sybase, Inc. and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sybase, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.pagedesigner.css2.layout;
import java.util.Iterator;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
/**
* The root of a Flow hierarchy. A flow page can be treated as a normal figure,
* but contains FlowFigures.
* <P>
* A FlowPage will not have a defined width unless it is inside a figure whose
* layout provides width hints when calling
* {@link org.eclipse.draw2d.IFigure#getPreferredSize(int, int)}.
* <P>
* WARNING: This class is not intended to be subclassed by clients.
*/
public class FlowPage extends BlockFlow {
private Dimension _pageSize = new Dimension();
private int _recommendedWidth;
private int _pageSizeCacheKeys[] = new int[4];
private Dimension _pageSizeCacheValues[] = new Dimension[4];
/**
* @see org.eclipse.jst.pagedesigner.css2.layout.BlockFlow#createDefaultFlowLayout()
*/
protected FlowFigureLayout createDefaultFlowLayout() {
return new PageFlowLayout(this);
}
/**
* @see org.eclipse.draw2d.Figure#getMinimumSize()
*/
public Dimension getMinimumSize(int w, int h) {
return getPreferredSize(w, h);
}
/**
* @see org.eclipse.draw2d.Figure#invalidate()
*/
public void invalidate() {
_pageSizeCacheValues = new Dimension[4];
super.invalidate();
}
/**
* @see org.eclipse.draw2d.Figure#getPreferredSize(int, int)
*/
public Dimension getPreferredSize(int width, int h) {
if (width >= 0)
width = Math.max(0, width - getInsets().getWidth());
for (int i = 0; i < 4; i++) {
if (_pageSizeCacheKeys[i] == width
&& _pageSizeCacheValues[i] != null)
return _pageSizeCacheValues[i];
}
_pageSizeCacheKeys[3] = _pageSizeCacheKeys[2];
_pageSizeCacheKeys[2] = _pageSizeCacheKeys[1];
_pageSizeCacheKeys[1] = _pageSizeCacheKeys[0];
_pageSizeCacheKeys[0] = width;
_pageSizeCacheValues[3] = _pageSizeCacheValues[2];
_pageSizeCacheValues[2] = _pageSizeCacheValues[1];
_pageSizeCacheValues[1] = _pageSizeCacheValues[0];
// Flowpage must temporarily layout to determine its preferred size
int oldWidth = getRecommendedWidth();
setRecommendedWidth(width);
validate();
_pageSizeCacheValues[0] = _pageSize.getExpanded(getInsets().getWidth(),
getInsets().getHeight());
if (width != oldWidth) {
setRecommendedWidth(oldWidth);
getUpdateManager().addInvalidFigure(this);
}
return _pageSizeCacheValues[0];
}
int getRecommendedWidth() {
return _recommendedWidth;
}
/**
* @see BlockFlow#postValidate()
*/
public void postValidate() {
Rectangle r = getBlockBox().toRectangle();
_pageSize.width = r.width;
_pageSize.height = r.height;
for (final Iterator it = getChildren().iterator(); it.hasNext();)
{
((FlowFigure)it.next()).postValidate();
}
}
/**
* @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigure#setBounds(Rectangle)
*/
public void setBounds(Rectangle r) {
if (getBounds().equals(r))
return;
boolean invalidate = getBounds().width != r.width
|| getBounds().height != r.height;
super.setBounds(r);
int newWidth = r.width - getInsets().getWidth();
if (invalidate || getRecommendedWidth() != newWidth) {
setRecommendedWidth(newWidth);
getUpdateManager().addInvalidFigure(this);
}
}
private void setRecommendedWidth(int width) {
if (_recommendedWidth == width)
return;
_recommendedWidth = width;
super.invalidate();
}
/**
* @see org.eclipse.draw2d.Figure#validate()
*/
public void validate() {
if (isValid())
return;
super.validate();
postValidate();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.Figure#setValid(boolean)
*/
public void setValid(boolean value) {
super.setValid(value);
}
public Insets getInsets() {
return new Insets(8);
}
}