1 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 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 78 public ExpandBar (Composite parent, int style) { 79 super (parent, checkStyle (style)); 80 } 81 82 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 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 335 public int getItemCount () { 336 checkWidget (); 337 return itemCount; 338 } 339 340 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 373 public int getSpacing () { 374 checkWidget (); 375 return spacing; 376 } 377 378 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 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 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 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 |