KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.internal.win32.*;
14 import org.eclipse.swt.*;
15 import org.eclipse.swt.graphics.*;
16 import org.eclipse.swt.events.*;
17
18 /**
19  * Instances of this class support the layout of selectable
20  * expand bar items.
21  * <p>
22  * The item children that may be added to instances of this class
23  * must be of type <code>ExpandItem</code>.
24  * </p><p>
25  * <dl>
26  * <dt><b>Styles:</b></dt>
27  * <dd>V_SCROLL</dd>
28  * <dt><b>Events:</b></dt>
29  * <dd>Expand, Collapse</dd>
30  * </dl>
31  * </p><p>
32  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
33  * </p>
34  *
35  * @see ExpandItem
36  * @see ExpandEvent
37  * @see ExpandListener
38  * @see ExpandAdapter
39  *
40  * @since 3.2
41  */

42 public class ExpandBar extends Composite {
43     ExpandItem[] items;
44     int itemCount;
45     ExpandItem focusItem;
46     int spacing = 4;
47     int yCurrentScroll;
48     int hFont;
49     
50     
51 /**
52  * Constructs a new instance of this class given its parent
53  * and a style value describing its behavior and appearance.
54  * <p>
55  * The style value is either one of the style constants defined in
56  * class <code>SWT</code> which is applicable to instances of this
57  * class, or must be built by <em>bitwise OR</em>'ing together
58  * (that is, using the <code>int</code> "|" operator) two or more
59  * of those <code>SWT</code> style constants. The class description
60  * lists the style constants that are applicable to the class.
61  * Style bits are also inherited from superclasses.
62  * </p>
63  *
64  * @param parent a composite control which will be the parent of the new instance (cannot be null)
65  * @param style the style of control to construct
66  *
67  * @exception IllegalArgumentException <ul>
68  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
69  * </ul>
70  * @exception SWTException <ul>
71  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
72  * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
73  * </ul>
74  *
75  * @see Widget#checkSubclass
76  * @see Widget#getStyle
77  */

78 public ExpandBar (Composite parent, int style) {
79     super (parent, checkStyle (style));
80 }
81
82 /**
83  * Adds the listener to the collection of listeners who will
84  * be notified when an item in the receiver is expanded or collapsed
85  * by sending it one of the messages defined in the <code>ExpandListener</code>
86  * interface.
87  *
88  * @param listener the listener which should be notified
89  *
90  * @exception IllegalArgumentException <ul>
91  * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
92  * </ul>
93  * @exception SWTException <ul>
94  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
95  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
96  * </ul>
97  *
98  * @see ExpandListener
99  * @see #removeExpandListener
100  */

101 public void addExpandListener (ExpandListener listener) {
102     checkWidget ();
103     if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
104     TypedListener typedListener = new TypedListener (listener);
105     addListener (SWT.Expand, typedListener);
106     addListener (SWT.Collapse, typedListener);
107 }
108
109 int callWindowProc (int hwnd, int msg, int wParam, int lParam) {
110     if (handle == 0) return 0;
111     return OS.DefWindowProc (hwnd, msg, wParam, lParam);
112 }
113
114 protected void checkSubclass () {
115     if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
116 }
117
118 static int checkStyle (int style) {
119     style &= ~SWT.H_SCROLL;
120     return style | SWT.NO_BACKGROUND;
121 }
122
123 public Point computeSize (int wHint, int hHint, boolean changed) {
124     checkWidget ();
125     int height = 0, width = 0;
126     if (wHint == SWT.DEFAULT || hHint == SWT.DEFAULT) {
127         if (itemCount > 0) {
128             int hDC = OS.GetDC (handle);
129             int hTheme = 0;
130             if (isAppThemed ()) {
131                 hTheme = display.hExplorerBarTheme ();
132             }
133             int hCurrentFont = 0, oldFont = 0;
134             if (hTheme == 0) {
135                 if (hFont != 0) {
136                     hCurrentFont = hFont;
137                 } else {
138                     if (!OS.IsWinCE) {
139                         NONCLIENTMETRICS info = OS.IsUnicode ? (NONCLIENTMETRICS) new NONCLIENTMETRICSW () : new NONCLIENTMETRICSA ();
140                         info.cbSize = NONCLIENTMETRICS.sizeof;
141                         if (OS.SystemParametersInfo (OS.SPI_GETNONCLIENTMETRICS, 0, info, 0)) {
142                             LOGFONT logFont = OS.IsUnicode ? (LOGFONT) ((NONCLIENTMETRICSW)info).lfCaptionFont : ((NONCLIENTMETRICSA)info).lfCaptionFont;
143                             hCurrentFont = OS.CreateFontIndirect (logFont);
144                         }
145                     }
146                 }
147                 if (hCurrentFont != 0) {
148                     oldFont = OS.SelectObject (hDC, hCurrentFont);
149                 }
150             }
151             height += spacing;
152             for (int i = 0; i < itemCount; i++) {
153                 ExpandItem item = items [i];
154                 height += item.getHeaderHeight ();
155                 if (item.expanded) height += item.height;
156                 height += spacing;
157                 width = Math.max (width, item.getPreferredWidth (hTheme, hDC));
158             }
159             if (hCurrentFont != 0) {
160                 OS.SelectObject (hDC, oldFont);
161                 if (hCurrentFont != hFont) OS.DeleteObject (hCurrentFont);
162             }
163             OS.ReleaseDC (handle, hDC);
164         }
165     }
166     if (width == 0) width = DEFAULT_WIDTH;
167     if (height == 0) height = DEFAULT_HEIGHT;
168     if (wHint != SWT.DEFAULT) width = wHint;
169     if (hHint != SWT.DEFAULT) height = hHint;
170     Rectangle trim = computeTrim (0, 0, width, height);
171     return new Point (trim.width, trim.height);
172 }
173
174 void createHandle () {
175     super.createHandle ();
176     state &= ~CANVAS;
177     state |= TRACK_MOUSE;
178 }
179
180 void createItem (ExpandItem item, int style, int index) {
181     if (!(0 <= index && index <= itemCount)) error (SWT.ERROR_INVALID_RANGE);
182     if (itemCount == items.length) {
183         ExpandItem [] newItems = new ExpandItem [itemCount + 4];
184         System.arraycopy (items, 0, newItems, 0, items.length);
185         items = newItems;
186     }
187     System.arraycopy (items, index, items, index + 1, itemCount - index);
188     items [index] = item;
189     itemCount++;
190     if (focusItem == null) focusItem = item;
191     
192     RECT rect = new RECT ();
193     OS.GetWindowRect (handle, rect);
194     item.width = Math.max (0, rect.right - rect.left - spacing * 2);
195     layoutItems (index, true);
196 }
197
198 void createWidget () {
199     super.createWidget ();
200     items = new ExpandItem [4];
201     if (!isAppThemed ()) {
202         backgroundMode = SWT.INHERIT_DEFAULT;
203     }
204 }
205
206 int defaultBackground() {
207     if (!isAppThemed ()) {
208         return OS.GetSysColor (OS.COLOR_WINDOW);
209     }
210     return super.defaultBackground();
211 }
212
213 void destroyItem (ExpandItem item) {
214     int index = 0;
215     while (index < itemCount) {
216         if (items [index] == item) break;
217         index++;
218     }
219     if (index == itemCount) return;
220     if (item == focusItem) {
221         int focusIndex = index > 0 ? index - 1 : 1;
222         if (focusIndex < itemCount) {
223             focusItem = items [focusIndex];
224             focusItem.redraw (true);
225         } else {
226             focusItem = null;
227         }
228     }
229     System.arraycopy (items, index + 1, items, index, --itemCount - index);
230     items [itemCount] = null;
231     item.redraw (true);
232     layoutItems (index, true);
233 }
234
235 void drawThemeBackground (int hDC, int hwnd, RECT rect) {
236     RECT rect2 = new RECT ();
237     OS.GetClientRect (handle, rect2);
238     OS.MapWindowPoints (handle, hwnd, rect2, 2);
239     OS.DrawThemeBackground (display.hExplorerBarTheme (), hDC, OS.EBP_NORMALGROUPBACKGROUND, 0, rect2, null);
240 }
241
242 void drawWidget (GC gc, RECT clipRect) {
243     int hTheme = 0;
244     if (isAppThemed ()) {
245         hTheme = display.hExplorerBarTheme ();
246     }
247     if (hTheme != 0) {
248         RECT rect = new RECT ();
249         OS.GetClientRect (handle, rect);
250         OS.DrawThemeBackground (hTheme, gc.handle, OS.EBP_HEADERBACKGROUND, 0, rect, clipRect);
251     } else {
252         drawBackground (gc.handle);
253     }
254     boolean drawFocus = false;
255     if (handle == OS.GetFocus ()) {
256         int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
257         drawFocus = (uiState & OS.UISF_HIDEFOCUS) == 0;
258     }
259     int hCaptionFont = 0, oldFont = 0;
260     if (hTheme == 0) {
261         if (!OS.IsWinCE && hFont == 0) {
262             NONCLIENTMETRICS info = OS.IsUnicode ? (NONCLIENTMETRICS) new NONCLIENTMETRICSW () : new NONCLIENTMETRICSA ();
263             info.cbSize = NONCLIENTMETRICS.sizeof;
264             if (OS.SystemParametersInfo (OS.SPI_GETNONCLIENTMETRICS, 0, info, 0)) {
265                 LOGFONT logFont = OS.IsUnicode ? (LOGFONT) ((NONCLIENTMETRICSW)info).lfCaptionFont : ((NONCLIENTMETRICSA)info).lfCaptionFont;
266                 hCaptionFont = OS.CreateFontIndirect (logFont);
267                 oldFont = OS.SelectObject (gc.handle, hCaptionFont);
268             }
269         }
270     }
271     for (int i = 0; i < itemCount; i++) {
272         ExpandItem item = items[i];
273         item.drawItem (gc, hTheme, clipRect, item == focusItem && drawFocus);
274     }
275     if (hCaptionFont != 0) {
276         OS.SelectObject (gc.handle, oldFont);
277         OS.DeleteObject (hCaptionFont);
278     }
279 }
280
281 Control findBackgroundControl () {
282     Control control = super.findBackgroundControl ();
283     if (!isAppThemed ()) {
284         if (control == null) control = this;
285     }
286     return control;
287 }
288
289 Control findThemeControl () {
290     return isAppThemed () ? this : super.findThemeControl ();
291 }
292
293 int getBandHeight () {
294     if (hFont == 0) return ExpandItem.CHEVRON_SIZE;
295     int hDC = OS.GetDC (handle);
296     int oldHFont = OS.SelectObject (hDC, hFont);
297     TEXTMETRIC lptm = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA();
298     OS.GetTextMetrics (hDC, lptm);
299     OS.SelectObject (hDC, oldHFont);
300     OS.ReleaseDC (handle, hDC);
301     return Math.max (ExpandItem.CHEVRON_SIZE, lptm.tmHeight + 4);
302 }
303
304 /**
305  * Returns the item at the given, zero-relative index in the
306  * receiver. Throws an exception if the index is out of range.
307  *
308  * @param index the index of the item to return
309  * @return the item at the given index
310  *
311  * @exception IllegalArgumentException <ul>
312  * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
313  * </ul>
314  * @exception SWTException <ul>
315  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
316  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
317  * </ul>
318  */

319 public ExpandItem getItem (int index) {
320     checkWidget ();
321     if (!(0 <= index && index < itemCount)) error (SWT.ERROR_INVALID_RANGE);
322     return items [index];
323 }
324
325 /**
326  * Returns the number of items contained in the receiver.
327  *
328  * @return the number of items
329  *
330  * @exception SWTException <ul>
331  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
332  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
333  * </ul>
334  */

335 public int getItemCount () {
336     checkWidget ();
337     return itemCount;
338 }
339
340 /**
341  * Returns an array of <code>ExpandItem</code>s which are the items
342  * in the receiver.
343  * <p>
344  * Note: This is not the actual structure used by the receiver
345  * to maintain its list of items, so modifying the array will
346  * not affect the receiver.
347  * </p>
348  *
349  * @return the items in the receiver
350  *
351  * @exception SWTException <ul>
352  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
353  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
354  * </ul>
355  */

356 public ExpandItem [] getItems () {
357     checkWidget ();
358     ExpandItem [] result = new ExpandItem [itemCount];
359     System.arraycopy (items, 0, result, 0, itemCount);
360     return result;
361 }
362
363 /**
364  * Returns the receiver's spacing.
365  *
366  * @return the spacing
367  *
368  * @exception SWTException <ul>
369  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
370  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
371  * </ul>
372  */

373 public int getSpacing () {
374     checkWidget ();
375     return spacing;
376 }
377
378 /**
379  * Searches the receiver's list starting at the first item
380  * (index 0) until an item is found that is equal to the
381  * argument, and returns the index of that item. If no item
382  * is found, returns -1.
383  *
384  * @param item the search item
385  * @return the index of the item
386  *
387  * @exception IllegalArgumentException <ul>
388  * <li>ERROR_NULL_ARGUMENT - if the item is null</li>
389  * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
390  * </ul>
391  * @exception SWTException <ul>
392  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
393  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
394  * </ul>
395  */

396 public int indexOf (ExpandItem item) {
397     checkWidget ();
398     if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
399     for (int i = 0; i < itemCount; i++) {
400         if (items [i] == item) return i;
401     }
402     return -1;
403 }
404
405 boolean isAppThemed () {
406     if (background != -1) return false;
407     if (foreground != -1) return false;
408     if (hFont != 0) return false;
409     return OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ();
410 }
411
412 void layoutItems (int index, boolean setScrollbar) {
413     if (index < itemCount) {
414         int y = spacing - yCurrentScroll;
415         for (int i = 0; i < index; i++) {
416             ExpandItem item = items [i];
417             if (item.expanded) y += item.height;
418             y += item.getHeaderHeight () + spacing;
419         }
420         for (int i = index; i < itemCount; i++) {
421             ExpandItem item = items [i];
422             item.setBounds (spacing, y, 0, 0, true, false);
423             if (item.expanded) y += item.height;
424             y += item.getHeaderHeight () + spacing;
425         }
426     }
427     if (setScrollbar) setScrollbar ();
428 }
429
430 void releaseChildren (boolean destroy) {
431     if (items != null) {
432         for (int i=0; i<items.length; i++) {
433             ExpandItem item = items [i];
434             if (item != null && !item.isDisposed ()) {
435                 item.release (false);
436             }
437         }
438         items = null;
439     }
440     focusItem = null;
441     super.releaseChildren (destroy);
442 }
443
444 /**
445  * Removes the listener from the collection of listeners who will
446  * be notified when items in the receiver are expanded or collapsed.
447  *
448  * @param listener the listener which should no longer be notified
449  *
450  * @exception IllegalArgumentException <ul>
451  * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
452  * </ul>
453  * @exception SWTException <ul>
454  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
455  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
456  * </ul>
457  *
458  * @see ExpandListener
459  * @see #addExpandListener
460  */

461 public void removeExpandListener (ExpandListener listener) {
462     checkWidget ();
463     if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
464     if (eventTable == null) return;
465     eventTable.unhook (SWT.Expand, listener);
466     eventTable.unhook (SWT.Collapse, listener);
467 }
468
469 void setBackgroundPixel (int pixel) {
470     super.setBackgroundPixel (pixel);
471     if (!OS.IsWinCE) {
472         int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE | OS.RDW_ALLCHILDREN;
473         OS.RedrawWindow (handle, null, 0, flags);
474     }
475 }
476
477 public void setFont (Font font) {
478     super.setFont (font);
479     hFont = font != null ? font.handle : 0;
480     layoutItems (0, true);
481 }
482
483 void setForegroundPixel (int pixel) {
484     super.setForegroundPixel (pixel);
485     if (!OS.IsWinCE) {
486         int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE | OS.RDW_ALLCHILDREN;
487         OS.RedrawWindow (handle, null, 0, flags);
488     }
489 }
490
491 void setScrollbar () {
492     if (itemCount == 0) return;
493     if ((style & SWT.V_SCROLL) == 0) return;
494     RECT rect = new RECT();
495     OS.GetClientRect (handle, rect);
496     int height = rect.bottom - rect.top;
497     ExpandItem item = items [itemCount - 1];
498     int maxHeight = item.y + getBandHeight () + spacing;
499     if (item.expanded) maxHeight += item.height;
500
501     //claim bottom free space
502
if (yCurrentScroll > 0 && height > maxHeight) {
503         yCurrentScroll = Math.max (0, yCurrentScroll + maxHeight - height);
504         layoutItems (0, false);
505     }
506     maxHeight += yCurrentScroll;
507     
508     SCROLLINFO info = new SCROLLINFO ();
509     info.cbSize = SCROLLINFO.sizeof;
510     info.fMask = OS.SIF_RANGE | OS.SIF_PAGE | OS.SIF_POS;
511     info.nMin = 0;
512     info.nMax = maxHeight;
513     info.nPage = height;
514     info.nPos = Math.min (yCurrentScroll, info.nMax);
515     if (info.nPage != 0) info.nPage++;
516     OS.SetScrollInfo (handle, OS.SB_VERT, info, true);
517 }
518
519 /**
520  * Sets the receiver's spacing. Spacing specifies the number of pixels allocated around
521  * each item.
522  *
523  * @exception SWTException <ul>
524  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
525  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
526  * </ul>
527  */

528 public void setSpacing (int spacing) {
529     checkWidget ();
530     if (spacing < 0) return;
531     if (spacing == this.spacing) return;
532     this.spacing = spacing;
533     RECT rect = new RECT ();
534     OS.GetClientRect (handle, rect);
535     int width = Math.max (0, (rect.right - rect.left) - spacing * 2);
536     for (int i = 0; i < itemCount; i++) {
537         ExpandItem item = items[i];
538         if (item.width != width) item.setBounds (0, 0, width, item.height, false, true);
539     }
540     layoutItems (0, true);
541     OS.InvalidateRect (handle, null, true);
542 }
543
544 void showItem (ExpandItem item) {
545     Control control = item.control;
546     if (control != null && !control.isDisposed ()) {
547         control.setVisible (item.expanded);
548     }
549     item.redraw (true);
550     int index = indexOf (item);
551     layoutItems (index + 1, true);
552 }
553
554 TCHAR windowClass () {
555     return display.windowClass;
556 }
557
558 int windowProc () {
559     return display.windowProc;
560 }
561
562 LRESULT WM_KEYDOWN (int wParam, int lParam) {
563     LRESULT result = super.WM_KEYDOWN (wParam, lParam);
564     if (result != null) return result;
565     if (focusItem == null) return result;
566     switch (wParam) {
567         case OS.VK_SPACE:
568         case OS.VK_RETURN:
569             Event event = new Event ();
570             event.item = focusItem;
571             sendEvent (focusItem.expanded ? SWT.Collapse : SWT.Expand, event);
572             focusItem.expanded = !focusItem.expanded;
573             showItem (focusItem);
574             return LRESULT.ZERO;
575         case OS.VK_UP: {
576             int focusIndex = indexOf (focusItem);
577             if (focusIndex > 0) {
578                 focusItem.redraw (true);
579                 focusItem = items [focusIndex - 1];
580                 focusItem.redraw (true);
581                 return LRESULT.ZERO;
582             }
583             break;
584         }
585         case OS.VK_DOWN: {
586             int focusIndex = indexOf (focusItem);
587             if (focusIndex < itemCount - 1) {
588                 focusItem.redraw (true);
589                 focusItem = items [focusIndex + 1];
590                 focusItem.redraw (true);
591                 return LRESULT.ZERO;
592             }
593             break;
594         }
595     }
596     return result;
597 }
598
599 LRESULT WM_KILLFOCUS (int wParam, int lParam) {
600     LRESULT result = super.WM_KILLFOCUS (wParam, lParam);
601     if (focusItem != null) focusItem.redraw (true);
602     return result;
603 }
604
605 LRESULT WM_LBUTTONDOWN (int wParam, int lParam) {
606     LRESULT result = super.WM_LBUTTONDOWN (wParam, lParam);
607     if (result == LRESULT.ZERO) return result;
608     int x = (short) (lParam & 0xFFFF);
609     int y = (short) (lParam >> 16);
610     for (int i = 0; i < itemCount; i++) {
611         ExpandItem item = items[i];
612         boolean hover = item.isHover (x, y);
613         if (hover && focusItem != item) {
614             focusItem.redraw (true);
615             focusItem = item;
616             focusItem.redraw (true);
617             forceFocus ();
618             break;
619         }
620     }
621     return result;
622 }
623
624 LRESULT WM_LBUTTONUP (int wParam, int lParam) {
625     LRESULT result = super.WM_LBUTTONUP (wParam, lParam);
626     if (result == LRESULT.ZERO) return result;
627     if (focusItem == null) return result;
628     int x = (short) (lParam & 0xFFFF);
629     int y = (short) (lParam >> 16);
630     boolean hover = focusItem.isHover (x, y);
631     if (hover) {
632         Event event = new Event ();
633         event.item = focusItem;
634         sendEvent (focusItem.expanded ? SWT.Collapse : SWT.Expand, event);
635         focusItem.expanded = !focusItem.expanded;
636         showItem (focusItem);
637     }
638     return result;
639 }
640
641 LRESULT WM_MOUSELEAVE (int wParam, int lParam) {
642     LRESULT result = super.WM_MOUSELEAVE (wParam, lParam);
643     if (result != null) return result;
644     for (int i = 0; i < itemCount; i++) {
645         ExpandItem item = items [i];
646         if (item.hover) {
647             item.hover = false;
648             item.redraw (false);
649             break;
650         }
651     }
652     return result;
653 }
654
655 LRESULT WM_MOUSEMOVE (int wParam, int lParam) {
656     LRESULT result = super.WM_MOUSEMOVE (wParam, lParam);
657     if (result == LRESULT.ZERO) return result;
658     int x = (short) (lParam & 0xFFFF);
659     int y = (short) (lParam >> 16);
660     for (int i = 0; i < itemCount; i++) {
661         ExpandItem item = items [i];
662         boolean hover = item.isHover (x, y);
663         if (item.hover != hover) {
664             item.hover = hover;
665             item.redraw (false);
666         }
667     }
668     return result;
669 }
670
671 LRESULT WM_PAINT (int wParam, int lParam) {
672     PAINTSTRUCT ps = new PAINTSTRUCT ();
673     GCData data = new GCData ();
674     data.ps = ps;
675     data.hwnd = handle;
676     GC gc = new_GC (data);
677     if (gc != null) {
678         int width = ps.right - ps.left;
679         int height = ps.bottom - ps.top;
680         if (width != 0 && height != 0) {
681             RECT rect = new RECT ();
682             OS.SetRect (rect, ps.left, ps.top, ps.right, ps.bottom);
683             drawWidget (gc, rect);
684             if (hooks (SWT.Paint) || filters (SWT.Paint)) {
685                 Event event = new Event ();
686                 event.gc = gc;
687                 event.x = rect.left;
688                 event.y = rect.top;
689                 event.width = width;
690                 event.height = height;
691                 sendEvent (SWT.Paint, event);
692                 event.gc = null;
693             }
694         }
695         gc.dispose ();
696     }
697     return LRESULT.ZERO;
698 }
699
700 LRESULT WM_PRINTCLIENT (int wParam, int lParam) {
701     LRESULT result = super.WM_PRINTCLIENT (wParam, lParam);
702     RECT rect = new RECT ();
703     OS.GetClientRect (handle, rect);
704     GCData data = new GCData ();
705     data.device = display;
706     data.foreground = getForegroundPixel ();
707     GC gc = GC.win32_new (wParam, data);
708     drawWidget (gc, rect);
709     gc.dispose ();
710     return result;
711 }
712
713 LRESULT WM_SETCURSOR (int wParam, int lParam) {
714     LRESULT result = super.WM_SETCURSOR (wParam, lParam);
715     if (result != null) return result;
716     int hitTest = lParam & 0xFFFF;
717     if (hitTest == OS.HTCLIENT) {
718         for (int i = 0; i < itemCount; i++) {
719             ExpandItem item = items [i];
720             if (item.hover) {
721                 int hCursor = OS.LoadCursor (0, OS.IDC_HAND);
722                 OS.SetCursor (hCursor);
723                 return LRESULT.ONE;
724             }
725         }
726     }
727     return result;
728 }
729
730 LRESULT WM_SETFOCUS (int wParam, int lParam) {
731     LRESULT result = super.WM_SETFOCUS (wParam, lParam);
732     if (focusItem != null) focusItem.redraw (true);
733     return result;
734 }
735
736 LRESULT WM_SIZE (int wParam, int lParam) {
737     LRESULT result = super.WM_SIZE (wParam, lParam);
738     RECT rect = new RECT ();
739     OS.GetClientRect (handle, rect);
740     int width = Math.max (0, (rect.right - rect.left) - spacing * 2);
741     for (int i = 0; i < itemCount; i++) {
742         ExpandItem item = items[i];
743         if (item.width != width) item.setBounds (0, 0, width, item.height, false, true);
744     }
745     setScrollbar ();
746     OS.InvalidateRect (handle, null, true);
747     return result;
748 }
749
750 LRESULT wmScroll (ScrollBar bar, boolean update, int hwnd, int msg, int wParam, int lParam) {
751     LRESULT result = super.wmScroll (bar, true, hwnd, msg, wParam, lParam);
752     SCROLLINFO info = new SCROLLINFO ();
753     info.cbSize = SCROLLINFO.sizeof;
754     info.fMask = OS.SIF_POS;
755     OS.GetScrollInfo (handle, OS.SB_VERT, info);
756     int updateY = yCurrentScroll - info.nPos;
757     OS.ScrollWindowEx (handle, 0, updateY, null, null, 0, null, OS.SW_SCROLLCHILDREN | OS.SW_INVALIDATE);
758     yCurrentScroll = info.nPos;
759     if (updateY != 0) {
760         for (int i = 0; i < itemCount; i++) {
761             items [i].y += updateY;
762         }
763     }
764     return result;
765 }
766 }
767
Popular Tags