Mercurial > projects > dwt-addons
diff dwtx/draw2d/text/InlineFlow.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/InlineFlow.d Sun Aug 03 00:52:14 2008 +0200 @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 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.InlineFlow; + +import dwt.dwthelper.utils; +import dwtx.dwtxhelper.Collection; + +import dwt.DWT; +import dwtx.draw2d.Border; +import dwtx.draw2d.ColorConstants; +import dwtx.draw2d.Graphics; +import dwtx.draw2d.geometry.Rectangle; +import dwtx.draw2d.text.FlowFigure; +import dwtx.draw2d.text.FlowFigureLayout; +import dwtx.draw2d.text.FlowBox; +import dwtx.draw2d.text.InlineFlowLayout; +import dwtx.draw2d.text.FlowBorder; + +/** + * A <code>FlowFigure</code> represented by multiple <code>LineBox</code> fragments. An + * <code>InlineFlow</code>'s parent must be either a {@link BlockFlow} or another + * InlineFlow. + * + * <P>An InlineFlow may contain other InlineFlow figures. + * + * <P>WARNING: This class is not intended to be subclassed by clients. + * @author Randy Hudson + * @since 2.0 + */ +public class InlineFlow : FlowFigure { + +List fragments; + +public this(){ + fragments = new ArrayList(1); +} + +/** + * Iterates over the children to find the width before a line-break is encountered. + * @see dwtx.draw2d.text.FlowFigure#addLeadingWordRequirements(int[]) + */ +public bool addLeadingWordRequirements(int[] width) { + Iterator iter = getChildren().iterator(); + while (iter.hasNext()) { + if ((cast(FlowFigure)iter.next()).addLeadingWordRequirements(width)) + return true; + } + return false; +} + +/** + * Extended to return false if the point is not also contained by at least one fragment. + * @return <code>true</code> if a fragment contains the given point + * @param x the relative x coordinate + * @param y the relative y coordinate + */ +public bool containsPoint(int x, int y) { + if (super.containsPoint(x, y)) { + List frags = getFragments(); + for (int i = 0; i < frags.size(); i++) + if ((cast(FlowBox)frags.get(i)).containsPoint(x, y)) + return true; + } + + return false; +} + +/** + * @see FlowFigure#createDefaultFlowLayout() + */ +protected FlowFigureLayout createDefaultFlowLayout() { + return new InlineFlowLayout(this); +} + +/** + * Returns the <code>FlowBox</code> fragments contained in this InlineFlow. The returned + * list should not be modified. + * @return The fragments + */ +public List getFragments() { + return fragments; +} + +/** + * Overridden to paint a {@link FlowBorder} if present, and draw selection. The border is + * painted first, followed by selection which is generally done in XOR, which still allows + * the border to be seen. + * @param graphics the graphics + */ +protected void paintBorder(Graphics graphics) { + if (getBorder() !is null) { + FlowBorder fb = cast(FlowBorder)getBorder(); + List frags = getFragments(); + Rectangle where = new Rectangle(); + int sides; + for (int i = 0; i < frags.size(); i++) { + FlowBox box = cast(FlowBox)frags.get(i); + + where.x = box.getX(); + where.width = box.getWidth(); + where.y = -box.getAscentWithBorder(); + where.height = box.getDescentWithBorder() - where.y; + where.y += box.getBaseline(); + sides = 0; + if (i is 0) + sides = DWT.LEAD; + if (i is frags.size() - 1) + sides |= DWT.TRAIL; + fb.paint(this, graphics, where, sides); + } + graphics.restoreState(); + } + if (selectionStart !is -1) + paintSelection(graphics); +} + +/** + * Renders the XOR selection rectangles to the graphics. + * @param graphics the graphics to paint on + * @since 3.1 + */ +protected void paintSelection(Graphics graphics) { + graphics.restoreState(); + graphics.setXORMode(true); + graphics.setBackgroundColor(ColorConstants.white); + List list = getFragments(); + FlowBox box; + for (int i = 0; i < list.size(); i++) { + box = cast(FlowBox)list.get(i); + int top = box.getLineRoot().getVisibleTop(); + int bottom = box.getLineRoot().getVisibleBottom(); + graphics.fillRectangle(box.getX(), top, box.getWidth(), bottom - top); + } +} + +/** + * @see FlowFigure#postValidate() + */ +public void postValidate() { + List list = getFragments(); + FlowBox box; + int left = Integer.MAX_VALUE, top = left; + int right = Integer.MIN_VALUE, bottom = right; + + for (int i = 0; i < list.size(); i++) { + box = cast(FlowBox)list.get(i); + left = Math.min(left, box.getX()); + right = Math.max(right, box.getX() + box.getWidth()); + top = Math.min(top, box.getLineRoot().getVisibleTop()); + bottom = Math.max(bottom, box.getLineRoot().getVisibleBottom()); + } + + setBounds(new Rectangle(left, top, right - left, bottom - top)); + repaint(); + list = getChildren(); + for (int i = 0; i < list.size(); i++) + (cast(FlowFigure)list.get(i)).postValidate(); +} + +/** + * Overridden to assert that only {@link FlowBorder} is used. <code>null</code> is still a + * valid value as well. + * @param border <code>null</code> or a FlowBorder + */ +public void setBorder(Border border) { + if (border is null || null !is cast(FlowBorder)border ) + super.setBorder(border); + else + throw new RuntimeException("Border must be an instance of FlowBorder"); //$NON-NLS-1$ +} + +}