comparison dwt/widgets/ExpandItem.d @ 0:380af2bdd8e5

Upload of whole dwt tree
author Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com>
date Sat, 09 Aug 2008 17:00:02 +0200
parents
children 649b8e223d5a
comparison
equal deleted inserted replaced
-1:000000000000 0:380af2bdd8e5
1 /*******************************************************************************
2 * Copyright (c) 2000, 2006 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 *******************************************************************************/
11 module dwt.widgets.ExpandItem;
12
13 import dwt.dwthelper.utils;
14
15 import dwt.DWT;
16 import dwt.DWTException;
17 import dwt.graphics.GC;
18 import dwt.graphics.Image;
19 import dwt.graphics.Point;
20 import dwt.graphics.Rectangle;
21
22 /**
23 * Instances of this class represent a selectable user interface object
24 * that represents a expandable item in a expand bar.
25 * <p>
26 * <dl>
27 * <dt><b>Styles:</b></dt>
28 * <dd>(none)</dd>
29 * <dt><b>Events:</b></dt>
30 * <dd>(none)</dd>
31 * </dl>
32 * </p><p>
33 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
34 * </p>
35 *
36 * @see ExpandBar
37 *
38 * @since 3.2
39 */
40 public class ExpandItem extends Item {
41 ExpandBar parent;
42 Control control;
43 bool expanded;
44 int x, y, width, height;
45 int imageHeight, imageWidth;
46 static final int TEXT_INSET = 6;
47 static final int BORDER = 1;
48 static final int CHEVRON_SIZE = 24;
49
50 /**
51 * Constructs a new instance of this class given its parent
52 * and a style value describing its behavior and appearance.
53 * <p>
54 * The style value is either one of the style constants defined in
55 * class <code>DWT</code> which is applicable to instances of this
56 * class, or must be built by <em>bitwise OR</em>'ing together
57 * (that is, using the <code>int</code> "|" operator) two or more
58 * of those <code>DWT</code> style constants. The class description
59 * lists the style constants that are applicable to the class.
60 * Style bits are also inherited from superclasses.
61 * </p>
62 *
63 * @param parent a composite control which will be the parent of the new instance (cannot be null)
64 * @param style the style of control to construct
65 *
66 * @exception IllegalArgumentException <ul>
67 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
68 * </ul>
69 * @exception DWTException <ul>
70 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
71 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
72 * </ul>
73 *
74 * @see Widget#checkSubclass
75 * @see Widget#getStyle
76 */
77 public ExpandItem (ExpandBar parent, int style) {
78 this (parent, style, checkNull (parent).getItemCount ());
79 }
80
81 /**
82 * Constructs a new instance of this class given its parent, a
83 * style value describing its behavior and appearance, and the index
84 * at which to place it in the items maintained by its parent.
85 * <p>
86 * The style value is either one of the style constants defined in
87 * class <code>DWT</code> which is applicable to instances of this
88 * class, or must be built by <em>bitwise OR</em>'ing together
89 * (that is, using the <code>int</code> "|" operator) two or more
90 * of those <code>DWT</code> style constants. The class description
91 * lists the style constants that are applicable to the class.
92 * Style bits are also inherited from superclasses.
93 * </p>
94 *
95 * @param parent a composite control which will be the parent of the new instance (cannot be null)
96 * @param style the style of control to construct
97 * @param index the zero-relative index to store the receiver in its parent
98 *
99 * @exception IllegalArgumentException <ul>
100 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
101 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
102 * </ul>
103 * @exception DWTException <ul>
104 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
105 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
106 * </ul>
107 *
108 * @see Widget#checkSubclass
109 * @see Widget#getStyle
110 */
111 public ExpandItem (ExpandBar parent, int style, int index) {
112 super (parent, style);
113 this.parent = parent;
114 parent.createItem (this, style, index);
115 }
116
117 static ExpandBar checkNull (ExpandBar control) {
118 if (control is null) DWT.error (DWT.ERROR_NULL_ARGUMENT);
119 return control;
120 }
121
122 public void dispose () {
123 if (isDisposed ()) return;
124 //if (!isValidThread ()) error (DWT.ERROR_THREAD_INVALID_ACCESS);
125 parent.destroyItem (this);
126 super.dispose();
127 parent = null;
128 control = null;
129 }
130
131 void drawChevron (GC gc, int x, int y) {
132 int [] polyline1, polyline2;
133 if (expanded) {
134 int px = x + 4 + 5;
135 int py = y + 4 + 7;
136 polyline1 = new int [] {
137 px,py, px+1,py, px+1,py-1, px+2,py-1, px+2,py-2, px+3,py-2, px+3,py-3,
138 px+3,py-2, px+4,py-2, px+4,py-1, px+5,py-1, px+5,py, px+6,py};
139 py += 4;
140 polyline2 = new int [] {
141 px,py, px+1,py, px+1,py-1, px+2,py-1, px+2,py-2, px+3,py-2, px+3,py-3,
142 px+3,py-2, px+4,py-2, px+4,py-1, px+5,py-1, px+5,py, px+6,py};
143 } else {
144 int px = x + 4 + 5;
145 int py = y + 4 + 4;
146 polyline1 = new int[] {
147 px,py, px+1,py, px+1,py+1, px+2,py+1, px+2,py+2, px+3,py+2, px+3,py+3,
148 px+3,py+2, px+4,py+2, px+4,py+1, px+5,py+1, px+5,py, px+6,py};
149 py += 4;
150 polyline2 = new int [] {
151 px,py, px+1,py, px+1,py+1, px+2,py+1, px+2,py+2, px+3,py+2, px+3,py+3,
152 px+3,py+2, px+4,py+2, px+4,py+1, px+5,py+1, px+5,py, px+6,py};
153 }
154 gc.setForeground (display.getSystemColor (DWT.COLOR_TITLE_FOREGROUND));
155 gc.drawPolyline (polyline1);
156 gc.drawPolyline (polyline2);
157 }
158
159 void drawItem (GC gc, bool drawFocus) {
160 int headerHeight = parent.getBandHeight ();
161 Display display = getDisplay ();
162 gc.setForeground (display.getSystemColor (DWT.COLOR_TITLE_BACKGROUND));
163 gc.setBackground (display.getSystemColor (DWT.COLOR_TITLE_BACKGROUND_GRADIENT));
164 gc.fillGradientRectangle (x, y, width, headerHeight, true);
165 if (expanded) {
166 gc.setForeground (display.getSystemColor (DWT.COLOR_TITLE_BACKGROUND_GRADIENT));
167 gc.drawLine (x, y + headerHeight, x, y + headerHeight + height - 1);
168 gc.drawLine (x, y + headerHeight + height - 1, x + width - 1, y + headerHeight + height - 1);
169 gc.drawLine (x + width - 1, y + headerHeight + height - 1, x + width - 1, y + headerHeight);
170 }
171 int drawX = x;
172 if (image !is null) {
173 drawX += ExpandItem.TEXT_INSET;
174 if (imageHeight > headerHeight) {
175 gc.drawImage (image, drawX, y + headerHeight - imageHeight);
176 } else {
177 gc.drawImage (image, drawX, y + (headerHeight - imageHeight) / 2);
178 }
179 drawX += imageWidth;
180 }
181 if (text.length() > 0) {
182 drawX += ExpandItem.TEXT_INSET;
183 Point size = gc.stringExtent (text);
184 gc.setForeground (parent.getForeground ());
185 gc.drawString (text, drawX, y + (headerHeight - size.y) / 2, true);
186 }
187 int chevronSize = ExpandItem.CHEVRON_SIZE;
188 drawChevron (gc, x + width - chevronSize, y + (headerHeight - chevronSize) / 2);
189 if (drawFocus) {
190 gc.drawFocus (x + 1, y + 1, width - 2, headerHeight - 2);
191 }
192 }
193
194 /**
195 * Returns the control that is shown when the item is expanded.
196 * If no control has been set, return <code>null</code>.
197 *
198 * @return the control
199 *
200 * @exception DWTException <ul>
201 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
202 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
203 * </ul>
204 */
205 public Control getControl() {
206 checkWidget ();
207 return control;
208 }
209
210 /**
211 * Returns <code>true</code> if the receiver is expanded,
212 * and false otherwise.
213 *
214 * @return the expanded state
215 *
216 * @exception DWTException <ul>
217 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
218 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
219 * </ul>
220 */
221 public bool getExpanded() {
222 checkWidget ();
223 return expanded;
224 }
225
226 /**
227 * Returns the height of the receiver's header
228 *
229 * @return the height of the header
230 *
231 * @exception DWTException <ul>
232 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
233 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
234 * </ul>
235 */
236 public int getHeaderHeight () {
237 checkWidget ();
238 return Math.max (parent.getBandHeight (), imageHeight);
239 }
240
241 /**
242 * Gets the height of the receiver.
243 *
244 * @return the height
245 *
246 * @exception DWTException <ul>
247 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
248 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
249 * </ul>
250 */
251 public int getHeight () {
252 checkWidget ();
253 return height;
254 }
255
256 /**
257 * Returns the receiver's parent, which must be a <code>ExpandBar</code>.
258 *
259 * @return the receiver's parent
260 *
261 * @exception DWTException <ul>
262 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
263 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
264 * </ul>
265 */
266 public ExpandBar getParent () {
267 checkWidget ();
268 return parent;
269 }
270
271 int getPreferredWidth (GC gc) {
272 int width = ExpandItem.TEXT_INSET * 2 + ExpandItem.CHEVRON_SIZE;
273 if (image !is null) {
274 width += ExpandItem.TEXT_INSET + imageWidth;
275 }
276 if (text.length() > 0) {
277 width += gc.stringExtent (text).x;
278 }
279 return width;
280 }
281
282 void redraw () {
283 int headerHeight = parent.getBandHeight ();
284 if (imageHeight > headerHeight) {
285 parent.redraw (x + ExpandItem.TEXT_INSET, y + headerHeight - imageHeight, imageWidth, imageHeight, false);
286 }
287 parent.redraw (x, y, width, headerHeight + height, false);
288 }
289
290 void setBounds (int x, int y, int width, int height, bool move, bool size) {
291 redraw ();
292 int headerHeight = parent.getBandHeight ();
293 if (move) {
294 if (imageHeight > headerHeight) {
295 y += (imageHeight - headerHeight);
296 }
297 this.x = x;
298 this.y = y;
299 redraw ();
300 }
301 if (size) {
302 this.width = width;
303 this.height = height;
304 redraw ();
305 }
306 if (control !is null && !control.isDisposed ()) {
307 if (move) control.setLocation (x + BORDER, y + headerHeight);
308 if (size) control.setSize (Math.max (0, width - 2 * BORDER), Math.max (0, height - BORDER));
309 }
310 }
311
312 /**
313 * Sets the control that is shown when the item is expanded.
314 *
315 * @param control the new control (or null)
316 *
317 * @exception IllegalArgumentException <ul>
318 * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
319 * <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li>
320 * </ul>
321 * @exception DWTException <ul>
322 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
323 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
324 * </ul>
325 */
326 public void setControl(Control control) {
327 checkWidget ();
328 if (control !is null) {
329 if (control.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT);
330 if (control.parent !is parent) error (DWT.ERROR_INVALID_PARENT);
331 }
332 this.control = control;
333 if (control !is null) {
334 control.setVisible (expanded);
335 int headerHeight = parent.getBandHeight ();
336 control.setBounds (x + BORDER, y + headerHeight, Math.max (0, width - 2 * BORDER), Math.max (0, height - BORDER));
337 }
338 }
339
340 /**
341 * Sets the expanded state of the receiver.
342 *
343 * @param expanded the new expanded state
344 *
345 * @exception DWTException <ul>
346 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
347 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
348 * </ul>
349 */
350 public void setExpanded (bool expanded) {
351 checkWidget ();
352 this.expanded = expanded;
353 parent.showItem (this);
354 }
355
356 public void setImage (Image image) {
357 super.setImage (image);
358 int oldImageHeight = imageHeight;
359 if (image !is null) {
360 Rectangle bounds = image.getBounds ();
361 imageHeight = bounds.height;
362 imageWidth = bounds.width;
363 } else {
364 imageHeight = imageWidth = 0;
365 }
366 if (oldImageHeight !is imageHeight) {
367 parent.layoutItems (parent.indexOf (this), true);
368 } else {
369 redraw ();
370 }
371 }
372
373 /**
374 * Sets the height of the receiver. This is height of the item when it is expanded,
375 * excluding the height of the header.
376 *
377 * @param height the new height
378 *
379 * @exception DWTException <ul>
380 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
381 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
382 * </ul>
383 */
384 public void setHeight (int height) {
385 checkWidget ();
386 if (height < 0) return;
387 setBounds (0, 0, width, height, false, true);
388 if (expanded) parent.layoutItems (parent.indexOf (this) + 1, true);
389 }
390
391 public void setText (String string) {
392 super.setText (string);
393 redraw ();
394 }
395 }