comparison dwtx/draw2d/text/BlockFlowLayout.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
comparison
equal deleted inserted replaced
96:b492ba44e44d 98:95307ad235d9
1 /*******************************************************************************
2 * Copyright (c) 2000, 2005 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13 module dwtx.draw2d.text.BlockFlowLayout;
14
15 import dwt.dwthelper.utils;
16 import dwtx.dwtxhelper.Collection;
17
18 import dwt.DWT;
19 import dwtx.draw2d.Figure;
20 import dwtx.draw2d.PositionConstants;
21 import dwtx.draw2d.geometry.Insets;
22 import dwtx.draw2d.text.FlowContainerLayout;
23 import dwtx.draw2d.text.BlockBox;
24 import dwtx.draw2d.text.BlockFlow;
25 import dwtx.draw2d.text.CompositeBox;
26 import dwtx.draw2d.text.FlowFigure;
27 import dwtx.draw2d.text.LineRoot;
28
29 /**
30 * The layout for {@link BlockFlow} figures.
31 *
32 * <P>WARNING: This class is not intended to be subclassed by clients.
33 * @author hudsonr
34 * @since 2.1
35 */
36 public class BlockFlowLayout
37 : FlowContainerLayout
38 {
39
40 BlockBox blockBox;
41 bool blockInvalid = false;
42 private bool continueOnSameLine = false;
43 private CompositeBox previousLine = null;
44
45 /**
46 * Creates a new BlockFlowLayout with the given BlockFlow.
47 * @param blockFlow the BlockFlow
48 */
49 public this(BlockFlow blockFlow) {
50 super(blockFlow);
51 }
52
53 private void addBelowPreviousLine(CompositeBox line) {
54 if (previousLine is null)
55 line.setLineTop(line.getTopMargin());
56 else
57 line.setLineTop(previousLine.getBaseline() + previousLine.getDescent()
58 + Math.max(previousLine.getBottomMargin(), line.getTopMargin()));
59
60 int alignment = getBlockFlow().getHorizontalAligment();
61 if (alignment is PositionConstants.LEFT || alignment is PositionConstants.RIGHT) {
62 int orientation = getBlockFlow().getOrientation();
63 if (alignment is PositionConstants.LEFT)
64 alignment = orientation is DWT.LEFT_TO_RIGHT
65 ? PositionConstants.ALWAYS_LEFT : PositionConstants.ALWAYS_RIGHT;
66 else
67 alignment = orientation is DWT.LEFT_TO_RIGHT
68 ? PositionConstants.ALWAYS_RIGHT : PositionConstants.ALWAYS_LEFT;
69 }
70 if (alignment !is PositionConstants.CENTER && getBlockFlow().isMirrored())
71 alignment = (PositionConstants.ALWAYS_LEFT | PositionConstants.ALWAYS_RIGHT)
72 & ~alignment;
73
74 switch (alignment) {
75 case PositionConstants.ALWAYS_RIGHT:
76 line.setX(blockBox.getRecommendedWidth() - line.getWidth());
77 break;
78 case PositionConstants.CENTER:
79 line.setX((blockBox.getRecommendedWidth() - line.getWidth()) / 2);
80 break;
81 case PositionConstants.ALWAYS_LEFT:
82 line.setX(0);
83 break;
84 default:
85 throw new RuntimeException("Unexpected state"); //$NON-NLS-1$
86 }
87 blockBox.add(line);
88 previousLine = line;
89 }
90
91 /**
92 * Align the line horizontally and then commit it.
93 */
94 protected void addCurrentLine() {
95 addBelowPreviousLine(currentLine);
96 (cast(LineRoot)currentLine).commit();
97 }
98
99 /**
100 * @see FlowContext#addLine(CompositeBox)
101 */
102 public void addLine(CompositeBox box) {
103 endLine();
104 addBelowPreviousLine(box);
105 }
106
107 /**
108 * Marks the blocks contents as changed. This means that children will be invalidated
109 * during validation.
110 * @since 3.1
111 */
112 public void blockContentsChanged() {
113 blockInvalid = true;
114 }
115
116 /**
117 * @see FlowContainerLayout#cleanup()
118 */
119 protected void cleanup() {
120 super.cleanup();
121 previousLine = null;
122 }
123
124 /**
125 * @see FlowContainerLayout#createNewLine()
126 */
127 protected void createNewLine() {
128 currentLine = new LineRoot(getBlockFlow().isMirrored());
129 currentLine.setRecommendedWidth(blockBox.getRecommendedWidth());
130 }
131
132 /**
133 * Called by flush(), adds the BlockBox associated with this BlockFlowLayout
134 * to the current line and then ends the line.
135 */
136 protected void endBlock() {
137 if (blockInvalid) {
138 Insets insets = getBlockFlow().getInsets();
139 blockBox.height += insets.getHeight();
140 blockBox.width += insets.getWidth();
141 }
142
143 if (getContext() !is null)
144 getContext().addLine(blockBox);
145
146 if (blockInvalid) {
147 blockInvalid = false;
148 List v = getFlowFigure().getChildren();
149 for (int i = 0; i < v.size(); i++)
150 (cast(FlowFigure)v.get(i)).postValidate();
151 }
152 }
153
154 /**
155 * @see FlowContext#endLine()
156 */
157 public void endLine() {
158 if (currentLine is null || !currentLine.isOccupied())
159 return;
160 addCurrentLine();
161 currentLine = null;
162 }
163
164 /**
165 * @see FlowContainerLayout#flush()
166 */
167 protected void flush() {
168 endLine();
169 endBlock();
170 }
171
172 bool forceChildInvalidation(Figure f) {
173 return blockInvalid;
174 }
175
176 /**
177 * Returns the BlockFlow associated with this BlockFlowLayout
178 * @return the BlockFlow
179 */
180 protected final BlockFlow getBlockFlow() {
181 return cast(BlockFlow)getFlowFigure();
182 }
183
184 int getContextWidth() {
185 return getContext().getRemainingLineWidth();
186 }
187
188 /**
189 * @see FlowContext#getContinueOnSameLine()
190 */
191 public bool getContinueOnSameLine() {
192 return continueOnSameLine;
193 }
194
195 /**
196 * @see FlowContext#getWidthLookahead(FlowFigure, int[])
197 */
198 public void getWidthLookahead(FlowFigure child, int result[]) {
199 List children = getFlowFigure().getChildren();
200 int index = -1;
201 if (child !is null)
202 index = children.indexOf(child);
203
204 for (int i = index + 1; i < children.size(); i++)
205 if ((cast(FlowFigure)children.get(i)).addLeadingWordRequirements(result))
206 return;
207 }
208
209 /**
210 * @see FlowContainerLayout#preLayout()
211 */
212 protected void preLayout() {
213 setContinueOnSameLine(false);
214 blockBox = getBlockFlow().getBlockBox_package();
215 setupBlock();
216 //Probably could setup current and previous line here, or just previous
217 }
218
219 /**
220 * @see dwtx.draw2d.text.FlowContext#setContinueOnSameLine(bool)
221 */
222 public void setContinueOnSameLine(bool value) {
223 continueOnSameLine = value;
224 }
225
226 /**
227 * sets up the single block that contains all of the lines.
228 */
229 protected void setupBlock() {
230 int recommended = getContextWidth();
231 if (recommended is Integer.MAX_VALUE)
232 recommended = -1;
233 BlockFlow bf = getBlockFlow();
234 if (recommended > 0) {
235 int borderCorrection = bf.getInsets().getWidth() + bf.getLeftMargin()
236 + bf.getRightMargin();
237 recommended = Math.max(0, recommended - borderCorrection);
238 }
239
240 if (recommended !is blockBox.recommendedWidth) {
241 blockInvalid = true;
242 blockBox.setRecommendedWidth(recommended);
243 }
244
245 if (blockInvalid) {
246 blockBox.height = 0;
247 blockBox.setWidth(Math.max(0, recommended));
248 }
249 }
250
251 }