KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > widgets > ExpandItem


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 package org.eclipse.swt.widgets;
12
13 import org.eclipse.swt.graphics.*;
14 import org.eclipse.swt.internal.win32.*;
15 import org.eclipse.swt.*;
16
17 /**
18  * Instances of this class represent a selectable user interface object
19  * that represents a expandable item in a expand bar.
20  * <p>
21  * <dl>
22  * <dt><b>Styles:</b></dt>
23  * <dd>(none)</dd>
24  * <dt><b>Events:</b></dt>
25  * <dd>(none)</dd>
26  * </dl>
27  * </p><p>
28  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
29  * </p>
30  *
31  * @see ExpandBar
32  *
33  * @since 3.2
34  */

35 public class ExpandItem extends Item {
36     ExpandBar parent;
37     Control control;
38     boolean expanded, hover;
39     int x, y, width, height;
40     int imageHeight, imageWidth;
41     static final int TEXT_INSET = 6;
42     static final int BORDER = 1;
43     static final int CHEVRON_SIZE = 24;
44     
45 /**
46  * Constructs a new instance of this class given its parent
47  * and a style value describing its behavior and appearance.
48  * <p>
49  * The style value is either one of the style constants defined in
50  * class <code>SWT</code> which is applicable to instances of this
51  * class, or must be built by <em>bitwise OR</em>'ing together
52  * (that is, using the <code>int</code> "|" operator) two or more
53  * of those <code>SWT</code> style constants. The class description
54  * lists the style constants that are applicable to the class.
55  * Style bits are also inherited from superclasses.
56  * </p>
57  *
58  * @param parent a composite control which will be the parent of the new instance (cannot be null)
59  * @param style the style of control to construct
60  *
61  * @exception IllegalArgumentException <ul>
62  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
63  * </ul>
64  * @exception SWTException <ul>
65  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
66  * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
67  * </ul>
68  *
69  * @see Widget#checkSubclass
70  * @see Widget#getStyle
71  */

72 public ExpandItem (ExpandBar parent, int style) {
73     this (parent, style, checkNull (parent).getItemCount ());
74 }
75
76 /**
77  * Constructs a new instance of this class given its parent, a
78  * style value describing its behavior and appearance, and the index
79  * at which to place it in the items maintained by its parent.
80  * <p>
81  * The style value is either one of the style constants defined in
82  * class <code>SWT</code> which is applicable to instances of this
83  * class, or must be built by <em>bitwise OR</em>'ing together
84  * (that is, using the <code>int</code> "|" operator) two or more
85  * of those <code>SWT</code> style constants. The class description
86  * lists the style constants that are applicable to the class.
87  * Style bits are also inherited from superclasses.
88  * </p>
89  *
90  * @param parent a composite control which will be the parent of the new instance (cannot be null)
91  * @param style the style of control to construct
92  * @param index the zero-relative index to store the receiver in its parent
93  *
94  * @exception IllegalArgumentException <ul>
95  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
96  * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
97  * </ul>
98  * @exception SWTException <ul>
99  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
100  * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
101  * </ul>
102  *
103  * @see Widget#checkSubclass
104  * @see Widget#getStyle
105  */

106 public ExpandItem (ExpandBar parent, int style, int index) {
107     super (parent, style);
108     this.parent = parent;
109     parent.createItem (this, style, index);
110 }
111
112 static ExpandBar checkNull (ExpandBar control) {
113     if (control == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
114     return control;
115 }
116
117 private void drawChevron (int hDC, RECT rect) {
118     int oldBrush = OS.SelectObject (hDC, OS.GetSysColorBrush (OS.COLOR_BTNFACE));
119     OS.PatBlt (hDC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, OS.PATCOPY);
120     OS.SelectObject (hDC, oldBrush);
121     rect.left += 4;
122     rect.top += 4;
123     rect.right -= 4;
124     rect.bottom -= 4;
125     int hPen = OS.CreatePen (OS.PS_SOLID, 1, parent.foreground);
126     int oldPen = OS.SelectObject (hDC, hPen);
127     int [] polyline1, polyline2;
128     if (expanded) {
129         int px = rect.left + 5;
130         int py = rect.top + 7;
131         polyline1 = new int [] {
132                 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,
133                 px+3,py-2, px+4,py-2, px+4,py-1, px+5,py-1, px+5,py, px+7,py};
134         py += 4;
135         polyline2 = new int [] {
136                 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,
137                 px+3,py-2, px+4,py-2, px+4,py-1, px+5,py-1, px+5,py, px+7,py};
138     } else {
139         int px = rect.left + 5;
140         int py = rect.top + 4;
141         polyline1 = new int[] {
142                 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,
143                 px+3,py+2, px+4,py+2, px+4,py+1, px+5,py+1, px+5,py, px+7,py};
144         py += 4;
145         polyline2 = new int [] {
146                 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,
147                 px+3,py+2, px+4,py+2, px+4,py+1, px+5,py+1, px+5,py, px+7,py};
148     }
149     OS.Polyline (hDC, polyline1, polyline1.length / 2);
150     OS.Polyline (hDC, polyline2, polyline2.length / 2);
151     if (hover) {
152         int whitePen = OS.CreatePen (OS.PS_SOLID, 1, OS.GetSysColor (OS.COLOR_3DHILIGHT));
153         int darkGrayPen = OS.CreatePen (OS.PS_SOLID, 1, OS.GetSysColor (OS.COLOR_3DSHADOW));
154         OS.SelectObject (hDC, whitePen);
155         int [] points1 = {
156                 rect.left, rect.bottom,
157                 rect.left, rect.top,
158                 rect.right, rect.top};
159         OS.Polyline (hDC, points1, points1.length / 2);
160         OS.SelectObject (hDC, darkGrayPen);
161         int [] points2 = {
162                 rect.right, rect.top,
163                 rect.right, rect.bottom,
164                 rect.left, rect.bottom};
165         OS.Polyline (hDC, points2, points2.length / 2);
166         OS.SelectObject (hDC, oldPen);
167         OS.DeleteObject (whitePen);
168         OS.DeleteObject (darkGrayPen);
169     } else {
170         OS.SelectObject (hDC, oldPen);
171     }
172     OS.DeleteObject (hPen);
173 }
174
175 void drawItem (GC gc, int hTheme, RECT clipRect, boolean drawFocus) {
176     int hDC = gc.handle;
177     int headerHeight = parent.getBandHeight ();
178     RECT rect = new RECT ();
179     OS.SetRect (rect, x, y, x + width, y + headerHeight);
180     if (hTheme != 0) {
181         OS.DrawThemeBackground (hTheme, hDC, OS.EBP_NORMALGROUPHEAD, 0, rect, clipRect);
182     } else {
183         int oldBrush = OS.SelectObject (hDC, OS.GetSysColorBrush (OS.COLOR_BTNFACE));
184         OS.PatBlt (hDC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, OS.PATCOPY);
185         OS.SelectObject (hDC, oldBrush);
186     }
187     if (image != null) {
188         rect.left += ExpandItem.TEXT_INSET;
189         if (imageHeight > headerHeight) {
190             gc.drawImage (image, rect.left, rect.top + headerHeight - imageHeight);
191         } else {
192             gc.drawImage (image, rect.left, rect.top + (headerHeight - imageHeight) / 2);
193         }
194         rect.left += imageWidth;
195     }
196     if (text.length () > 0) {
197         rect.left += ExpandItem.TEXT_INSET;
198         TCHAR buffer = new TCHAR (parent.getCodePage (), text, false);
199         if (hTheme != 0) {
200             OS.DrawThemeText (hTheme, hDC, OS.EBP_NORMALGROUPHEAD, 0, buffer.chars, buffer.length(), OS.DT_VCENTER | OS.DT_SINGLELINE, 0, rect);
201         } else {
202             int oldBkMode = OS.SetBkMode (hDC, OS.TRANSPARENT);
203             OS.DrawText (hDC, buffer, buffer.length (), rect, OS.DT_VCENTER | OS.DT_SINGLELINE);
204             OS.SetBkMode (hDC, oldBkMode);
205         }
206     }
207     int chevronSize = ExpandItem.CHEVRON_SIZE;
208     rect.left = rect.right - chevronSize;
209     rect.top = y + (headerHeight - chevronSize) / 2;
210     rect.bottom = rect.top + chevronSize;
211     if (hTheme != 0) {
212         int partID = expanded ? OS.EBP_NORMALGROUPCOLLAPSE : OS.EBP_NORMALGROUPEXPAND;
213         int stateID = hover ? OS.EBNGC_HOT : OS.EBNGC_NORMAL;
214         OS.DrawThemeBackground (hTheme, hDC, partID, stateID, rect, clipRect);
215     } else {
216         drawChevron (hDC, rect);
217     }
218     if (drawFocus) {
219         OS.SetRect (rect, x + 1, y + 1, x + width - 2, y + headerHeight - 2);
220         OS.DrawFocusRect (hDC, rect);
221     }
222     if (expanded) {
223         if (!parent.isAppThemed ()) {
224             int pen = OS.CreatePen (OS.PS_SOLID, 1, OS.GetSysColor (OS.COLOR_BTNFACE));
225             int oldPen = OS.SelectObject (hDC, pen);
226             int [] points = {
227                     x, y + headerHeight,
228                     x, y + headerHeight + height,
229                     x + width - 1, y + headerHeight + height,
230                     x + width - 1, y + headerHeight - 1};
231             OS.Polyline (hDC, points, points.length / 2);
232             OS.SelectObject (hDC, oldPen);
233             OS.DeleteObject (pen);
234         }
235     }
236 }
237
238 void destroyWidget () {
239     parent.destroyItem (this);
240     releaseHandle ();
241 }
242
243 /**
244  * Returns the control that is shown when the item is expanded.
245  * If no control has been set, return <code>null</code>.
246  *
247  * @return the control
248  *
249  * @exception SWTException <ul>
250  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
251  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
252  * </ul>
253  */

254 public Control getControl () {
255     checkWidget ();
256     return control;
257 }
258
259 /**
260  * Returns <code>true</code> if the receiver is expanded,
261  * and false otherwise.
262  *
263  * @return the expanded state
264  *
265  * @exception SWTException <ul>
266  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
267  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
268  * </ul>
269  */

270 public boolean getExpanded () {
271     checkWidget ();
272     return expanded;
273 }
274
275 /**
276  * Returns the height of the receiver's header
277  *
278  * @return the height of the header
279  *
280  * @exception SWTException <ul>
281  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
282  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
283  * </ul>
284  */

285 public int getHeaderHeight () {
286     checkWidget ();
287     return Math.max (parent.getBandHeight (), imageHeight);
288 }
289
290 /**
291  * Gets the height of the receiver.
292  *
293  * @return the height
294  *
295  * @exception SWTException <ul>
296  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
297  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
298  * </ul>
299  */

300 public int getHeight () {
301     checkWidget ();
302     return height;
303 }
304
305 /**
306  * Returns the receiver's parent, which must be a <code>ExpandBar</code>.
307  *
308  * @return the receiver's parent
309  *
310  * @exception SWTException <ul>
311  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
312  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
313  * </ul>
314  */

315 public ExpandBar getParent () {
316     checkWidget ();
317     return parent;
318 }
319
320 int getPreferredWidth (int hTheme, int hDC) {
321     int width = ExpandItem.TEXT_INSET * 2 + ExpandItem.CHEVRON_SIZE;
322     if (image != null) {
323         width += ExpandItem.TEXT_INSET + imageWidth;
324     }
325     if (text.length() > 0) {
326         RECT rect = new RECT ();
327         TCHAR buffer = new TCHAR (parent.getCodePage (), text, false);
328         if (hTheme != 0) {
329             OS.GetThemeTextExtent (hTheme, hDC, OS.EBP_NORMALGROUPHEAD, 0, buffer.chars, buffer.length(), OS.DT_SINGLELINE, null, rect);
330         } else {
331             OS.DrawText (hDC, buffer, buffer.length (), rect, OS.DT_CALCRECT);
332         }
333         width += (rect.right - rect.left);
334     }
335     return width;
336 }
337
338 boolean isHover (int x, int y) {
339     int bandHeight = parent.getBandHeight ();
340     return this.x < x && x < (this.x + width) && this.y < y && y < (this.y + bandHeight);
341 }
342
343 void redraw (boolean all) {
344     int parentHandle = parent.handle;
345     int headerHeight = parent.getBandHeight ();
346     RECT rect = new RECT ();
347     int left = all ? x : x + width - headerHeight;
348     OS.SetRect (rect, left, y, x + width, y + headerHeight);
349     OS.InvalidateRect (parentHandle, rect, true);
350     if (imageHeight > headerHeight) {
351         OS.SetRect (rect, x + ExpandItem.TEXT_INSET, y + headerHeight - imageHeight, x + ExpandItem.TEXT_INSET + imageWidth, y);
352         OS.InvalidateRect (parentHandle, rect, true);
353     }
354     if (!parent.isAppThemed ()) {
355         OS.SetRect (rect, x, y + headerHeight, x + width, y + headerHeight + height + 1);
356         OS.InvalidateRect (parentHandle, rect, true);
357     }
358 }
359
360 void releaseHandle () {
361     super.releaseHandle ();
362     parent = null;
363 }
364
365 void releaseWidget () {
366     super.releaseWidget ();
367     control = null;
368 }
369
370 void setBounds (int x, int y, int width, int height, boolean move, boolean size) {
371     redraw (true);
372     int headerHeight = parent.getBandHeight ();
373     if (move) {
374         if (imageHeight > headerHeight) {
375             y += (imageHeight - headerHeight);
376         }
377         this.x = x;
378         this.y = y;
379         redraw (true);
380     }
381     if (size) {
382         this.width = width;
383         this.height = height;
384         redraw (true);
385     }
386     if (control != null && !control.isDisposed ()) {
387         if (!parent.isAppThemed ()) {
388             x += BORDER;
389             width = Math.max (0, width - BORDER * 2);
390             height = Math.max (0, height - BORDER);
391         }
392         if (move && size) control.setBounds (x, y + headerHeight, width, height);
393         if (move && !size) control.setLocation (x, y + headerHeight);
394         if (!move && size) control.setSize (width, height);
395     }
396 }
397
398 /**
399  * Sets the control that is shown when the item is expanded.
400  *
401  * @param control the new control (or null)
402  *
403  * @exception IllegalArgumentException <ul>
404  * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
405  * <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li>
406  * </ul>
407  * @exception SWTException <ul>
408  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
409  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
410  * </ul>
411  */

412 public void setControl (Control control) {
413     checkWidget ();
414     if (control != null) {
415         if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
416         if (control.parent != parent) error (SWT.ERROR_INVALID_PARENT);
417     }
418     this.control = control;
419     if (control != null) {
420         int headerHeight = parent.getBandHeight ();
421         control.setVisible (expanded);
422         if (!parent.isAppThemed ()) {
423             int width = Math.max (0, this.width - BORDER * 2);
424             int height = Math.max (0, this.height - BORDER);
425             control.setBounds (x + BORDER, y + headerHeight, width, height);
426         } else {
427             control.setBounds (x, y + headerHeight, width, height);
428         }
429     }
430 }
431
432 /**
433  * Sets the expanded state of the receiver.
434  *
435  * @param expanded the new expanded state
436  *
437  * @exception SWTException <ul>
438  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
439  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
440  * </ul>
441  */

442 public void setExpanded (boolean expanded) {
443     checkWidget ();
444     this.expanded = expanded;
445     parent.showItem (this);
446 }
447
448 /**
449  * Sets the height of the receiver. This is height of the item when it is expanded,
450  * excluding the height of the header.
451  *
452  * @param height the new height
453  *
454  * @exception SWTException <ul>
455  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
456  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
457  * </ul>
458  */

459 public void setHeight (int height) {
460     checkWidget ();
461     if (height < 0) return;
462     setBounds (0, 0, width, height, false, true);
463     if (expanded) parent.layoutItems (parent.indexOf (this) + 1, true);
464 }
465
466 public void setImage (Image image) {
467     super.setImage (image);
468     int oldImageHeight = imageHeight;
469     if (image != null) {
470         Rectangle bounds = image.getBounds ();
471         imageHeight = bounds.height;
472         imageWidth = bounds.width;
473     } else {
474         imageHeight = imageWidth = 0;
475     }
476     if (oldImageHeight != imageHeight) {
477         parent.layoutItems (parent.indexOf (this), true);
478     } else {
479         redraw (true);
480     }
481 }
482
483 public void setText (String JavaDoc string) {
484     super.setText (string);
485     redraw (true);
486 }
487 }
488
Popular Tags