Skip to main content
summaryrefslogblamecommitdiffstats
blob: 40c734e0056de50e517efb47a221d08069161e5a (plain) (tree)


























































































































































































































































                                                                                                       
/*******************************************************************************
 * 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.table;

import java.util.List;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jst.pagedesigner.css2.layout.BoxUtil;
import org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout;
import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
import org.eclipse.jst.pagedesigner.css2.layout.FlowFigure;

/**
 * @author mengbo
 * @version 1.5
 */
public abstract class CachedTableCellLayout extends CSSBlockFlowLayout {
	protected Dimension _pageSize = new Dimension();

	protected boolean _calculatingSize = false;

	private int _pageSizeCacheKeys[] = new int[4];

	private Dimension _pageSizeCacheValues[] = new Dimension[4];

	private int _recommendedWidth;

	private Dimension _cacheMaxWidthSize = null;

	private boolean _isTable;

	/**
	 * @param cssfigure
	 */
	public CachedTableCellLayout(CSSFigure cssfigure) {
		super(cssfigure);
	}

	/**
	 * when figure revalidated, means some child or itself get changed somehow,
	 * so clear the cache information here.
	 */
	public void figureRevalidate() {
		super.figureRevalidate();
		_pageSizeCacheKeys = new int[4];
		_pageSizeCacheValues = new Dimension[4];
		_pageSize = new Dimension();
		_recommendedWidth = 0;
		_cacheMaxWidthSize = null;
		_isTable = false;
	}

	/**
	 * TODO: This method is not being called.
	 */
	public void postValidate() {
		if (_isTable) {
			if (_calculatingSize) {
				_pageSize.width = _blockBox.getWidth();
				_pageSize.height = _blockBox.getHeight();
			} else {
				if (_isTable) {
					Rectangle rect = getCellRect();
					_blockBox.setXYWidthHeight(rect);
					this.getCSSFigure().setBounds(rect);
				}
			}
			List list = getCSSFigure().getChildren();
			for (int i = 0, n = list.size(); i < n; i++) {
				((FlowFigure) list.get(i)).postValidate();
			}
		} else {
			super.postValidate();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.CSSBlockFlowLayout#preLayout()
	 */
	protected void preLayout() {
		_isTable = initializeTableInfo();
		if (_isTable) {
			if (!_calculatingSize) {
				// XXX: I don't know why need to call setValid(false) here, if I
				// don't call
				// it, the layout will be wrong.
				getCSSFigure().setValid(false);
			}
		}
		super.preLayout();
	}

	public abstract Rectangle getCellRect();

	public abstract boolean initializeTableInfo();

	protected void setupBlock() {
		if (_isTable) {
			// Remove all current Fragments
			_blockBox.clear();

			if (_calculatingSize) {
				// we are not in the real layout
				// Setup the one fragment for this Block with the correct X and
				// available width
				int recommendedWidth = getRecommendedWidth();
				_blockBox.setRecommendedWidth(recommendedWidth);

				if (recommendedWidth > 0
						&& recommendedWidth != Integer.MAX_VALUE) {
					_blockBox.setWidth(recommendedWidth);
				}
			} else {
				Rectangle rect = getCellRect();
				_blockBox.setWidth(rect.width);
				_blockBox.setRecommendedWidth(rect.width);
				_blockBox.setHeight(rect.height);
				_blockBox.setRecommendedHeight(rect.height);
			}

			BoxUtil.setupBorderPaddingMargin(_blockBox, getCSSStyle());
		} else {
			super.setupBlock();
		}
	}

	/**
	 * @see org.eclipse.draw2d.Figure#getPreferredSize(int, int)
	 */
	public Dimension getPreferredSize(IFigure container, int width, int h) {
		if (this.isCalculatingMaxWidth()) {
			return getMaxContentWidthSize(container, width, h);
		}
		try {
			_calculatingSize = true;
			// if (width >= 0)
			// {
			// width = Math.max(0, width - container.getInsets().getWidth());
			// }

			for (int i = 0; i < 4; i++) {
				if (_pageSizeCacheKeys[i] == width
						&& _pageSizeCacheValues[i] != null) {
					if (h > _pageSizeCacheValues[i].height) {
						return new Dimension(_pageSizeCacheValues[i].width, h);
					}
					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);
			((CSSFigure) container).setValid(false);
			container.validate();
			((CSSFigure) container).postValidate();
			_pageSizeCacheValues[0] = new Dimension(_pageSize);

			if (width != oldWidth) {
				setRecommendedWidth(oldWidth);
				// container.getUpdateManager().addInvalidFigure(container);
			}
			if (h > _pageSizeCacheValues[0].height) {
				return new Dimension(_pageSizeCacheValues[0].width, h);
			} else {
				return _pageSizeCacheValues[0];
			}
		} finally {
			_calculatingSize = false;
		}
	}

	public int getRecommendedWidth() {
		return _recommendedWidth;
	}

	private void setRecommendedWidth(int width) {
		if (_recommendedWidth == width) {
			return;
		}
		_recommendedWidth = width;
	}

	public Dimension getMaxContentWidthSize(IFigure container, int width,
			int height) {
		try {
			_calculatingSize = true;

			if (this._cacheMaxWidthSize == null) {
				boolean b = getCalcuatingMaxWidth();
				setCalculatingMaxWidth(true);

				// Flowpage must temporarily layout to determine its preferred
				// size
				int oldWidth = getRecommendedWidth();
				if (width <= 0) {
					setRecommendedWidth(Integer.MAX_VALUE);
				} else {
					setRecommendedWidth(width);
				}
				((CSSFigure) container).setValid(false);
				container.validate();

				((CSSFigure) container).postValidate();
				_cacheMaxWidthSize = new Dimension(_pageSize);
				if (height > _pageSize.height) {
					_cacheMaxWidthSize.height = height;
				}

				if (0 != oldWidth) {
					setRecommendedWidth(oldWidth);
					// container.getUpdateManager().addInvalidFigure(container);
				}

				setCalculatingMaxWidth(b);
			}
			return _cacheMaxWidthSize;
		} finally {
			_calculatingSize = false;
		}
	}

	/**
	 * @return Returns the _isTable.
	 */
	protected boolean isTable() {
		return _isTable;
	}
}

Back to the top