Mercurial > projects > dwt-addons
view 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 source
/******************************************************************************* * 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$ } }