Mercurial > projects > dwt-addons
diff dwtx/draw2d/text/BlockFlow.d @ 98:95307ad235d9
Added Draw2d code, still work in progress
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 03 Aug 2008 00:52:14 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/draw2d/text/BlockFlow.d Sun Aug 03 00:52:14 2008 +0200 @@ -0,0 +1,313 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation 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: + * IBM Corporation - initial API and implementation + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module dwtx.draw2d.text.BlockFlow; + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; + +import dwt.DWT; +import dwtx.draw2d.ColorConstants; +import dwtx.draw2d.Graphics; +import dwtx.draw2d.IFigure; +import dwtx.draw2d.PositionConstants; +import dwtx.draw2d.geometry.Insets; +import dwtx.draw2d.geometry.Rectangle; +import dwtx.draw2d.text.FlowFigure; +import dwtx.draw2d.text.BlockBox; +import dwtx.draw2d.text.BidiProcessor; +import dwtx.draw2d.text.FlowFigureLayout; +import dwtx.draw2d.text.BidiChars; +import dwtx.draw2d.text.BlockFlowLayout; +import dwtx.draw2d.text.FlowBorder; + +/** + * A <code>FlowFigure</code> represented by a single {@link BlockBox} containing one or + * more lines. A BlockFlow is a creator of LineBoxes, which its children require during + * layout. A BlockFlow can be thought of as a foundation for a paragraph. + * <P> + * BlockFlows must be parented by a <code>FlowFigure</code>. {@link FlowPage} can be + * used as a "root" block and can be parented by normal Figures. + * <P> + * Only {@link FlowFigure}s can be added to a BlockFlow. + * <P> + * WARNING: This class is not intended to be subclassed by clients. + * @author hudsonr + * @since 2.1 + */ +public class BlockFlow + : FlowFigure +{ + +private const BlockBox blockBox; +private int alignment = PositionConstants.NONE; +private int orientation = DWT.NONE; +private bool bidiValid; + +/** + * Constructs a new BlockFlow. + */ +public this() { + blockBox = createBlockBox(); +} + +/** + * BlockFlows contribute a paragraph separator so as to keep the Bidi state of the text + * on either side of this block from affecting each other. Since each block is like a + * different paragraph, it does not contribute any actual text to its containing block. + * + * @see dwtx.draw2d.text.FlowFigure#contributeBidi(dwtx.draw2d.text.BidiProcessor) + */ +protected void contributeBidi(BidiProcessor proc) { + proc.addControlChar(BidiChars.P_SEP); +} + +BlockBox createBlockBox() { + return new BlockBox(this); +} + +/** + * @see dwtx.draw2d.text.FlowFigure#createDefaultFlowLayout() + */ +protected FlowFigureLayout createDefaultFlowLayout() { + return new BlockFlowLayout(this); +} + +/** + * Returns the BlockBox associated with this. + * @return This BlockFlow's BlockBox + */ +protected BlockBox getBlockBox() { + return blockBox; +} +package BlockBox getBlockBox_package() { + return getBlockBox(); +} + +int getBottomMargin() { + int margin = 0; + if (auto border = cast(FlowBorder)getBorder() ) { + return border.getBottomMargin(); + } + List children = getChildren(); + int childIndex = children.size() - 1; + if (childIndex >= 0 && null !is cast(BlockFlow)children.get(childIndex) ) { + margin = Math.max(margin, + (cast(BlockFlow)children.get(childIndex)).getBottomMargin()); + } + return margin; +} + +/** + * Returns the effective horizontal alignment. This method will never return {@link + * PositionConstants#NONE}. If the value is none, it will return the inherited alignment. + * If no alignment was inherited, it will return the default alignment ({@link + * PositionConstants#LEFT}). + * @return the effective alignment + */ +public int getHorizontalAligment() { + if (alignment !is PositionConstants.NONE) + return alignment; + IFigure parent = getParent(); + while (parent !is null && !( null !is cast(BlockFlow)parent )) + parent = parent.getParent(); + if (parent !is null) + return (cast(BlockFlow)parent).getHorizontalAligment(); + return PositionConstants.LEFT; +} + +int getLeftMargin() { + if ( auto b = cast(FlowBorder)getBorder() ) + return b.getLeftMargin(); + return 0; +} + +/** + * Returns the orientation set on this block. + * @return LTR, RTL or NONE + * @see #setOrientation(int) + * @since 3.1 + */ +public int getLocalOrientation() { + return orientation; +} + +/** + * Returns the horizontal alignment set on this block. + * @return LEFT, RIGHT, ALWAYS_LEFT, ALWAYS_RIGHT, NONE + * @see #setHorizontalAligment(int) + * @since 3.1 + */ +public int getLocalHorizontalAlignment() { + return alignment; +} + +/** + * Returns this block's Bidi orientation. If none was set on this block, it + * will inherit the one from its containing block. If there is no containing block, it + * will return the default orientation (DWT.RIGHT_TO_LEFT if mirrored; DWT.LEFT_TO_RIGHT + * otherwise). + * + * @return DWT.RIGHT_TO_LEFT or DWT.LEFT_TO_RIGHT + * @see #setOrientation(int) + * @since 3.1 + */ +public int getOrientation() { + if (orientation !is DWT.NONE) + return orientation; + IFigure parent = getParent(); + while (parent !is null && !(null !is cast(BlockFlow)parent )) + parent = parent.getParent(); + if (parent !is null) + return (cast(BlockFlow)parent).getOrientation(); + return isMirrored() ? DWT.RIGHT_TO_LEFT : DWT.LEFT_TO_RIGHT; +} + +int getRightMargin() { + if (auto b = cast(FlowBorder)getBorder() ) + return b.getRightMargin(); + return 0; +} + +int getTopMargin() { + int margin = 0; + if (auto border = cast(FlowBorder)getBorder() ) { + return border.getTopMargin(); + } + List children = getChildren(); + if (children.size() > 0 && null !is cast(BlockFlow)children.get(0) ) { + margin = Math.max(margin, + (cast(BlockFlow)children.get(0)).getTopMargin()); + } + return margin; +} + +/** + * @see dwtx.draw2d.Figure#paintBorder(dwtx.draw2d.Graphics) + */ +public void paintBorder(Graphics graphics) { + if ( auto b = cast(FlowBorder)getBorder() ) { + Rectangle where = getBlockBox().toRectangle(); + where.crop(new Insets(getTopMargin(), getLeftMargin(), + getBottomMargin(), getRightMargin())); + (cast(FlowBorder)getBorder()).paint(this, graphics, where, DWT.LEAD | DWT.TRAIL); + } else + super.paintBorder(graphics); + if (selectionStart !is -1) { + graphics.restoreState(); + graphics.setXORMode(true); + graphics.setBackgroundColor(ColorConstants.white); + graphics.fillRectangle(getBounds()); + } +} + +/** + * @see dwtx.draw2d.text.FlowFigure#postValidate() + */ +public void postValidate() { + Rectangle newBounds = getBlockBox().toRectangle(); + newBounds.crop(new Insets(getTopMargin(), getLeftMargin(), + getBottomMargin(), getRightMargin())); + setBounds(newBounds); +} + +/** + * @see FlowFigure#revalidate() + */ +public void revalidate() { + BlockFlowLayout layout = cast(BlockFlowLayout)getLayoutManager(); + layout.blockContentsChanged(); + super.revalidate(); +} + +/** + * A Block will invalidate the Bidi state of all its children, so that it is + * re-evaluated when this block is next validated. + * @see dwtx.draw2d.text.FlowFigure#revalidateBidi(dwtx.draw2d.IFigure) + */ +protected void revalidateBidi(IFigure origin) { + if (bidiValid) { + bidiValid = false; + revalidate(); + } +} + +/** + * Sets the horitontal aligment of the block. Valid values are: + * <UL> + * <LI>{@link PositionConstants#NONE NONE} - (default) Alignment is inherited from + * parent. If a parent is not found then LEFT is used.</LI> + * <LI>{@link PositionConstants#LEFT} - Alignment is with leading edge</LI> + * <LI>{@link PositionConstants#RIGHT} - Alignment is with trailing edge</LI> + * <LI>{@link PositionConstants#CENTER}</LI> + * <LI>{@link PositionConstants#ALWAYS_LEFT} - Left, irrespective of orientation</LI> + * <LI>{@link PositionConstants#ALWAYS_RIGHT} - Right, irrespective of orientation</LI> + * </UL> + * @param value the aligment + * @see #getHorizontalAligment() + */ +public void setHorizontalAligment(int value) { + value &= PositionConstants.LEFT | PositionConstants.CENTER | PositionConstants.RIGHT + | PositionConstants.ALWAYS_LEFT | PositionConstants.ALWAYS_RIGHT; + if (value is alignment) + return; + alignment = value; + revalidate(); +} + +/** + * Sets the orientation for this block. Orientation can be one of: + * <UL> + * <LI>{@link DWT#LEFT_TO_RIGHT} + * <LI>{@link DWT#RIGHT_TO_LEFT} + * <LI>{@link DWT#NONE} (default) + * </UL> + * <code>NONE</code> is used to indicate that orientation should be inherited from the + * encompassing block. + * + * @param orientation LTR, RTL or NONE + * @see #getOrientation() + * @since 3.1 + */ +public void setOrientation(int orientation) { + orientation &= DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT; + if (this.orientation is orientation) + return; + this.orientation = orientation; + revalidateBidi(this); +} + +/** + * @see dwtx.draw2d.Figure#useLocalCoordinates() + */ +protected bool useLocalCoordinates() { + return true; +} + +/** + * Re-evaluate the Bidi state of all the fragments if it has been + * invalidated. + * @see dwtx.draw2d.IFigure#validate() + */ +public void validate() { + if (!bidiValid) { + BidiProcessor.INSTANCE.setOrientation(getOrientation()); + if (getOrientation() is DWT.LEFT_TO_RIGHT && isMirrored()) + BidiProcessor.INSTANCE.addControlChar(BidiChars.LRE); + super.contributeBidi(BidiProcessor.INSTANCE); + BidiProcessor.INSTANCE.process(); + bidiValid = true; + } + super.validate(); +} + +}