blob: 05bf6c45436b516e39dee5845ba059d50790f087 [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 org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Insets;
/**
* The layout for {@link BlockFlow}figures.
* <P>
* WARNING: This class is not intended to be subclassed by clients.
*
* @author mengbo
* @since 2.1
*/
public class BlockFlowLayout extends FlowContainerLayout {
private LineBox _previousLine = null;
BlockBox _blockBox;
/**
* Creates a new BlockFlowLayout with the given BlockFlow.
*
* @param blockFlow
* the BlockFlow
*/
public BlockFlowLayout(BlockFlow blockFlow) {
super(blockFlow);
}
/**
* @see FlowContainerLayout#cleanup()
*/
protected void cleanup() {
_currentLine = _previousLine = null;
}
/**
* @see FlowContainerLayout#createNewLine()
*/
protected void createNewLine() {
_currentLine = new LineBox();
setupLine(_currentLine, Integer.MIN_VALUE);
}
protected void createNewLine(int topmargin) {
_currentLine = new LineBox();
setupLine(_currentLine, topmargin);
}
/**
* Override to setup the line's x, remaining, and available width.
*
* @param line
* the LineBox to set up
* @param topMargin
*/
protected void setupLine(LineBox line, int topMargin) {
line.clear();
// the caller of getCurrentLine() may add leftMargin and leftPadding and
// leftBorder to line.x
line._x = 0;
// FIXME: here should check the floating boxes, and minus the width of
// them from
// current line.
line.setRecommendedWidth(_blockBox.getRecommendedContentWidth());
if (_previousLine == null) {
line._y = 0;
if (topMargin != Integer.MIN_VALUE) {
line._y += topMargin;
}
} else {
if (topMargin == Integer.MIN_VALUE) {
line._y = _previousLine._y + _previousLine.getHeight()
+ getLinePadding() + _previousLine.getMarginInsets().bottom; // XXX:
// should
// add
// previous
// margin
// bottom?
} else {
line._y = _previousLine._y
+ _previousLine.getHeight()
+ Math.max(topMargin,
_previousLine.getMarginInsets().bottom);
}
}
// line.validate();
}
/**
* Called by flush(), adds the BlockBox associated with this BlockFlowLayout
* to the current line and then ends the line.
*/
protected void endBlock() {
getFlowContext().addToCurrentLine(_blockBox);
// FIXME: here should tell the context the bottom margin.
getFlowContext().endLine();
}
/**
* @see FlowContext#endLine()
*/
public void endLine() {
// this is called from child layouts.
// If there is no current line, state is equivalent to new line
if (_currentLine == null) {
return;
}
if (_currentLine.isOccupied()) {
layoutLine(); // finalize the current line layout
} else {
_currentLine = null;
return;
}
LineBox box = _currentLine;
_previousLine = box;
_currentLine = null;// _previousLine; //XXX: ???? why (yang)
// setupLine(getCurrentLine());
}
/**
* @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentY()
*/
public int getCurrentY() {
return getCurrentLine()._y; // FIXME: margin of previous block?
}
/**
* Returns the BlockFlow associated with this BlockFlowLayout
*
* @return the BlockFlow
*/
protected final BlockFlow getBlockFlow() {
return (BlockFlow) getFlowFigure();
}
/**
* Adjust all fragments in the current line to have the same baseline. Do
* any additional adjustments, such as horizontal alignment.
*/
protected void layoutLine() {
// currentLine.x = 0; //XXX: comment out, don't understand why set to 0,
// because it has already
// been set when setupLine(). And if do need, should
// set to getBorderPaddingInsets().left
switch (getBlockFlow().getHorizontalAligment()) {
case PositionConstants.RIGHT:
_currentLine._x = _blockBox.getContentWidth()
- getBorderPaddingInsets().right - _currentLine.getWidth();
break;
case PositionConstants.CENTER:
_currentLine._x = (_blockBox.getContentWidth()
+ getBorderPaddingInsets().left
- getBorderPaddingInsets().right - _currentLine.getWidth()) / 2;
break;
}
// FIXME: should check vertical alignment here?
_currentLine.commit();
_blockBox.add(_currentLine);
}
/**
* @see FlowContainerLayout#flush()
*/
protected void flush() {
if (_currentLine != null)
layoutLine();
endBlock();
}
/**
* @see FlowContainerLayout#preLayout()
*/
protected void preLayout() {
_blockBox = getBlockFlow().getBlockBox();
setupBlock();
// Probably could setup current and previous line here, or just previous
}
/**
* sets up the single block that contains all of the lines.
*/
protected void setupBlock() {
// Ask for a new line, in case we are in the middle of a line
// FIXME: the endLine() should tell context the top margin of this
// block.
getFlowContext().endLine();
LineBox line = getFlowContext().getCurrentLine();
// int recommended = line.getAvailableWidth();
// if (recommended != previousRecommendedWidth)
// Remove all current Fragments
_blockBox.clear();
// Setup the one fragment for this Block with the correct X and
// available width
// FIXME: here should check whether the CSS already set recommended
// width for this
// block.
_blockBox.setRecommendedWidth(line.getAvailableWidth());
_blockBox._y = getFlowContext().getCurrentY();
// FIXME: blockBox.x should be context.getBorderPaddingInsets().left
// or just line.x ?
_blockBox._x = 0;
}
Insets getBorderPaddingInsets() {
// FIXME:
return new Insets();
}
int getLinePadding() {
return 0;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#dispose()
*/
public void dispose() {
// TODO: anything to dispose?
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getContainerWidth()
*/
public int getContainerWidth() {
int width = Math.max(0, Math.max(_blockBox.getWidth(), _blockBox
.getRecommendedWidth()));
return width;
}
}