Mercurial > projects > dwt-addons
comparison 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 |
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.BlockFlow; | |
14 | |
15 import dwt.dwthelper.utils; | |
16 import dwtx.dwtxhelper.Collection; | |
17 | |
18 import dwt.DWT; | |
19 import dwtx.draw2d.ColorConstants; | |
20 import dwtx.draw2d.Graphics; | |
21 import dwtx.draw2d.IFigure; | |
22 import dwtx.draw2d.PositionConstants; | |
23 import dwtx.draw2d.geometry.Insets; | |
24 import dwtx.draw2d.geometry.Rectangle; | |
25 import dwtx.draw2d.text.FlowFigure; | |
26 import dwtx.draw2d.text.BlockBox; | |
27 import dwtx.draw2d.text.BidiProcessor; | |
28 import dwtx.draw2d.text.FlowFigureLayout; | |
29 import dwtx.draw2d.text.BidiChars; | |
30 import dwtx.draw2d.text.BlockFlowLayout; | |
31 import dwtx.draw2d.text.FlowBorder; | |
32 | |
33 /** | |
34 * A <code>FlowFigure</code> represented by a single {@link BlockBox} containing one or | |
35 * more lines. A BlockFlow is a creator of LineBoxes, which its children require during | |
36 * layout. A BlockFlow can be thought of as a foundation for a paragraph. | |
37 * <P> | |
38 * BlockFlows must be parented by a <code>FlowFigure</code>. {@link FlowPage} can be | |
39 * used as a "root" block and can be parented by normal Figures. | |
40 * <P> | |
41 * Only {@link FlowFigure}s can be added to a BlockFlow. | |
42 * <P> | |
43 * WARNING: This class is not intended to be subclassed by clients. | |
44 * @author hudsonr | |
45 * @since 2.1 | |
46 */ | |
47 public class BlockFlow | |
48 : FlowFigure | |
49 { | |
50 | |
51 private const BlockBox blockBox; | |
52 private int alignment = PositionConstants.NONE; | |
53 private int orientation = DWT.NONE; | |
54 private bool bidiValid; | |
55 | |
56 /** | |
57 * Constructs a new BlockFlow. | |
58 */ | |
59 public this() { | |
60 blockBox = createBlockBox(); | |
61 } | |
62 | |
63 /** | |
64 * BlockFlows contribute a paragraph separator so as to keep the Bidi state of the text | |
65 * on either side of this block from affecting each other. Since each block is like a | |
66 * different paragraph, it does not contribute any actual text to its containing block. | |
67 * | |
68 * @see dwtx.draw2d.text.FlowFigure#contributeBidi(dwtx.draw2d.text.BidiProcessor) | |
69 */ | |
70 protected void contributeBidi(BidiProcessor proc) { | |
71 proc.addControlChar(BidiChars.P_SEP); | |
72 } | |
73 | |
74 BlockBox createBlockBox() { | |
75 return new BlockBox(this); | |
76 } | |
77 | |
78 /** | |
79 * @see dwtx.draw2d.text.FlowFigure#createDefaultFlowLayout() | |
80 */ | |
81 protected FlowFigureLayout createDefaultFlowLayout() { | |
82 return new BlockFlowLayout(this); | |
83 } | |
84 | |
85 /** | |
86 * Returns the BlockBox associated with this. | |
87 * @return This BlockFlow's BlockBox | |
88 */ | |
89 protected BlockBox getBlockBox() { | |
90 return blockBox; | |
91 } | |
92 package BlockBox getBlockBox_package() { | |
93 return getBlockBox(); | |
94 } | |
95 | |
96 int getBottomMargin() { | |
97 int margin = 0; | |
98 if (auto border = cast(FlowBorder)getBorder() ) { | |
99 return border.getBottomMargin(); | |
100 } | |
101 List children = getChildren(); | |
102 int childIndex = children.size() - 1; | |
103 if (childIndex >= 0 && null !is cast(BlockFlow)children.get(childIndex) ) { | |
104 margin = Math.max(margin, | |
105 (cast(BlockFlow)children.get(childIndex)).getBottomMargin()); | |
106 } | |
107 return margin; | |
108 } | |
109 | |
110 /** | |
111 * Returns the effective horizontal alignment. This method will never return {@link | |
112 * PositionConstants#NONE}. If the value is none, it will return the inherited alignment. | |
113 * If no alignment was inherited, it will return the default alignment ({@link | |
114 * PositionConstants#LEFT}). | |
115 * @return the effective alignment | |
116 */ | |
117 public int getHorizontalAligment() { | |
118 if (alignment !is PositionConstants.NONE) | |
119 return alignment; | |
120 IFigure parent = getParent(); | |
121 while (parent !is null && !( null !is cast(BlockFlow)parent )) | |
122 parent = parent.getParent(); | |
123 if (parent !is null) | |
124 return (cast(BlockFlow)parent).getHorizontalAligment(); | |
125 return PositionConstants.LEFT; | |
126 } | |
127 | |
128 int getLeftMargin() { | |
129 if ( auto b = cast(FlowBorder)getBorder() ) | |
130 return b.getLeftMargin(); | |
131 return 0; | |
132 } | |
133 | |
134 /** | |
135 * Returns the orientation set on this block. | |
136 * @return LTR, RTL or NONE | |
137 * @see #setOrientation(int) | |
138 * @since 3.1 | |
139 */ | |
140 public int getLocalOrientation() { | |
141 return orientation; | |
142 } | |
143 | |
144 /** | |
145 * Returns the horizontal alignment set on this block. | |
146 * @return LEFT, RIGHT, ALWAYS_LEFT, ALWAYS_RIGHT, NONE | |
147 * @see #setHorizontalAligment(int) | |
148 * @since 3.1 | |
149 */ | |
150 public int getLocalHorizontalAlignment() { | |
151 return alignment; | |
152 } | |
153 | |
154 /** | |
155 * Returns this block's Bidi orientation. If none was set on this block, it | |
156 * will inherit the one from its containing block. If there is no containing block, it | |
157 * will return the default orientation (DWT.RIGHT_TO_LEFT if mirrored; DWT.LEFT_TO_RIGHT | |
158 * otherwise). | |
159 * | |
160 * @return DWT.RIGHT_TO_LEFT or DWT.LEFT_TO_RIGHT | |
161 * @see #setOrientation(int) | |
162 * @since 3.1 | |
163 */ | |
164 public int getOrientation() { | |
165 if (orientation !is DWT.NONE) | |
166 return orientation; | |
167 IFigure parent = getParent(); | |
168 while (parent !is null && !(null !is cast(BlockFlow)parent )) | |
169 parent = parent.getParent(); | |
170 if (parent !is null) | |
171 return (cast(BlockFlow)parent).getOrientation(); | |
172 return isMirrored() ? DWT.RIGHT_TO_LEFT : DWT.LEFT_TO_RIGHT; | |
173 } | |
174 | |
175 int getRightMargin() { | |
176 if (auto b = cast(FlowBorder)getBorder() ) | |
177 return b.getRightMargin(); | |
178 return 0; | |
179 } | |
180 | |
181 int getTopMargin() { | |
182 int margin = 0; | |
183 if (auto border = cast(FlowBorder)getBorder() ) { | |
184 return border.getTopMargin(); | |
185 } | |
186 List children = getChildren(); | |
187 if (children.size() > 0 && null !is cast(BlockFlow)children.get(0) ) { | |
188 margin = Math.max(margin, | |
189 (cast(BlockFlow)children.get(0)).getTopMargin()); | |
190 } | |
191 return margin; | |
192 } | |
193 | |
194 /** | |
195 * @see dwtx.draw2d.Figure#paintBorder(dwtx.draw2d.Graphics) | |
196 */ | |
197 public void paintBorder(Graphics graphics) { | |
198 if ( auto b = cast(FlowBorder)getBorder() ) { | |
199 Rectangle where = getBlockBox().toRectangle(); | |
200 where.crop(new Insets(getTopMargin(), getLeftMargin(), | |
201 getBottomMargin(), getRightMargin())); | |
202 (cast(FlowBorder)getBorder()).paint(this, graphics, where, DWT.LEAD | DWT.TRAIL); | |
203 } else | |
204 super.paintBorder(graphics); | |
205 if (selectionStart !is -1) { | |
206 graphics.restoreState(); | |
207 graphics.setXORMode(true); | |
208 graphics.setBackgroundColor(ColorConstants.white); | |
209 graphics.fillRectangle(getBounds()); | |
210 } | |
211 } | |
212 | |
213 /** | |
214 * @see dwtx.draw2d.text.FlowFigure#postValidate() | |
215 */ | |
216 public void postValidate() { | |
217 Rectangle newBounds = getBlockBox().toRectangle(); | |
218 newBounds.crop(new Insets(getTopMargin(), getLeftMargin(), | |
219 getBottomMargin(), getRightMargin())); | |
220 setBounds(newBounds); | |
221 } | |
222 | |
223 /** | |
224 * @see FlowFigure#revalidate() | |
225 */ | |
226 public void revalidate() { | |
227 BlockFlowLayout layout = cast(BlockFlowLayout)getLayoutManager(); | |
228 layout.blockContentsChanged(); | |
229 super.revalidate(); | |
230 } | |
231 | |
232 /** | |
233 * A Block will invalidate the Bidi state of all its children, so that it is | |
234 * re-evaluated when this block is next validated. | |
235 * @see dwtx.draw2d.text.FlowFigure#revalidateBidi(dwtx.draw2d.IFigure) | |
236 */ | |
237 protected void revalidateBidi(IFigure origin) { | |
238 if (bidiValid) { | |
239 bidiValid = false; | |
240 revalidate(); | |
241 } | |
242 } | |
243 | |
244 /** | |
245 * Sets the horitontal aligment of the block. Valid values are: | |
246 * <UL> | |
247 * <LI>{@link PositionConstants#NONE NONE} - (default) Alignment is inherited from | |
248 * parent. If a parent is not found then LEFT is used.</LI> | |
249 * <LI>{@link PositionConstants#LEFT} - Alignment is with leading edge</LI> | |
250 * <LI>{@link PositionConstants#RIGHT} - Alignment is with trailing edge</LI> | |
251 * <LI>{@link PositionConstants#CENTER}</LI> | |
252 * <LI>{@link PositionConstants#ALWAYS_LEFT} - Left, irrespective of orientation</LI> | |
253 * <LI>{@link PositionConstants#ALWAYS_RIGHT} - Right, irrespective of orientation</LI> | |
254 * </UL> | |
255 * @param value the aligment | |
256 * @see #getHorizontalAligment() | |
257 */ | |
258 public void setHorizontalAligment(int value) { | |
259 value &= PositionConstants.LEFT | PositionConstants.CENTER | PositionConstants.RIGHT | |
260 | PositionConstants.ALWAYS_LEFT | PositionConstants.ALWAYS_RIGHT; | |
261 if (value is alignment) | |
262 return; | |
263 alignment = value; | |
264 revalidate(); | |
265 } | |
266 | |
267 /** | |
268 * Sets the orientation for this block. Orientation can be one of: | |
269 * <UL> | |
270 * <LI>{@link DWT#LEFT_TO_RIGHT} | |
271 * <LI>{@link DWT#RIGHT_TO_LEFT} | |
272 * <LI>{@link DWT#NONE} (default) | |
273 * </UL> | |
274 * <code>NONE</code> is used to indicate that orientation should be inherited from the | |
275 * encompassing block. | |
276 * | |
277 * @param orientation LTR, RTL or NONE | |
278 * @see #getOrientation() | |
279 * @since 3.1 | |
280 */ | |
281 public void setOrientation(int orientation) { | |
282 orientation &= DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT; | |
283 if (this.orientation is orientation) | |
284 return; | |
285 this.orientation = orientation; | |
286 revalidateBidi(this); | |
287 } | |
288 | |
289 /** | |
290 * @see dwtx.draw2d.Figure#useLocalCoordinates() | |
291 */ | |
292 protected bool useLocalCoordinates() { | |
293 return true; | |
294 } | |
295 | |
296 /** | |
297 * Re-evaluate the Bidi state of all the fragments if it has been | |
298 * invalidated. | |
299 * @see dwtx.draw2d.IFigure#validate() | |
300 */ | |
301 public void validate() { | |
302 if (!bidiValid) { | |
303 BidiProcessor.INSTANCE.setOrientation(getOrientation()); | |
304 if (getOrientation() is DWT.LEFT_TO_RIGHT && isMirrored()) | |
305 BidiProcessor.INSTANCE.addControlChar(BidiChars.LRE); | |
306 super.contributeBidi(BidiProcessor.INSTANCE); | |
307 BidiProcessor.INSTANCE.process(); | |
308 bidiValid = true; | |
309 } | |
310 super.validate(); | |
311 } | |
312 | |
313 } |