comparison org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/widgets/ExpandBar.d @ 0:6dd524f61e62

add dwt win and basic java stuff
author Frank Benoit <benoit@tionex.de>
date Mon, 02 Mar 2009 14:44:16 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:6dd524f61e62
1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 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 org.eclipse.swt.widgets.ExpandBar;
14
15
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.SWTException;
18 import org.eclipse.swt.events.ExpandAdapter;
19 import org.eclipse.swt.events.ExpandEvent;
20 import org.eclipse.swt.events.ExpandListener;
21 import org.eclipse.swt.graphics.Font;
22 import org.eclipse.swt.graphics.GC;
23 import org.eclipse.swt.graphics.GCData;
24 import org.eclipse.swt.graphics.Point;
25 import org.eclipse.swt.graphics.Rectangle;
26 import org.eclipse.swt.graphics.Drawable;
27 import org.eclipse.swt.internal.win32.OS;
28
29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Control;
31 import org.eclipse.swt.widgets.ExpandItem;
32 import org.eclipse.swt.widgets.ScrollBar;
33 import org.eclipse.swt.widgets.ExpandItem;
34 import org.eclipse.swt.widgets.TypedListener;
35 import org.eclipse.swt.widgets.Event;
36
37 import java.lang.all;
38
39 /**
40 * Instances of this class support the layout of selectable
41 * expand bar items.
42 * <p>
43 * The item children that may be added to instances of this class
44 * must be of type <code>ExpandItem</code>.
45 * </p><p>
46 * <dl>
47 * <dt><b>Styles:</b></dt>
48 * <dd>V_SCROLL</dd>
49 * <dt><b>Events:</b></dt>
50 * <dd>Expand, Collapse</dd>
51 * </dl>
52 * </p><p>
53 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
54 * </p>
55 *
56 * @see ExpandItem
57 * @see ExpandEvent
58 * @see ExpandListener
59 * @see ExpandAdapter
60 * @see <a href="http://www.eclipse.org/swt/snippets/#expandbar">ExpandBar snippets</a>
61 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample</a>
62 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
63 *
64 * @since 3.2
65 */
66 public class ExpandBar : Composite {
67
68 alias Composite.computeSize computeSize;
69 alias Composite.windowProc windowProc;
70
71 ExpandItem[] items;
72 int itemCount;
73 ExpandItem focusItem;
74 int spacing = 4;
75 int yCurrentScroll;
76 HFONT hFont;
77
78
79 /**
80 * Constructs a new instance of this class given its parent
81 * and a style value describing its behavior and appearance.
82 * <p>
83 * The style value is either one of the style constants defined in
84 * class <code>SWT</code> which is applicable to instances of this
85 * class, or must be built by <em>bitwise OR</em>'ing together
86 * (that is, using the <code>int</code> "|" operator) two or more
87 * of those <code>SWT</code> style constants. The class description
88 * lists the style constants that are applicable to the class.
89 * Style bits are also inherited from superclasses.
90 * </p>
91 *
92 * @param parent a composite control which will be the parent of the new instance (cannot be null)
93 * @param style the style of control to construct
94 *
95 * @exception IllegalArgumentException <ul>
96 * <li>ERROR_NULL_ARGUMENT - if the parent is null</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 this (Composite parent, int style) {
107 super (parent, checkStyle (style));
108 }
109
110 /**
111 * Adds the listener to the collection of listeners who will
112 * be notified when an item in the receiver is expanded or collapsed
113 * by sending it one of the messages defined in the <code>ExpandListener</code>
114 * interface.
115 *
116 * @param listener the listener which should be notified
117 *
118 * @exception IllegalArgumentException <ul>
119 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
120 * </ul>
121 * @exception SWTException <ul>
122 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
123 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
124 * </ul>
125 *
126 * @see ExpandListener
127 * @see #removeExpandListener
128 */
129 public void addExpandListener (ExpandListener listener) {
130 checkWidget ();
131 if (listener is null) error (SWT.ERROR_NULL_ARGUMENT);
132 TypedListener typedListener = new TypedListener (listener);
133 addListener (SWT.Expand, typedListener);
134 addListener (SWT.Collapse, typedListener);
135 }
136
137 override int callWindowProc (HWND hwnd, int msg, int wParam, int lParam) {
138 if (handle is null) return 0;
139 return OS.DefWindowProc (hwnd, msg, wParam, lParam);
140 }
141
142 override protected void checkSubclass () {
143 if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
144 }
145
146 static int checkStyle (int style) {
147 style &= ~SWT.H_SCROLL;
148 return style | SWT.NO_BACKGROUND;
149 }
150
151 override public Point computeSize (int wHint, int hHint, bool changed) {
152 checkWidget ();
153 int height = 0, width = 0;
154 if (wHint is SWT.DEFAULT || hHint is SWT.DEFAULT) {
155 if (itemCount > 0) {
156 auto hDC = OS.GetDC (handle);
157 HTHEME hTheme;
158 if (isAppThemed ()) {
159 hTheme = display.hExplorerBarTheme ();
160 }
161 HFONT hCurrentFont, oldFont;
162 if (hTheme is null) {
163 if (hFont !is null) {
164 hCurrentFont = hFont;
165 } else {
166 static if (!OS.IsWinCE) {
167 NONCLIENTMETRICS info;
168 info.cbSize = NONCLIENTMETRICS.sizeof;
169 if (OS.SystemParametersInfo (OS.SPI_GETNONCLIENTMETRICS, 0, &info, 0)) {
170 LOGFONT* logFont = &info.lfCaptionFont;
171 hCurrentFont = OS.CreateFontIndirect (logFont);
172 }
173 }
174 }
175 if (hCurrentFont !is null) {
176 oldFont = OS.SelectObject (hDC, hCurrentFont);
177 }
178 }
179 height += spacing;
180 for (int i = 0; i < itemCount; i++) {
181 ExpandItem item = items [i];
182 height += item.getHeaderHeight ();
183 if (item.expanded) height += item.height;
184 height += spacing;
185 width = Math.max (width, item.getPreferredWidth (hTheme, hDC));
186 }
187 if (hCurrentFont !is null) {
188 OS.SelectObject (hDC, oldFont);
189 if (hCurrentFont !is hFont) OS.DeleteObject (hCurrentFont);
190 }
191 OS.ReleaseDC (handle, hDC);
192 }
193 }
194 if (width is 0) width = DEFAULT_WIDTH;
195 if (height is 0) height = DEFAULT_HEIGHT;
196 if (wHint !is SWT.DEFAULT) width = wHint;
197 if (hHint !is SWT.DEFAULT) height = hHint;
198 Rectangle trim = computeTrim (0, 0, width, height);
199 return new Point (trim.width, trim.height);
200 }
201
202 override void createHandle () {
203 super.createHandle ();
204 state &= ~CANVAS;
205 state |= TRACK_MOUSE;
206 }
207
208 void createItem (ExpandItem item, int style, int index) {
209 if (!(0 <= index && index <= itemCount)) error (SWT.ERROR_INVALID_RANGE);
210 if (itemCount is items.length) {
211 ExpandItem [] newItems = new ExpandItem [itemCount + 4];
212 System.arraycopy (items, 0, newItems, 0, items.length);
213 items = newItems;
214 }
215 System.arraycopy (items, index, items, index + 1, itemCount - index);
216 items [index] = item;
217 itemCount++;
218 if (focusItem is null) focusItem = item;
219
220 RECT rect;
221 OS.GetWindowRect (handle, &rect);
222 item.width = Math.max (0, rect.right - rect.left - spacing * 2);
223 layoutItems (index, true);
224 }
225
226 override void createWidget () {
227 super.createWidget ();
228 items = new ExpandItem [4];
229 if (!isAppThemed ()) {
230 backgroundMode = SWT.INHERIT_DEFAULT;
231 }
232 }
233
234 override int defaultBackground() {
235 if (!isAppThemed ()) {
236 return OS.GetSysColor (OS.COLOR_WINDOW);
237 }
238 return super.defaultBackground();
239 }
240
241 void destroyItem (ExpandItem item) {
242 int index = 0;
243 while (index < itemCount) {
244 if (items [index] is item) break;
245 index++;
246 }
247 if (index is itemCount) return;
248 if (item is focusItem) {
249 int focusIndex = index > 0 ? index - 1 : 1;
250 if (focusIndex < itemCount) {
251 focusItem = items [focusIndex];
252 focusItem.redraw (true);
253 } else {
254 focusItem = null;
255 }
256 }
257 System.arraycopy (items, index + 1, items, index, --itemCount - index);
258 items [itemCount] = null;
259 item.redraw (true);
260 layoutItems (index, true);
261 }
262
263 override void drawThemeBackground (HDC hDC, HWND hwnd, RECT* rect) {
264 RECT rect2;
265 OS.GetClientRect (handle, &rect2);
266 OS.MapWindowPoints (handle, hwnd, cast(POINT*) &rect2, 2);
267 OS.DrawThemeBackground (display.hExplorerBarTheme (), hDC, OS.EBP_NORMALGROUPBACKGROUND, 0, &rect2, null);
268 }
269
270 void drawWidget (GC gc, RECT* clipRect) {
271 HTHEME hTheme;
272 if (isAppThemed ()) {
273 hTheme = display.hExplorerBarTheme ();
274 }
275 if (hTheme !is null) {
276 RECT rect;
277 OS.GetClientRect (handle, &rect);
278 OS.DrawThemeBackground (hTheme, gc.handle, OS.EBP_HEADERBACKGROUND, 0, &rect, clipRect);
279 } else {
280 drawBackground (gc.handle);
281 }
282 bool drawFocus = false;
283 if (handle is OS.GetFocus ()) {
284 int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
285 drawFocus = (uiState & OS.UISF_HIDEFOCUS) is 0;
286 }
287 HFONT hCurrentFont, oldFont;
288 if (hTheme is null) {
289 if (hFont !is null) {
290 hCurrentFont = hFont;
291 } else {
292 if (!OS.IsWinCE) {
293 NONCLIENTMETRICS info;
294 info.cbSize = NONCLIENTMETRICS.sizeof;
295 if (OS.SystemParametersInfo (OS.SPI_GETNONCLIENTMETRICS, 0, &info, 0)) {
296 LOGFONT* logFont = &info.lfCaptionFont;
297 hCurrentFont = OS.CreateFontIndirect (logFont);
298 }
299 }
300 }
301 if (hCurrentFont !is null) {
302 oldFont = OS.SelectObject (gc.handle, hCurrentFont);
303 }
304 if (foreground !is -1) {
305 OS.SetTextColor (gc.handle, foreground);
306 }
307 }
308 for (int i = 0; i < itemCount; i++) {
309 ExpandItem item = items[i];
310 item.drawItem (gc, hTheme, clipRect, item is focusItem && drawFocus);
311 }
312 if (hCurrentFont !is null) {
313 OS.SelectObject (gc.handle, oldFont);
314 if (hCurrentFont !is hFont) OS.DeleteObject (hCurrentFont);
315 }
316 }
317
318 override Control findBackgroundControl () {
319 Control control = super.findBackgroundControl ();
320 if (!isAppThemed ()) {
321 if (control is null) control = this;
322 }
323 return control;
324 }
325
326 override Control findThemeControl () {
327 return isAppThemed () ? this : super.findThemeControl ();
328 }
329
330 int getBandHeight () {
331 if (hFont is null) return ExpandItem.CHEVRON_SIZE;
332 auto hDC = OS.GetDC (handle);
333 auto oldHFont = OS.SelectObject (hDC, hFont);
334 TEXTMETRIC lptm;
335 OS.GetTextMetrics (hDC, &lptm);
336 OS.SelectObject (hDC, oldHFont);
337 OS.ReleaseDC (handle, hDC);
338 return Math.max (ExpandItem.CHEVRON_SIZE, lptm.tmHeight + 4);
339 }
340
341 /**
342 * Returns the item at the given, zero-relative index in the
343 * receiver. Throws an exception if the index is out of range.
344 *
345 * @param index the index of the item to return
346 * @return the item at the given index
347 *
348 * @exception IllegalArgumentException <ul>
349 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
350 * </ul>
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 getItem (int index) {
357 checkWidget ();
358 if (!(0 <= index && index < itemCount)) error (SWT.ERROR_INVALID_RANGE);
359 return items [index];
360 }
361
362 /**
363 * Returns the number of items contained in the receiver.
364 *
365 * @return the number of items
366 *
367 * @exception SWTException <ul>
368 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
369 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
370 * </ul>
371 */
372 public int getItemCount () {
373 checkWidget ();
374 return itemCount;
375 }
376
377 /**
378 * Returns an array of <code>ExpandItem</code>s which are the items
379 * in the receiver.
380 * <p>
381 * Note: This is not the actual structure used by the receiver
382 * to maintain its list of items, so modifying the array will
383 * not affect the receiver.
384 * </p>
385 *
386 * @return the items in the receiver
387 *
388 * @exception SWTException <ul>
389 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
390 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
391 * </ul>
392 */
393 public ExpandItem [] getItems () {
394 checkWidget ();
395 ExpandItem [] result = new ExpandItem [itemCount];
396 System.arraycopy (items, 0, result, 0, itemCount);
397 return result;
398 }
399
400 /**
401 * Returns the receiver's spacing.
402 *
403 * @return the spacing
404 *
405 * @exception SWTException <ul>
406 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
407 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
408 * </ul>
409 */
410 public int getSpacing () {
411 checkWidget ();
412 return spacing;
413 }
414
415 /**
416 * Searches the receiver's list starting at the first item
417 * (index 0) until an item is found that is equal to the
418 * argument, and returns the index of that item. If no item
419 * is found, returns -1.
420 *
421 * @param item the search item
422 * @return the index of the item
423 *
424 * @exception IllegalArgumentException <ul>
425 * <li>ERROR_NULL_ARGUMENT - if the item is null</li>
426 * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
427 * </ul>
428 * @exception SWTException <ul>
429 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
430 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
431 * </ul>
432 */
433 public int indexOf (ExpandItem item) {
434 checkWidget ();
435 if (item is null) error (SWT.ERROR_NULL_ARGUMENT);
436 for (int i = 0; i < itemCount; i++) {
437 if (items [i] is item) return i;
438 }
439 return -1;
440 }
441
442 bool isAppThemed () {
443 if (background !is -1) return false;
444 if (foreground !is -1) return false;
445 if (hFont !is null) return false;
446 return OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ();
447 }
448
449 void layoutItems (int index, bool setScrollbar_) {
450 if (index < itemCount) {
451 int y = spacing - yCurrentScroll;
452 for (int i = 0; i < index; i++) {
453 ExpandItem item = items [i];
454 if (item.expanded) y += item.height;
455 y += item.getHeaderHeight () + spacing;
456 }
457 for (int i = index; i < itemCount; i++) {
458 ExpandItem item = items [i];
459 item.setBounds (spacing, y, 0, 0, true, false);
460 if (item.expanded) y += item.height;
461 y += item.getHeaderHeight () + spacing;
462 }
463 }
464 if (setScrollbar_) setScrollbar ();
465 }
466
467 override void releaseChildren (bool destroy) {
468 if (items !is null) {
469 for (int i=0; i<items.length; i++) {
470 ExpandItem item = items [i];
471 if (item !is null && !item.isDisposed ()) {
472 item.release (false);
473 }
474 }
475 items = null;
476 }
477 focusItem = null;
478 super.releaseChildren (destroy);
479 }
480
481 /**
482 * Removes the listener from the collection of listeners who will
483 * be notified when items in the receiver are expanded or collapsed.
484 *
485 * @param listener the listener which should no longer be notified
486 *
487 * @exception IllegalArgumentException <ul>
488 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
489 * </ul>
490 * @exception SWTException <ul>
491 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
492 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
493 * </ul>
494 *
495 * @see ExpandListener
496 * @see #addExpandListener
497 */
498 public void removeExpandListener (ExpandListener listener) {
499 checkWidget ();
500 if (listener is null) error (SWT.ERROR_NULL_ARGUMENT);
501 if (eventTable is null) return;
502 eventTable.unhook (SWT.Expand, listener);
503 eventTable.unhook (SWT.Collapse, listener);
504 }
505
506 override void setBackgroundPixel (int pixel) {
507 super.setBackgroundPixel (pixel);
508 static if (!OS.IsWinCE) {
509 int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE | OS.RDW_ALLCHILDREN;
510 OS.RedrawWindow (handle, null, null, flags);
511 }
512 }
513
514 override public void setFont (Font font) {
515 super.setFont (font);
516 hFont = font !is null ? font.handle : null;
517 layoutItems (0, true);
518 }
519
520 override void setForegroundPixel (int pixel) {
521 super.setForegroundPixel (pixel);
522 static if (!OS.IsWinCE) {
523 int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE | OS.RDW_ALLCHILDREN;
524 OS.RedrawWindow (handle, null, null, flags);
525 }
526 }
527
528 void setScrollbar () {
529 if (itemCount is 0) return;
530 if ((style & SWT.V_SCROLL) is 0) return;
531 RECT rect;
532 OS.GetClientRect (handle, &rect);
533 int height = rect.bottom - rect.top;
534 ExpandItem item = items [itemCount - 1];
535 int maxHeight = item.y + getBandHeight () + spacing;
536 if (item.expanded) maxHeight += item.height;
537
538 //claim bottom free space
539 if (yCurrentScroll > 0 && height > maxHeight) {
540 yCurrentScroll = Math.max (0, yCurrentScroll + maxHeight - height);
541 layoutItems (0, false);
542 }
543 maxHeight += yCurrentScroll;
544
545 SCROLLINFO info;
546 info.cbSize = SCROLLINFO.sizeof;
547 info.fMask = OS.SIF_RANGE | OS.SIF_PAGE | OS.SIF_POS;
548 info.nMin = 0;
549 info.nMax = maxHeight;
550 info.nPage = height;
551 info.nPos = Math.min (yCurrentScroll, info.nMax);
552 if (info.nPage !is 0) info.nPage++;
553 OS.SetScrollInfo (handle, OS.SB_VERT, &info, true);
554 }
555
556 /**
557 * Sets the receiver's spacing. Spacing specifies the number of pixels allocated around
558 * each item.
559 *
560 * @param spacing the spacing around each item
561 *
562 * @exception SWTException <ul>
563 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
564 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
565 * </ul>
566 */
567 public void setSpacing (int spacing) {
568 checkWidget ();
569 if (spacing < 0) return;
570 if (spacing is this.spacing) return;
571 this.spacing = spacing;
572 RECT rect;
573 OS.GetClientRect (handle, &rect);
574 int width = Math.max (0, (rect.right - rect.left) - spacing * 2);
575 for (int i = 0; i < itemCount; i++) {
576 ExpandItem item = items[i];
577 if (item.width !is width) item.setBounds (0, 0, width, item.height, false, true);
578 }
579 layoutItems (0, true);
580 OS.InvalidateRect (handle, null, true);
581 }
582
583 void showItem (ExpandItem item) {
584 Control control = item.control;
585 if (control !is null && !control.isDisposed ()) {
586 control.setVisible (item.expanded);
587 }
588 item.redraw (true);
589 int index = indexOf (item);
590 layoutItems (index + 1, true);
591 }
592
593 void showFocus (bool up) {
594 RECT rect;
595 OS.GetClientRect (handle, &rect);
596 int height = rect.bottom - rect.top;
597 int updateY = 0;
598 if (up) {
599 if (focusItem.y < 0) {
600 updateY = Math.min (yCurrentScroll, -focusItem.y);
601 }
602 } else {
603 int itemHeight = focusItem.y + getBandHeight ();
604 if (focusItem.expanded) {
605 if (height >= getBandHeight () + focusItem.height) {
606 itemHeight += focusItem.height;
607 }
608 }
609 if (itemHeight > height) {
610 updateY = height - itemHeight;
611 }
612 }
613 if (updateY !is 0) {
614 yCurrentScroll = Math.max (0, yCurrentScroll - updateY);
615 if ((style & SWT.V_SCROLL) !is 0) {
616 SCROLLINFO info;
617 info.cbSize = SCROLLINFO.sizeof;
618 info.fMask = OS.SIF_POS;
619 info.nPos = yCurrentScroll;
620 OS.SetScrollInfo (handle, OS.SB_VERT, &info, true);
621 }
622 OS.ScrollWindowEx (handle, 0, updateY, null, null, null, null, OS.SW_SCROLLCHILDREN | OS.SW_INVALIDATE);
623 for (int i = 0; i < itemCount; i++) {
624 items [i].y += updateY;
625 }
626 }
627 }
628
629 override String windowClass () {
630 return display.windowClass;
631 }
632
633 override int windowProc () {
634 return cast(int) display.windowProc;
635 }
636
637 override LRESULT WM_KEYDOWN (int wParam, int lParam) {
638 LRESULT result = super.WM_KEYDOWN (wParam, lParam);
639 if (result !is null) return result;
640 if (focusItem is null) return result;
641 switch (wParam) {
642 case OS.VK_SPACE:
643 case OS.VK_RETURN:
644 Event event = new Event ();
645 event.item = focusItem;
646 sendEvent (focusItem.expanded ? SWT.Collapse : SWT.Expand, event);
647 focusItem.expanded = !focusItem.expanded;
648 showItem (focusItem);
649 return LRESULT.ZERO;
650 case OS.VK_UP: {
651 int focusIndex = indexOf (focusItem);
652 if (focusIndex > 0) {
653 focusItem.redraw (true);
654 focusItem = items [focusIndex - 1];
655 focusItem.redraw (true);
656 showFocus (true);
657 return LRESULT.ZERO;
658 }
659 break;
660 }
661 case OS.VK_DOWN: {
662 int focusIndex = indexOf (focusItem);
663 if (focusIndex < itemCount - 1) {
664 focusItem.redraw (true);
665 focusItem = items [focusIndex + 1];
666 focusItem.redraw (true);
667 showFocus (false);
668 return LRESULT.ZERO;
669 }
670 break;
671 }
672 default:
673 }
674 return result;
675 }
676
677 override LRESULT WM_KILLFOCUS (int wParam, int lParam) {
678 LRESULT result = super.WM_KILLFOCUS (wParam, lParam);
679 if (focusItem !is null) focusItem.redraw (true);
680 return result;
681 }
682
683 override LRESULT WM_LBUTTONDOWN (int wParam, int lParam) {
684 LRESULT result = super.WM_LBUTTONDOWN (wParam, lParam);
685 if (result is LRESULT.ZERO) return result;
686 int x = OS.GET_X_LPARAM (lParam);
687 int y = OS.GET_Y_LPARAM (lParam);
688 for (int i = 0; i < itemCount; i++) {
689 ExpandItem item = items[i];
690 bool hover = item.isHover (x, y);
691 if (hover && focusItem !is item) {
692 focusItem.redraw (true);
693 focusItem = item;
694 focusItem.redraw (true);
695 forceFocus ();
696 break;
697 }
698 }
699 return result;
700 }
701
702 override LRESULT WM_LBUTTONUP (int wParam, int lParam) {
703 LRESULT result = super.WM_LBUTTONUP (wParam, lParam);
704 if (result is LRESULT.ZERO) return result;
705 if (focusItem is null) return result;
706 int x = OS.GET_X_LPARAM (lParam);
707 int y = OS.GET_Y_LPARAM (lParam);
708 bool hover = focusItem.isHover (x, y);
709 if (hover) {
710 Event event = new Event ();
711 event.item = focusItem;
712 sendEvent (focusItem.expanded ? SWT.Collapse : SWT.Expand, event);
713 focusItem.expanded = !focusItem.expanded;
714 showItem (focusItem);
715 }
716 return result;
717 }
718
719 override LRESULT WM_MOUSELEAVE (int wParam, int lParam) {
720 LRESULT result = super.WM_MOUSELEAVE (wParam, lParam);
721 if (result !is null) return result;
722 for (int i = 0; i < itemCount; i++) {
723 ExpandItem item = items [i];
724 if (item.hover) {
725 item.hover = false;
726 item.redraw (false);
727 break;
728 }
729 }
730 return result;
731 }
732
733 override LRESULT WM_MOUSEMOVE (int wParam, int lParam) {
734 LRESULT result = super.WM_MOUSEMOVE (wParam, lParam);
735 if (result is LRESULT.ZERO) return result;
736 int x = OS.GET_X_LPARAM (lParam);
737 int y = OS.GET_Y_LPARAM (lParam);
738 for (int i = 0; i < itemCount; i++) {
739 ExpandItem item = items [i];
740 bool hover = item.isHover (x, y);
741 if (item.hover !is hover) {
742 item.hover = hover;
743 item.redraw (false);
744 }
745 }
746 return result;
747 }
748
749 override LRESULT WM_PAINT (int wParam, int lParam) {
750 PAINTSTRUCT ps;
751 GCData data = new GCData ();
752 data.ps = &ps;
753 data.hwnd = handle;
754 GC gc = new_GC (data);
755 if (gc !is null) {
756 int width = ps.rcPaint.right - ps.rcPaint.left;
757 int height = ps.rcPaint.bottom - ps.rcPaint.top;
758 if (width !is 0 && height !is 0) {
759 RECT rect;
760 OS.SetRect (&rect, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);
761 drawWidget (gc, &rect);
762 if (hooks (SWT.Paint) || filters (SWT.Paint)) {
763 Event event = new Event ();
764 event.gc = gc;
765 event.x = rect.left;
766 event.y = rect.top;
767 event.width = width;
768 event.height = height;
769 sendEvent (SWT.Paint, event);
770 event.gc = null;
771 }
772 }
773 gc.dispose ();
774 }
775 return LRESULT.ZERO;
776 }
777
778 override LRESULT WM_PRINTCLIENT (int wParam, int lParam) {
779 LRESULT result = super.WM_PRINTCLIENT (wParam, lParam);
780 RECT rect;
781 OS.GetClientRect (handle, &rect);
782 GCData data = new GCData ();
783 data.device = display;
784 data.foreground = getForegroundPixel ();
785 GC gc = GC.win32_new ( cast(Drawable)cast(void*)wParam, data);
786 drawWidget (gc, &rect);
787 gc.dispose ();
788 return result;
789 }
790
791 override LRESULT WM_SETCURSOR (int wParam, int lParam) {
792 LRESULT result = super.WM_SETCURSOR (wParam, lParam);
793 if (result !is null) return result;
794 int hitTest = cast(short) OS.LOWORD (lParam);
795 if (hitTest is OS.HTCLIENT) {
796 for (int i = 0; i < itemCount; i++) {
797 ExpandItem item = items [i];
798 if (item.hover) {
799 auto hCursor = OS.LoadCursor (null, OS.IDC_HAND);
800 OS.SetCursor (hCursor);
801 return LRESULT.ONE;
802 }
803 }
804 }
805 return result;
806 }
807
808 override LRESULT WM_SETFOCUS (int wParam, int lParam) {
809 LRESULT result = super.WM_SETFOCUS (wParam, lParam);
810 if (focusItem !is null) focusItem.redraw (true);
811 return result;
812 }
813
814 override LRESULT WM_SIZE (int wParam, int lParam) {
815 LRESULT result = super.WM_SIZE (wParam, lParam);
816 RECT rect;
817 OS.GetClientRect (handle, &rect);
818 int width = Math.max (0, (rect.right - rect.left) - spacing * 2);
819 for (int i = 0; i < itemCount; i++) {
820 ExpandItem item = items[i];
821 if (item.width !is width) item.setBounds (0, 0, width, item.height, false, true);
822 }
823 setScrollbar ();
824 OS.InvalidateRect (handle, null, true);
825 return result;
826 }
827
828 override LRESULT wmScroll (ScrollBar bar, bool update, HWND hwnd, int msg, int wParam, int lParam) {
829 LRESULT result = super.wmScroll (bar, true, hwnd, msg, wParam, lParam);
830 SCROLLINFO info;
831 info.cbSize = SCROLLINFO.sizeof;
832 info.fMask = OS.SIF_POS;
833 OS.GetScrollInfo (handle, OS.SB_VERT, &info);
834 int updateY = yCurrentScroll - info.nPos;
835 OS.ScrollWindowEx (handle, 0, updateY, null, null, null, null, OS.SW_SCROLLCHILDREN | OS.SW_INVALIDATE);
836 yCurrentScroll = info.nPos;
837 if (updateY !is 0) {
838 for (int i = 0; i < itemCount; i++) {
839 items [i].y += updateY;
840 }
841 }
842 return result;
843 }
844 }
845