1 11 package org.eclipse.swt.widgets; 12 13 14 import org.eclipse.swt.internal.*; 15 import org.eclipse.swt.internal.win32.*; 16 import org.eclipse.swt.*; 17 import org.eclipse.swt.graphics.*; 18 import org.eclipse.swt.events.*; 19 20 45 public class TabFolder extends Composite { 46 TabItem [] items; 47 ImageList imageList; 48 static final int TabFolderProc; 49 static final TCHAR TabFolderClass = new TCHAR (0, OS.WC_TABCONTROL, true); 50 51 56 static final int ID_UPDOWN = 1; 57 58 static { 59 WNDCLASS lpWndClass = new WNDCLASS (); 60 OS.GetClassInfo (0, TabFolderClass, lpWndClass); 61 TabFolderProc = lpWndClass.lpfnWndProc; 62 81 int hInstance = OS.GetModuleHandle (null); 82 int hHeap = OS.GetProcessHeap (); 83 lpWndClass.hInstance = hInstance; 84 lpWndClass.style &= ~(OS.CS_HREDRAW | OS.CS_VREDRAW | OS.CS_GLOBALCLASS); 85 int byteCount = TabFolderClass.length () * TCHAR.sizeof; 86 int lpszClassName = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount); 87 OS.MoveMemory (lpszClassName, TabFolderClass, byteCount); 88 lpWndClass.lpszClassName = lpszClassName; 89 OS.RegisterClass (lpWndClass); 90 OS.HeapFree (hHeap, 0, lpszClassName); 91 } 92 93 121 public TabFolder (Composite parent, int style) { 122 super (parent, checkStyle (style)); 123 } 124 125 149 public void addSelectionListener(SelectionListener listener) { 150 checkWidget (); 151 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); 152 TypedListener typedListener = new TypedListener(listener); 153 addListener(SWT.Selection,typedListener); 154 addListener(SWT.DefaultSelection,typedListener); 155 } 156 157 int callWindowProc (int hwnd, int msg, int wParam, int lParam) { 158 if (handle == 0) return 0; 159 return OS.CallWindowProc (TabFolderProc, hwnd, msg, wParam, lParam); 160 } 161 162 static int checkStyle (int style) { 163 167 if (OS.IsPPC) { 168 if ((style & SWT.TOP) == 0) style |= SWT.BOTTOM; 169 } 170 style = checkBits (style, SWT.TOP, SWT.BOTTOM, 0, 0, 0, 0); 171 172 179 return style & ~(SWT.H_SCROLL | SWT.V_SCROLL); 180 } 181 182 protected void checkSubclass () { 183 if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); 184 } 185 186 public Point computeSize (int wHint, int hHint, boolean changed) { 187 checkWidget (); 188 Point size = super.computeSize (wHint, hHint, changed); 189 RECT insetRect = new RECT (), itemRect = new RECT (); 190 OS.SendMessage (handle, OS.TCM_ADJUSTRECT, 0, insetRect); 191 int width = insetRect.left - insetRect.right; 192 int count = OS.SendMessage (handle, OS.TCM_GETITEMCOUNT, 0, 0); 193 if (count != 0) { 194 OS.SendMessage (handle, OS.TCM_GETITEMRECT, count - 1, itemRect); 195 width = Math.max (width, itemRect.right - insetRect.right); 196 } 197 RECT rect = new RECT (); 198 OS.SetRect (rect, 0, 0, width, size.y); 199 OS.SendMessage (handle, OS.TCM_ADJUSTRECT, 1, rect); 200 int border = getBorderWidth (); 201 rect.left -= border; rect.right += border; 202 width = rect.right - rect.left; 203 size.x = Math.max (width, size.x); 204 return size; 205 } 206 207 public Rectangle computeTrim (int x, int y, int width, int height) { 208 checkWidget (); 209 RECT rect = new RECT (); 210 OS.SetRect (rect, x, y, x + width, y + height); 211 OS.SendMessage (handle, OS.TCM_ADJUSTRECT, 1, rect); 212 int border = getBorderWidth (); 213 rect.left -= border; rect.right += border; 214 rect.top -= border; rect.bottom += border; 215 int newWidth = rect.right - rect.left; 216 int newHeight = rect.bottom - rect.top; 217 return new Rectangle (rect.left, rect.top, newWidth, newHeight); 218 } 219 220 void createItem (TabItem item, int index) { 221 int count = OS.SendMessage (handle, OS.TCM_GETITEMCOUNT, 0, 0); 222 if (!(0 <= index && index <= count)) error (SWT.ERROR_INVALID_RANGE); 223 if (count == items.length) { 224 TabItem [] newItems = new TabItem [items.length + 4]; 225 System.arraycopy (items, 0, newItems, 0, items.length); 226 items = newItems; 227 } 228 TCITEM tcItem = new TCITEM (); 229 if (OS.SendMessage (handle, OS.TCM_INSERTITEM, index, tcItem) == -1) { 230 error (SWT.ERROR_ITEM_NOT_ADDED); 231 } 232 System.arraycopy (items, index, items, index + 1, count - index); 233 items [index] = item; 234 235 240 if (count == 0) { 241 Event event = new Event (); 242 event.item = items [0]; 243 sendEvent (SWT.Selection, event); 244 } 246 } 247 248 void createHandle () { 249 super.createHandle (); 250 state &= ~(CANVAS | THEME_BACKGROUND); 251 252 253 if (OS.IsPPC) { 254 OS.SendMessage (handle, OS.CCM_SETVERSION, 0x020c , 0); 255 } 256 257 264 int hwndToolTip = OS.SendMessage (handle, OS.TCM_GETTOOLTIPS, 0, 0); 265 OS.SendMessage (hwndToolTip, OS.TTM_SETMAXTIPWIDTH, 0, 0x7FFF); 266 } 267 268 void createWidget () { 269 super.createWidget (); 270 items = new TabItem [4]; 271 } 272 273 void destroyItem (TabItem item) { 274 int count = OS.SendMessage (handle, OS.TCM_GETITEMCOUNT, 0, 0); 275 int index = 0; 276 while (index < count) { 277 if (items [index] == item) break; 278 index++; 279 } 280 if (index == count) return; 281 int selectionIndex = OS.SendMessage (handle, OS.TCM_GETCURSEL, 0, 0); 282 if (OS.SendMessage (handle, OS.TCM_DELETEITEM, index, 0) == 0) { 283 error (SWT.ERROR_ITEM_NOT_REMOVED); 284 } 285 System.arraycopy (items, index + 1, items, index, --count - index); 286 items [count] = null; 287 if (count == 0) { 288 if (imageList != null) { 289 OS.SendMessage (handle, OS.TCM_SETIMAGELIST, 0, 0); 290 display.releaseImageList (imageList); 291 } 292 imageList = null; 293 items = new TabItem [4]; 294 } 295 if (count > 0 && index == selectionIndex) { 296 setSelection (Math.max (0, selectionIndex - 1), true); 297 } 298 } 299 300 void drawThemeBackground (int hDC, int hwnd, RECT rect) { 301 RECT rect2 = new RECT (); 302 OS.GetClientRect (handle, rect2); 303 OS.MapWindowPoints (handle, hwnd, rect2, 2); 304 if (OS.IntersectRect (new RECT (), rect2, rect)) { 305 OS.DrawThemeBackground (display.hTabTheme (), hDC, OS.TABP_BODY, 0, rect2, null); 306 } 307 } 308 309 Control findThemeControl () { 310 311 return this; 312 } 313 314 public Rectangle getClientArea () { 315 checkWidget (); 316 forceResize (); 317 RECT rect = new RECT (); 318 OS.GetClientRect (handle, rect); 319 OS.SendMessage (handle, OS.TCM_ADJUSTRECT, 0, rect); 320 int width = rect.right - rect.left; 321 int height = rect.bottom - rect.top; 322 return new Rectangle (rect.left, rect.top, width, height); 323 } 324 325 340 public TabItem getItem (int index) { 341 checkWidget (); 342 int count = OS.SendMessage (handle, OS.TCM_GETITEMCOUNT, 0, 0); 343 if (!(0 <= index && index < count)) error (SWT.ERROR_INVALID_RANGE); 344 return items [index]; 345 } 346 347 357 public int getItemCount () { 358 checkWidget (); 359 return OS.SendMessage (handle, OS.TCM_GETITEMCOUNT, 0, 0); 360 } 361 362 378 public TabItem [] getItems () { 379 checkWidget (); 380 int count = OS.SendMessage (handle, OS.TCM_GETITEMCOUNT, 0, 0); 381 TabItem [] result = new TabItem [count]; 382 System.arraycopy (items, 0, result, 0, count); 383 return result; 384 } 385 386 402 public TabItem [] getSelection () { 403 checkWidget (); 404 int index = OS.SendMessage (handle, OS.TCM_GETCURSEL, 0, 0); 405 if (index == -1) return new TabItem [0]; 406 return new TabItem [] {items [index]}; 407 } 408 409 420 public int getSelectionIndex () { 421 checkWidget (); 422 return OS.SendMessage (handle, OS.TCM_GETCURSEL, 0, 0); 423 } 424 425 int imageIndex (Image image) { 426 if (image == null) return OS.I_IMAGENONE; 427 if (imageList == null) { 428 Rectangle bounds = image.getBounds (); 429 imageList = display.getImageList (style & SWT.RIGHT_TO_LEFT, bounds.width, bounds.height); 430 int index = imageList.add (image); 431 int hImageList = imageList.getHandle (); 432 OS.SendMessage (handle, OS.TCM_SETIMAGELIST, 0, hImageList); 433 return index; 434 } 435 int index = imageList.indexOf (image); 436 if (index == -1) { 437 index = imageList.add (image); 438 } else { 439 imageList.put (index, image); 440 } 441 return index; 442 } 443 444 461 public int indexOf (TabItem item) { 462 checkWidget (); 463 if (item == null) error (SWT.ERROR_NULL_ARGUMENT); 464 int count = OS.SendMessage (handle, OS.TCM_GETITEMCOUNT, 0, 0); 465 for (int i=0; i<count; i++) { 466 if (items [i] == item) return i; 467 } 468 return -1; 469 } 470 471 Point minimumSize (int wHint, int hHint, boolean flushCache) { 472 Control [] children = _getChildren (); 473 int width = 0, height = 0; 474 for (int i=0; i<children.length; i++) { 475 Control child = children [i]; 476 int index = 0; 477 int count = OS.SendMessage (handle, OS.TCM_GETITEMCOUNT, 0, 0); 478 while (index < count) { 479 if (items [index].control == child) break; 480 index++; 481 } 482 if (index == count) { 483 Rectangle rect = child.getBounds (); 484 width = Math.max (width, rect.x + rect.width); 485 height = Math.max (height, rect.y + rect.height); 486 } else { 487 Point size = child.computeSize (wHint, hHint, flushCache); 488 width = Math.max (width, size.x); 489 height = Math.max (height, size.y); 490 } 491 } 492 return new Point (width, height); 493 } 494 495 boolean mnemonicHit (char key) { 496 for (int i=0; i<items.length; i++) { 497 TabItem item = items [i]; 498 if (item != null) { 499 char ch = findMnemonic (item.getText ()); 500 if (Character.toUpperCase (key) == Character.toUpperCase (ch)) { 501 if (forceFocus ()) { 502 if (i != getSelectionIndex ()) setSelection (i, true); 503 return true; 504 } 505 } 506 } 507 } 508 return false; 509 } 510 511 boolean mnemonicMatch (char key) { 512 for (int i=0; i<items.length; i++) { 513 TabItem item = items [i]; 514 if (item != null) { 515 char ch = findMnemonic (item.getText ()); 516 if (Character.toUpperCase (key) == Character.toUpperCase (ch)) { 517 return true; 518 } 519 } 520 } 521 return false; 522 } 523 524 void releaseChildren (boolean destroy) { 525 if (items != null) { 526 int count = OS.SendMessage (handle, OS.TCM_GETITEMCOUNT, 0, 0); 527 for (int i=0; i<count; i++) { 528 TabItem item = items [i]; 529 if (item != null && !item.isDisposed ()) { 530 item.release (false); 531 } 532 } 533 items = null; 534 } 535 super.releaseChildren (destroy); 536 } 537 538 void releaseWidget () { 539 super.releaseWidget (); 540 if (imageList != null) { 541 OS.SendMessage (handle, OS.TCM_SETIMAGELIST, 0, 0); 542 display.releaseImageList (imageList); 543 } 544 imageList = null; 545 } 546 547 void removeControl (Control control) { 548 super.removeControl (control); 549 int count = OS.SendMessage (handle, OS.TCM_GETITEMCOUNT, 0, 0); 550 for (int i=0; i<count; i++) { 551 TabItem item = items [i]; 552 if (item.control == control) item.setControl (null); 553 } 554 } 555 556 573 public void removeSelectionListener (SelectionListener listener) { 574 checkWidget (); 575 if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); 576 if (eventTable == null) return; 577 eventTable.unhook (SWT.Selection, listener); 578 eventTable.unhook (SWT.DefaultSelection,listener); 579 } 580 581 598 public void setSelection (TabItem item) { 599 checkWidget (); 600 if (item == null) error (SWT.ERROR_NULL_ARGUMENT); 601 setSelection (new TabItem [] {item}); 602 } 603 604 619 public void setSelection (TabItem [] items) { 620 checkWidget (); 621 if (items == null) error (SWT.ERROR_NULL_ARGUMENT); 622 if (items.length == 0) { 623 setSelection (-1, false); 624 } else { 625 for (int i=items.length-1; i>=0; --i) { 626 int index = indexOf (items [i]); 627 if (index != -1) setSelection (index, false); 628 } 629 } 630 } 631 632 public void setFont (Font font) { 633 checkWidget (); 634 Rectangle oldRect = getClientArea (); 635 super.setFont (font); 636 Rectangle newRect = getClientArea (); 637 if (!oldRect.equals (newRect)) { 638 sendResize (); 639 int index = OS.SendMessage (handle, OS.TCM_GETCURSEL, 0, 0); 640 if (index != -1) { 641 TabItem item = items [index]; 642 Control control = item.control; 643 if (control != null && !control.isDisposed ()) { 644 control.setBounds (getClientArea ()); 645 } 646 } 647 } 648 } 649 650 663 public void setSelection (int index) { 664 checkWidget (); 665 int count = OS.SendMessage (handle, OS.TCM_GETITEMCOUNT, 0, 0); 666 if (!(0 <= index && index < count)) return; 667 setSelection (index, false); 668 } 669 670 void setSelection (int index, boolean notify) { 671 int oldIndex = OS.SendMessage (handle, OS.TCM_GETCURSEL, 0, 0); 672 if (oldIndex == index) return; 673 if (oldIndex != -1) { 674 TabItem item = items [oldIndex]; 675 Control control = item.control; 676 if (control != null && !control.isDisposed ()) { 677 control.setVisible (false); 678 } 679 } 680 OS.SendMessage (handle, OS.TCM_SETCURSEL, index, 0); 681 int newIndex = OS.SendMessage (handle, OS.TCM_GETCURSEL, 0, 0); 682 if (newIndex != -1) { 683 TabItem item = items [newIndex]; 684 Control control = item.control; 685 if (control != null && !control.isDisposed ()) { 686 control.setBounds (getClientArea ()); 687 control.setVisible (true); 688 } 689 if (notify) { 690 Event event = new Event (); 691 event.item = item; 692 sendEvent (SWT.Selection, event); 693 } 694 } 695 } 696 697 String toolTipText (NMTTDISPINFO hdr) { 698 if ((hdr.uFlags & OS.TTF_IDISHWND) != 0) { 699 return null; 700 } 701 int index = hdr.idFrom; 702 int hwndToolTip = OS.SendMessage (handle, OS.TCM_GETTOOLTIPS, 0, 0); 703 if (hwndToolTip == hdr.hwndFrom) { 704 if (toolTipText != null) return ""; 705 if (0 <= index && index < items.length) { 706 TabItem item = items [index]; 707 if (item != null) return item.toolTipText; 708 } 709 } 710 return super.toolTipText (hdr); 711 } 712 713 boolean traversePage (boolean next) { 714 int count = getItemCount (); 715 if (count <= 1) return false; 716 int index = getSelectionIndex (); 717 if (index == -1) { 718 index = 0; 719 } else { 720 int offset = (next) ? 1 : -1; 721 index = (index + offset + count) % count; 722 } 723 setSelection (index, true); 724 if (index == getSelectionIndex ()) { 725 OS.SendMessage (handle, OS.WM_CHANGEUISTATE, OS.UIS_INITIALIZE, 0); 726 return true; 727 } 728 return false; 729 } 730 731 int widgetStyle () { 732 739 int bits = super.widgetStyle () | OS.WS_CLIPCHILDREN; 740 if ((style & SWT.NO_FOCUS) != 0) bits |= OS.TCS_FOCUSNEVER; 741 if ((style & SWT.BOTTOM) != 0) bits |= OS.TCS_BOTTOM; 742 return bits | OS.TCS_TABS | OS.TCS_TOOLTIPS; 743 } 744 745 TCHAR windowClass () { 746 return TabFolderClass; 747 } 748 749 int windowProc () { 750 return TabFolderProc; 751 } 752 753 LRESULT WM_GETDLGCODE (int wParam, int lParam) { 754 LRESULT result = super.WM_GETDLGCODE (wParam, lParam); 755 760 if (result != null) return result; 761 return new LRESULT (OS.DLGC_BUTTON); 762 } 763 764 LRESULT WM_MOUSELEAVE (int wParam, int lParam) { 765 LRESULT result = super.WM_MOUSELEAVE (wParam, lParam); 766 if (result != null) return result; 767 778 if (OS.COMCTL32_MAJOR >= 6) { 779 TOOLINFO lpti = new TOOLINFO (); 780 lpti.cbSize = TOOLINFO.sizeof; 781 int hwndToolTip = OS.SendMessage (handle, OS.TCM_GETTOOLTIPS, 0, 0); 782 if (OS.SendMessage (hwndToolTip, OS.TTM_GETCURRENTTOOL, 0, lpti) != 0) { 783 if ((lpti.uFlags & OS.TTF_IDISHWND) == 0) { 784 OS.SendMessage (hwndToolTip, OS.TTM_DELTOOL, 0, lpti); 785 OS.SendMessage (hwndToolTip, OS.TTM_ADDTOOL, 0, lpti); 786 } 787 } 788 } 789 return result; 790 } 791 792 LRESULT WM_NCHITTEST (int wParam, int lParam) { 793 LRESULT result = super.WM_NCHITTEST (wParam, lParam); 794 if (result != null) return result; 795 807 int hittest = OS.DefWindowProc (handle, OS.WM_NCHITTEST, wParam, lParam); 808 return new LRESULT (hittest); 809 } 810 811 LRESULT WM_NOTIFY (int wParam, int lParam) { 812 830 LRESULT result = super.WM_NOTIFY (wParam, lParam); 831 if (result != null) return result; 832 return LRESULT.ZERO; 833 } 834 835 LRESULT WM_PARENTNOTIFY (int wParam, int lParam) { 836 LRESULT result = super.WM_PARENTNOTIFY (wParam, lParam); 837 if (result != null) return result; 838 848 if (OS.WIN32_VERSION < OS.VERSION (4, 10)) return result; 849 if ((style & SWT.RIGHT_TO_LEFT) != 0) { 850 int code = wParam & 0xFFFF; 851 switch (code) { 852 case OS.WM_CREATE: { 853 int id = (wParam >> 16), hwnd = lParam; 854 if (id == ID_UPDOWN) { 855 int bits = OS.GetWindowLong (hwnd, OS.GWL_EXSTYLE); 856 OS.SetWindowLong (hwnd, OS.GWL_EXSTYLE, bits | OS.WS_EX_LAYOUTRTL); 857 } 858 break; 859 } 860 } 861 } 862 return result; 863 } 864 865 LRESULT WM_SIZE (int wParam, int lParam) { 866 LRESULT result = super.WM_SIZE (wParam, lParam); 867 874 if (isDisposed ()) return result; 875 int index = OS.SendMessage (handle, OS.TCM_GETCURSEL, 0, 0); 876 if (index != -1) { 877 TabItem item = items [index]; 878 Control control = item.control; 879 if (control != null && !control.isDisposed ()) { 880 control.setBounds (getClientArea ()); 881 } 882 } 883 return result; 884 } 885 886 LRESULT WM_WINDOWPOSCHANGING (int wParam, int lParam) { 887 LRESULT result = super.WM_WINDOWPOSCHANGING (wParam, lParam); 888 if (result != null) return result; 889 if (!OS.IsWindowVisible (handle)) return result; 890 WINDOWPOS lpwp = new WINDOWPOS (); 891 OS.MoveMemory (lpwp, lParam, WINDOWPOS.sizeof); 892 if ((lpwp.flags & (OS.SWP_NOSIZE | OS.SWP_NOREDRAW)) != 0) { 893 return result; 894 } 895 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); 901 if ((bits & OS.TCS_MULTILINE) != 0) { 902 OS.InvalidateRect (handle, null, true); 903 return result; 904 } 905 RECT rect = new RECT (); 906 OS.SetRect (rect, 0, 0, lpwp.cx, lpwp.cy); 907 OS.SendMessage (handle, OS.WM_NCCALCSIZE, 0, rect); 908 int newWidth = rect.right - rect.left; 909 int newHeight = rect.bottom - rect.top; 910 OS.GetClientRect (handle, rect); 911 int oldWidth = rect.right - rect.left; 912 int oldHeight = rect.bottom - rect.top; 913 if (newWidth == oldWidth && newHeight == oldHeight) { 914 return result; 915 } 916 RECT inset = new RECT (); 917 OS.SendMessage (handle, OS.TCM_ADJUSTRECT, 0, inset); 918 int marginX = -inset.right, marginY = -inset.bottom; 919 if (newWidth != oldWidth) { 920 int left = oldWidth; 921 if (newWidth < oldWidth) left = newWidth; 922 OS.SetRect (rect, left - marginX, 0, newWidth, newHeight); 923 OS.InvalidateRect (handle, rect, true); 924 } 925 if (newHeight != oldHeight) { 926 int bottom = oldHeight; 927 if (newHeight < oldHeight) bottom = newHeight; 928 if (newWidth < oldWidth) oldWidth -= marginX; 929 OS.SetRect (rect, 0, bottom - marginY, oldWidth, newHeight); 930 OS.InvalidateRect (handle, rect, true); 931 } 932 return result; 933 } 934 935 LRESULT wmNotifyChild (NMHDR hdr, int wParam, int lParam) { 936 int code = hdr.code; 937 switch (code) { 938 case OS.TCN_SELCHANGE: 939 case OS.TCN_SELCHANGING: 940 TabItem item = null; 941 int index = OS.SendMessage (handle, OS.TCM_GETCURSEL, 0, 0); 942 if (index != -1) item = items [index]; 943 if (item != null) { 944 Control control = item.control; 945 if (control != null && !control.isDisposed ()) { 946 if (code == OS.TCN_SELCHANGE) { 947 control.setBounds (getClientArea ()); 948 } 949 control.setVisible (code == OS.TCN_SELCHANGE); 950 } 951 } 952 if (code == OS.TCN_SELCHANGE) { 953 Event event = new Event (); 954 event.item = item; 955 postEvent (SWT.Selection, event); 956 } 957 } 958 return super.wmNotifyChild (hdr, wParam, lParam); 959 } 960 961 } 962 | Popular Tags |