Mercurial > projects > dwt-addons
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 } |