1 11 package org.eclipse.ui.internal.presentations.r21.widgets; 12 13 import org.eclipse.swt.SWT; 14 import org.eclipse.swt.SWTError; 15 import org.eclipse.swt.SWTException; 16 import org.eclipse.swt.accessibility.ACC; 17 import org.eclipse.swt.accessibility.Accessible; 18 import org.eclipse.swt.accessibility.AccessibleAdapter; 19 import org.eclipse.swt.accessibility.AccessibleControlAdapter; 20 import org.eclipse.swt.accessibility.AccessibleControlEvent; 21 import org.eclipse.swt.accessibility.AccessibleEvent; 22 import org.eclipse.swt.events.SelectionListener; 23 import org.eclipse.swt.graphics.Color; 24 import org.eclipse.swt.graphics.Font; 25 import org.eclipse.swt.graphics.GC; 26 import org.eclipse.swt.graphics.Image; 27 import org.eclipse.swt.graphics.ImageData; 28 import org.eclipse.swt.graphics.PaletteData; 29 import org.eclipse.swt.graphics.Point; 30 import org.eclipse.swt.graphics.RGB; 31 import org.eclipse.swt.graphics.Rectangle; 32 import org.eclipse.swt.widgets.Composite; 33 import org.eclipse.swt.widgets.Control; 34 import org.eclipse.swt.widgets.Display; 35 import org.eclipse.swt.widgets.Event; 36 import org.eclipse.swt.widgets.Label; 37 import org.eclipse.swt.widgets.Listener; 38 import org.eclipse.swt.widgets.Shell; 39 import org.eclipse.swt.widgets.ToolBar; 40 import org.eclipse.swt.widgets.ToolItem; 41 import org.eclipse.swt.widgets.TypedListener; 42 43 70 71 public class CTabFolder extends Composite { 72 73 79 public int marginWidth = 0; 80 81 87 public int marginHeight = 0; 88 89 92 public static RGB borderInsideRGB = new RGB(132, 130, 132); 93 94 97 public static RGB borderMiddleRGB = new RGB(143, 141, 138); 98 99 102 public static RGB borderOutsideRGB = new RGB(171, 168, 165); 103 104 108 public int MIN_TAB_WIDTH = 3; 109 110 111 int xClient, yClient; 112 113 boolean onBottom = false; 114 115 boolean fixedTabHeight; 116 117 int tabHeight; 118 119 120 private CTabItem items[] = new CTabItem[0]; 121 122 private int selectedIndex = -1; 123 124 int topTabIndex = -1; 126 127 private CTabFolderListener[] tabListeners = new CTabFolderListener[0]; 128 129 130 Image backgroundImage; 131 132 Color[] gradientColors; 133 134 int[] gradientPercents; 135 136 Color selectionForeground; 137 138 Color background; 139 140 private static final int DEFAULT_WIDTH = 64; 142 143 private static final int DEFAULT_HEIGHT = 64; 144 145 private ToolBar arrowBar; 147 148 private Image arrowLeftImage; 149 150 private Image arrowRightImage; 151 152 private Control topRight; 153 154 boolean showClose = false; 156 157 private Image closeImage; 158 159 ToolBar closeBar; 160 161 private ToolBar inactiveCloseBar; 162 163 private CTabItem inactiveItem; 164 165 boolean showBorders = false; 167 168 private int borderBottom = 0; 169 170 private int borderLeft = 0; 171 172 private int borderRight = 0; 173 174 private int borderTop = 0; 175 176 private Color borderColor1; 177 178 private Color borderColor2; 179 180 private Color borderColor3; 181 182 private boolean inDispose = false; 185 186 private Point oldSize; 189 190 private Font oldFont; 191 192 int insertionIndex = -2; 195 197 private Shell tip; 199 200 private Label label; 201 202 private boolean showToolTip = false; 203 204 private CTabItem toolTipItem; 205 206 234 public CTabFolder(Composite parent, int style) { 235 super(parent, checkStyle(style)); 236 237 onBottom = (getStyle() & SWT.BOTTOM) != 0; 238 239 borderColor1 = new Color(getDisplay(), borderInsideRGB); 240 borderColor2 = new Color(getDisplay(), borderMiddleRGB); 241 borderColor3 = new Color(getDisplay(), borderOutsideRGB); 242 243 tip = new Shell(getShell(), SWT.ON_TOP); 245 label = new Label(tip, SWT.CENTER); 246 247 Listener listener = new Listener() { 249 public void handleEvent(Event event) { 250 switch (event.type) { 251 case SWT.Dispose: 252 onDispose(); 253 break; 254 case SWT.Paint: 255 onPaint(event); 256 break; 257 case SWT.Resize: 258 onResize(); 259 break; 260 case SWT.MouseDoubleClick: 261 onMouseDoubleClick(event); 262 break; 263 case SWT.MouseDown: 264 onMouseDown(event); 265 break; 266 case SWT.MouseExit: 267 onMouseExit(event); 268 break; 269 case SWT.MouseHover: 270 onMouseHover(event); 271 break; 272 case SWT.MouseMove: 273 onMouseMove(event); 274 break; 275 case SWT.FocusIn: 276 onFocus(event); 277 break; 278 case SWT.FocusOut: 279 onFocus(event); 280 break; 281 case SWT.KeyDown: 282 onKeyDown(event); 283 break; 284 case SWT.Traverse: 285 onTraverse(event); 286 break; 287 } 288 } 289 }; 290 291 int[] folderEvents = new int[] { SWT.Dispose, SWT.Paint, SWT.Resize, 292 SWT.MouseDoubleClick, SWT.MouseDown, SWT.MouseExit, 293 SWT.MouseHover, SWT.MouseMove, SWT.FocusIn, SWT.FocusOut, 294 SWT.KeyDown, SWT.Traverse, }; 295 for (int i = 0; i < folderEvents.length; i++) { 296 addListener(folderEvents[i], listener); 297 } 298 299 createArrowBar(); 300 createCloseBar(); 301 302 setBorderVisible((style & SWT.BORDER) != 0); 303 304 initAccessible(); 305 306 } 307 308 private static int checkStyle(int style) { 309 int mask = SWT.TOP | SWT.BOTTOM | SWT.FLAT | SWT.LEFT_TO_RIGHT 310 | SWT.RIGHT_TO_LEFT; 311 style = style & mask; 312 if ((style & SWT.TOP) != 0) { 315 style = style & ~(SWT.TOP | SWT.BOTTOM) | SWT.TOP; 316 } 317 style |= SWT.NO_REDRAW_RESIZE; 319 return style; 320 } 321 322 334 public void addSelectionListener(SelectionListener listener) { 335 checkWidget(); 336 if (listener == null) { 337 SWT.error(SWT.ERROR_NULL_ARGUMENT); 338 } 339 TypedListener typedListener = new TypedListener(listener); 340 addListener(SWT.Selection, typedListener); 341 addListener(SWT.DefaultSelection, typedListener); 342 } 343 344 359 public void addCTabFolderListener(CTabFolderListener listener) { 360 checkWidget(); 361 if (listener == null) { 362 SWT.error(SWT.ERROR_NULL_ARGUMENT); 363 } 364 CTabFolderListener[] newTabListeners = new CTabFolderListener[tabListeners.length + 1]; 366 System.arraycopy(tabListeners, 0, newTabListeners, 0, 367 tabListeners.length); 368 tabListeners = newTabListeners; 369 tabListeners[tabListeners.length - 1] = listener; 370 showClose = true; 371 setButtonBounds(); 372 } 373 374 private void closeNotify(CTabItem item, int time) { 375 if (item == null) { 376 return; 377 } 378 379 CTabFolderEvent event = new CTabFolderEvent(this); 380 event.widget = this; 381 event.time = time; 382 event.item = item; 383 event.doit = true; 384 if (tabListeners != null) { 385 for (int i = 0; i < tabListeners.length; i++) { 386 tabListeners[i].itemClosed(event); 387 } 388 } 389 if (event.doit) { 390 item.dispose(); 391 } 392 } 393 394 public Point computeSize(int wHint, int hHint, boolean changed) { 395 checkWidget(); 396 int minWidth = 0; 397 int minHeight = 0; 398 399 GC gc = new GC(this); 401 for (int i = 0; i < items.length; i++) { 402 minWidth += items[i].preferredWidth(gc); 403 } 404 gc.dispose(); 405 406 for (int i = 0; i < items.length; i++) { 408 Control control = items[i].getControl(); 409 if (control != null && !control.isDisposed()) { 410 Point size = control.computeSize(wHint, hHint); 411 minWidth = Math.max(minWidth, size.x); 412 minHeight = Math.max(minHeight, size.y); 413 } 414 } 415 if (minWidth == 0) { 416 minWidth = DEFAULT_WIDTH; 417 } 418 if (minHeight == 0) { 419 minHeight = DEFAULT_HEIGHT; 420 } 421 422 if (wHint != SWT.DEFAULT) { 423 minWidth = wHint; 424 } 425 if (hHint != SWT.DEFAULT) { 426 minHeight = hHint; 427 } 428 429 Rectangle trim = computeTrim(0, 0, minWidth, minHeight); 430 return new Point(trim.width, trim.height); 431 } 432 433 public Rectangle computeTrim(int x, int y, int width, int height) { 434 checkWidget(); 435 if (items.length == 0) { 436 if (!showBorders) { 437 return new Rectangle(x, y, width, height); 438 } 439 int trimX = x - borderRight - 1; 440 int trimY = y - borderBottom - 1; 441 int trimWidth = width + borderRight + 2; 442 int trimHeight = height + borderBottom + 2; 443 return new Rectangle(trimX, trimY, trimWidth, trimHeight); 444 } else { 445 int trimX = x - marginWidth - borderLeft; 446 int trimY = y - marginHeight - tabHeight - borderTop - 1; 447 if (onBottom) { 449 trimY = y - marginHeight - borderTop; 450 } 451 int trimWidth = width + borderLeft + borderRight + 2 * marginWidth; 452 int trimHeight = height + borderTop + borderBottom + 2 453 * marginHeight + tabHeight + 1; 454 return new Rectangle(trimX, trimY, trimWidth, trimHeight); 455 } 456 } 457 458 461 void createItem(CTabItem item, int index) { 462 if (0 > index || index > getItemCount()) { 463 SWT.error(SWT.ERROR_INVALID_RANGE); 464 } 465 CTabItem[] newItems = new CTabItem[items.length + 1]; 467 System.arraycopy(items, 0, newItems, 0, index); 468 newItems[index] = item; 469 System.arraycopy(items, index, newItems, index + 1, items.length 470 - index); 471 items = newItems; 472 473 item.parent = this; 474 475 if (selectedIndex >= index) { 476 selectedIndex++; 477 } 478 if (items.length == 1) { 479 topTabIndex = 0; 480 resetTabSize(true); 481 } else { 482 setItemBounds(); 483 showItem(item); 484 } 485 486 if (items.length == 1) { 487 redraw(); 488 } else { 489 redrawTabArea(-1); 490 } 491 } 492 493 private void createArrowBar() { 494 arrowBar = new ToolBar(this, SWT.FLAT); 496 arrowBar.setVisible(false); 497 arrowBar.setBackground(background); 498 ToolItem scrollLeft = new ToolItem(arrowBar, SWT.PUSH); 499 scrollLeft.setEnabled(false); 500 ToolItem scrollRight = new ToolItem(arrowBar, SWT.PUSH); 501 scrollRight.setEnabled(false); 502 503 scrollLeft.addListener(SWT.Selection, new Listener() { 504 public void handleEvent(Event event) { 505 scroll_scrollLeft(); 506 } 507 }); 508 scrollRight.addListener(SWT.Selection, new Listener() { 509 public void handleEvent(Event event) { 510 scroll_scrollRight(); 511 } 512 }); 513 514 } 515 516 private void createCloseBar() { 517 closeBar = new ToolBar(this, SWT.FLAT); 518 closeBar.setVisible(false); 519 if (gradientColors != null && gradientColors.length > 0) { 520 closeBar.setBackground(gradientColors[gradientColors.length - 1]); 521 } else { 522 closeBar.setBackground(background); 523 } 524 ToolItem closeItem = new ToolItem(closeBar, SWT.PUSH); 525 526 inactiveCloseBar = new ToolBar(this, SWT.FLAT); 527 inactiveCloseBar.setVisible(false); 528 inactiveCloseBar.setBackground(background); 529 ToolItem inactiveCloseItem = new ToolItem(inactiveCloseBar, SWT.PUSH); 530 531 closeItem.addListener(SWT.Selection, new Listener() { 532 public void handleEvent(Event event) { 533 closeNotify(getSelection(), event.time); 534 } 535 }); 536 inactiveCloseItem.addListener(SWT.Selection, new Listener() { 537 public void handleEvent(Event event) { 538 closeNotify(inactiveItem, event.time); 539 inactiveCloseBar.setVisible(false); 540 inactiveItem = null; 541 } 542 }); 543 inactiveCloseBar.addListener(SWT.MouseExit, new Listener() { 544 public void handleEvent(Event event) { 545 if (inactiveItem != null) { 546 Rectangle itemBounds = inactiveItem.getBounds(); 547 if (itemBounds.contains(event.x, event.y)) { 548 return; 549 } 550 } 551 inactiveCloseBar.setVisible(false); 552 inactiveItem = null; 553 } 554 }); 555 556 } 557 558 561 void destroyItem(CTabItem item) { 562 if (inDispose) { 563 return; 564 } 565 566 int index = indexOf(item); 567 if (index == -1) { 568 return; } 570 571 insertionIndex = -2; 572 573 if (items.length == 1) { 574 items = new CTabItem[0]; 575 selectedIndex = -1; 576 topTabIndex = 0; 577 578 Control control = item.getControl(); 579 if (control != null && !control.isDisposed()) { 580 control.setVisible(false); 581 } 582 closeBar.setVisible(false); 583 if (!fixedTabHeight) { 584 tabHeight = 0; 585 } 586 redraw(); 587 return; 588 } 589 590 CTabItem[] newItems = new CTabItem[items.length - 1]; 592 System.arraycopy(items, 0, newItems, 0, index); 593 System.arraycopy(items, index + 1, newItems, index, items.length 594 - index - 1); 595 items = newItems; 596 597 if (topTabIndex == items.length) { 598 --topTabIndex; 599 } 600 601 if (selectedIndex == index) { 603 Control control = item.getControl(); 604 if (control != null && !control.isDisposed()) { 605 control.setVisible(false); 606 } 607 selectedIndex = -1; 608 setSelection(Math.max(0, index - 1), true); 609 } else if (selectedIndex > index) { 610 selectedIndex--; 611 } 612 613 setItemBounds(); 614 redrawTabArea(-1); 615 } 616 617 private void onKeyDown(Event e) { 618 if (e.keyCode != SWT.ARROW_LEFT && e.keyCode != SWT.ARROW_RIGHT) { 619 return; 620 } 621 int leadKey = (getStyle() & SWT.MIRRORED) != 0 ? SWT.ARROW_RIGHT 622 : SWT.ARROW_LEFT; 623 if (e.keyCode == leadKey) { 624 if (selectedIndex > 0) { 625 setSelection(selectedIndex - 1, true); 626 } 627 } else { 628 if (selectedIndex < items.length - 1) { 629 setSelection(selectedIndex + 1, true); 630 } 631 } 632 } 633 634 637 private void onDispose() { 638 644 inDispose = true; 645 646 int length = items.length; 647 for (int i = 0; i < length; i++) { 648 if (items[i] != null) { 649 items[i].dispose(); 650 } 651 } 652 653 if (tip != null && !tip.isDisposed()) { 655 tip.dispose(); 656 tip = null; 657 label = null; 658 } 659 660 if (arrowLeftImage != null) { 661 arrowLeftImage.dispose(); 662 } 663 arrowLeftImage = null; 664 if (arrowRightImage != null) { 665 arrowRightImage.dispose(); 666 } 667 arrowRightImage = null; 668 if (closeImage != null) { 669 closeImage.dispose(); 670 } 671 closeImage = null; 672 673 gradientColors = null; 674 gradientPercents = null; 675 backgroundImage = null; 676 677 if (borderColor1 != null) { 678 borderColor1.dispose(); 679 } 680 borderColor1 = null; 681 682 if (borderColor2 != null) { 683 borderColor2.dispose(); 684 } 685 borderColor2 = null; 686 687 if (borderColor3 != null) { 688 borderColor3.dispose(); 689 } 690 borderColor3 = null; 691 } 692 693 private void onFocus(Event e) { 694 checkWidget(); 695 if (selectedIndex >= 0) { 696 redrawTabArea(selectedIndex); 697 } else { 698 setSelection(0, true); 699 } 700 } 701 702 705 private void drawBorder(GC gc) { 706 707 Rectangle d = super.getClientArea(); 708 709 if (showBorders) { 710 if ((getStyle() & SWT.FLAT) != 0) { 711 gc.setForeground(borderColor1); 712 gc.drawRectangle(d.x, d.y, d.x + d.width - 1, d.y + d.height 713 - 1); 714 } else { 715 gc.setForeground(borderColor1); 716 gc.drawRectangle(d.x, d.y, d.x + d.width - 3, d.y + d.height 717 - 3); 718 719 gc.setForeground(borderColor2); 720 gc.drawLine(d.x + 1, d.y + d.height - 2, d.x + d.width - 1, d.y 721 + d.height - 2); 722 gc.drawLine(d.x + d.width - 2, d.y + 1, d.x + d.width - 2, d.y 723 + d.height - 1); 724 725 gc.setForeground(borderColor3); 726 gc.drawLine(d.x + 2, d.y + d.height - 1, d.x + d.width - 2, d.y 727 + d.height - 1); 728 gc.drawLine(d.x + d.width - 1, d.y + 2, d.x + d.width - 1, d.y 729 + d.height - 2); 730 731 gc.setForeground(getParent().getBackground()); 733 gc.drawLine(d.x + d.width - 2, d.y, d.x + d.width - 1, d.y); 734 gc.drawLine(d.x + d.width - 1, d.y + 1, d.x + d.width - 1, 735 d.y + 1); 736 737 gc.drawLine(d.x, d.y + d.height - 2, d.x, d.y + d.height - 2); 738 gc.drawLine(d.x, d.y + d.height - 1, d.x + 1, d.y + d.height 739 - 1); 740 741 gc.drawLine(d.x + d.width - 1, d.y + d.height - 1, d.x 742 + d.width - 1, d.y + d.height - 1); 743 } 744 745 } 746 747 if (items.length > 0) { 749 int lineY = d.y + borderTop + tabHeight; 750 if (onBottom) { 751 lineY = d.y + d.height - borderBottom - tabHeight - 1; 752 } 753 gc.setForeground(borderColor1); 754 gc.drawLine(d.x + borderLeft, lineY, d.x + d.width - borderRight, 755 lineY); 756 } 757 758 gc.setForeground(getForeground()); 759 } 760 761 public Rectangle getClientArea() { 762 checkWidget(); 763 Point size = getSize(); 764 if (items.length == 0) { 765 if (!showBorders) { 766 return super.getClientArea(); 767 } 768 int width = size.x - borderRight - 2; 769 int height = size.y - borderBottom - 2; 770 return new Rectangle(borderRight + 1, borderBottom + 1, width, 771 height); 772 } else { 773 int width = size.x - 2 * marginWidth - borderLeft - borderRight; 774 int height = size.y - 2 * marginHeight - borderTop - borderBottom 775 - tabHeight - 1; 776 return new Rectangle(xClient, yClient, width, height); 777 } 778 } 779 780 790 public int getTabHeight() { 791 checkWidget(); 792 return tabHeight; 793 } 794 795 800 public CTabItem getItem(int index) { 801 if (index < 0 || index >= items.length) { 803 SWT.error(SWT.ERROR_INVALID_RANGE); 804 } 805 return items[index]; 806 } 807 808 814 public CTabItem getItem(Point pt) { 815 if (items.length == 0) { 817 return null; 818 } 819 int lastItem = getLastItem(); 820 lastItem = Math.min(items.length - 1, lastItem + 1); 821 for (int i = topTabIndex; i <= lastItem; i++) { 822 Rectangle bounds = items[i].getBounds(); 823 if (bounds.contains(pt)) { 824 return items[i]; 825 } 826 } 827 return null; 828 } 829 830 835 public int getItemCount() { 836 return items.length; 838 } 839 840 845 public CTabItem[] getItems() { 846 CTabItem[] tabItems = new CTabItem[items.length]; 848 System.arraycopy(items, 0, tabItems, 0, items.length); 849 return tabItems; 850 } 851 852 private int getLastItem() { 853 if (items.length == 0) { 854 return -1; 855 } 856 Rectangle area = getClientArea(); 857 if (area.width <= 0) { 858 return 0; 859 } 860 Rectangle toolspace = getToolSpace(); 861 if (toolspace.width == 0) { 862 return items.length - 1; 863 } 864 int width = area.width - toolspace.width; 865 int index = topTabIndex; 866 int tabWidth = items[index].width; 867 while (index < items.length - 1) { 868 tabWidth += items[index + 1].width; 869 if (tabWidth > width) { 870 break; 871 } 872 index++; 873 } 874 return index; 875 } 876 877 883 public CTabItem getSelection() { 884 if (selectedIndex == -1) { 886 return null; 887 } 888 return items[selectedIndex]; 889 } 890 891 897 public int getSelectionIndex() { 898 return selectedIndex; 900 } 901 902 private Rectangle getToolSpace() { 903 boolean showArrows = scroll_leftVisible() || scroll_rightVisible(); 904 if (!showArrows && topRight == null) { 905 return new Rectangle(0, 0, 0, 0); 906 } 907 Rectangle toolspace; 908 if (showArrows) { 909 toolspace = arrowBar.getBounds(); 910 toolspace.width += borderRight; 911 if (topRight != null) { 912 toolspace.width += topRight.getSize().x; 913 } 914 } else { 915 toolspace = topRight.getBounds(); 916 toolspace.width += borderRight; 917 } 918 return toolspace; 919 } 920 921 934 public Control getTopRight() { 935 checkWidget(); 936 return topRight; 937 } 938 939 949 public int indexOf(CTabItem item) { 950 if (item == null) { 952 SWT.error(SWT.ERROR_NULL_ARGUMENT); 953 } 954 for (int i = 0; i < items.length; i++) { 955 if (items[i] == item) { 956 return i; 957 } 958 } 959 return -1; 960 } 961 962 private void initAccessible() { 963 final Accessible accessible = getAccessible(); 964 accessible.addAccessibleListener(new AccessibleAdapter() { 965 public void getName(AccessibleEvent e) { 966 String name = null; 967 int childID = e.childID; 968 if (childID >= 0 && childID < items.length) { 969 name = items[childID].getText(); 970 int index = name.indexOf('&'); 971 if (index > 0) { 972 name = name.substring(0, index) 973 + name.substring(index + 1); 974 } 975 } 976 e.result = name; 977 } 978 979 public void getHelp(AccessibleEvent e) { 980 String help = null; 981 int childID = e.childID; 982 if (childID == ACC.CHILDID_SELF) { 983 help = getToolTipText(); 984 } else if (childID >= 0 && childID < items.length) { 985 help = items[childID].getToolTipText(); 986 } 987 e.result = help; 988 } 989 990 public void getKeyboardShortcut(AccessibleEvent e) { 991 String shortcut = null; 992 int childID = e.childID; 993 if (childID >= 0 && childID < items.length) { 994 String text = items[childID].getText(); 995 if (text != null) { 996 char mnemonic = getMnemonic(text); 997 if (mnemonic != '\0') { 998 shortcut = "Alt+" + mnemonic; } 1000 } 1001 } 1002 e.result = shortcut; 1003 } 1004 }); 1005 1006 accessible.addAccessibleControlListener(new AccessibleControlAdapter() { 1007 public void getChildAtPoint(AccessibleControlEvent e) { 1008 Point testPoint = toControl(new Point(e.x, e.y)); 1009 int childID = ACC.CHILDID_NONE; 1010 for (int i = 0; i < items.length; i++) { 1011 if (items[i].getBounds().contains(testPoint)) { 1012 childID = i; 1013 break; 1014 } 1015 } 1016 if (childID == ACC.CHILDID_NONE) { 1017 Rectangle location = getBounds(); 1018 location.height = location.height - getClientArea().height; 1019 if (location.contains(testPoint)) { 1020 childID = ACC.CHILDID_SELF; 1021 } 1022 } 1023 e.childID = childID; 1024 } 1025 1026 public void getLocation(AccessibleControlEvent e) { 1027 Rectangle location = null; 1028 int childID = e.childID; 1029 if (childID == ACC.CHILDID_SELF) { 1030 location = getBounds(); 1031 } 1032 if (childID >= 0 && childID < items.length) { 1033 location = items[childID].getBounds(); 1034 } 1035 if (location != null) { 1036 Point pt = toDisplay(new Point(location.x, location.y)); 1037 e.x = pt.x; 1038 e.y = pt.y; 1039 e.width = location.width; 1040 e.height = location.height; 1041 } 1042 } 1043 1044 public void getChildCount(AccessibleControlEvent e) { 1045 e.detail = items.length; 1046 } 1047 1048 public void getDefaultAction(AccessibleControlEvent e) { 1049 String action = null; 1050 int childID = e.childID; 1051 if (childID >= 0 && childID < items.length) { 1052 action = "Switch"; } 1054 e.result = action; 1055 } 1056 1057 public void getFocus(AccessibleControlEvent e) { 1058 int childID = ACC.CHILDID_NONE; 1059 if (isFocusControl()) { 1060 if (selectedIndex == -1) { 1061 childID = ACC.CHILDID_SELF; 1062 } else { 1063 childID = selectedIndex; 1064 } 1065 } 1066 e.childID = childID; 1067 } 1068 1069 public void getRole(AccessibleControlEvent e) { 1070 int role = 0; 1071 int childID = e.childID; 1072 if (childID == ACC.CHILDID_SELF) { 1073 role = ACC.ROLE_TABFOLDER; 1074 } else if (childID >= 0 && childID < items.length) { 1075 role = ACC.ROLE_TABITEM; 1076 } 1077 e.detail = role; 1078 } 1079 1080 public void getSelection(AccessibleControlEvent e) { 1081 e.childID = (selectedIndex == -1) ? ACC.CHILDID_NONE 1082 : selectedIndex; 1083 } 1084 1085 public void getState(AccessibleControlEvent e) { 1086 int state = 0; 1087 int childID = e.childID; 1088 if (childID == ACC.CHILDID_SELF) { 1089 state = ACC.STATE_NORMAL; 1090 } else if (childID >= 0 && childID < items.length) { 1091 state = ACC.STATE_SELECTABLE; 1092 if (isFocusControl()) { 1093 state |= ACC.STATE_FOCUSABLE; 1094 } 1095 if (selectedIndex == childID) { 1096 state |= ACC.STATE_SELECTED; 1097 if (isFocusControl()) { 1098 state |= ACC.STATE_FOCUSED; 1099 } 1100 } 1101 } 1102 e.detail = state; 1103 } 1104 1105 public void getChildren(AccessibleControlEvent e) { 1106 Object [] children = new Object [items.length]; 1107 for (int i = 0; i < items.length; i++) { 1108 children[i] = new Integer (i); 1109 } 1110 e.children = children; 1111 } 1112 }); 1113 1114 addListener(SWT.Selection, new Listener() { 1115 public void handleEvent(Event event) { 1116 if (isFocusControl()) { 1117 if (selectedIndex == -1) { 1118 accessible.setFocus(ACC.CHILDID_SELF); 1119 } else { 1120 accessible.setFocus(selectedIndex); 1121 } 1122 } 1123 } 1124 }); 1125 1126 addListener(SWT.FocusIn, new Listener() { 1127 public void handleEvent(Event event) { 1128 if (selectedIndex == -1) { 1129 accessible.setFocus(ACC.CHILDID_SELF); 1130 } else { 1131 accessible.setFocus(selectedIndex); 1132 } 1133 } 1134 }); 1135 } 1136 1137 private void setButtonBounds() { 1138 1139 updateArrowBar(); 1140 updateCloseBar(); 1141 1142 Rectangle area = super.getClientArea(); 1143 1144 int offset = 0; 1145 if (topRight != null) { 1146 Point size = topRight.computeSize(SWT.DEFAULT, tabHeight); 1147 int x = area.x + area.width - borderRight - size.x; 1148 int y = onBottom ? area.y + area.height - borderBottom - size.y 1149 : area.y + borderTop; 1150 topRight.setBounds(x, y, size.x, size.y); 1151 offset = size.x; 1152 } 1153 boolean leftVisible = scroll_leftVisible(); 1154 boolean rightVisible = scroll_rightVisible(); 1155 if (leftVisible || rightVisible) { 1156 Point size = arrowBar.computeSize(SWT.DEFAULT, tabHeight); 1157 int x = area.x + area.width - borderRight - size.x - offset; 1158 int y = (onBottom) ? area.y + area.height - borderBottom - size.y 1159 : area.y + borderTop; 1160 1161 arrowBar.setBounds(x, y, size.x, size.y); 1162 ToolItem[] items = arrowBar.getItems(); 1163 items[0].setEnabled(leftVisible); 1164 items[1].setEnabled(rightVisible); 1165 arrowBar.setVisible(true); 1166 } else { 1167 arrowBar.setVisible(false); 1168 } 1169 1170 if (showClose) { 1173 inactiveCloseBar.setVisible(false); 1174 CTabItem item = getSelection(); 1175 if (item == null) { 1176 closeBar.setVisible(false); 1177 } else { 1178 int toolbarHeight = tabHeight - CTabItem.TOP_MARGIN 1179 - CTabItem.BOTTOM_MARGIN + 2; Point size = closeBar.computeSize(SWT.DEFAULT, toolbarHeight); 1181 int x = item.x + item.width - size.x - 2; int y = item.y + Math.max(0, (item.height - toolbarHeight) / 2); 1183 closeBar.setBounds(x, y, size.x, toolbarHeight); 1184 Rectangle toolspace = getToolSpace(); 1185 Point folderSize = getSize(); 1186 boolean visible = (toolspace.width == 0 || x < toolspace.x) 1187 && x + size.x < folderSize.x - borderRight; 1188 closeBar.setVisible(visible); 1189 } 1190 } 1191 } 1192 1193 private boolean setItemLocation() { 1194 if (items.length == 0) { 1195 return false; 1196 } 1197 Rectangle area = super.getClientArea(); 1198 int x = area.x; 1199 int y = area.y + borderTop; 1200 if (onBottom) { 1201 y = Math.max(0, area.y + area.height - borderBottom - tabHeight); 1202 } 1203 1204 boolean changed = false; 1205 for (int i = topTabIndex - 1; i >= 0; i--) { 1206 CTabItem tab = items[i]; 1208 x -= tab.width; 1209 if (!changed && (tab.x != x || tab.y != y)) { 1210 changed = true; 1211 } 1212 tab.x = x; 1214 tab.y = y; 1215 } 1216 1217 x = area.x + borderLeft; 1218 for (int i = topTabIndex; i < items.length; i++) { 1219 CTabItem tab = items[i]; 1221 tab.x = x; 1222 tab.y = y; 1223 x = x + tab.width; 1224 } 1225 setButtonBounds(); 1226 return changed; 1227 } 1228 1229 private void setLastItem(int index) { 1230 if (index < 0 || index > items.length - 1) { 1231 return; 1232 } 1233 Rectangle area = getClientArea(); 1234 if (area.width <= 0) { 1235 return; 1236 } 1237 int maxWidth = area.width; 1238 Rectangle toolspace = getToolSpace(); 1239 if (toolspace.width > 0) { 1240 maxWidth -= toolspace.width; 1241 } 1242 int tabWidth = items[index].width; 1243 while (index > 0) { 1244 tabWidth += items[index - 1].width; 1245 if (tabWidth > maxWidth) { 1246 break; 1247 } 1248 index--; 1249 } 1250 topTabIndex = index; 1251 setItemLocation(); 1252 redrawTabArea(-1); 1253 } 1254 1255 1258 boolean setItemBounds() { 1259 boolean changed = false; 1260 if (isDisposed()) { 1261 return changed; 1262 } 1263 Rectangle area = super.getClientArea(); 1264 1265 xClient = area.x + borderLeft + marginWidth; 1266 if (onBottom) { 1267 yClient = area.y + borderTop + marginHeight; 1268 } else { 1269 yClient = area.y + borderTop + tabHeight + 1 + marginHeight; 1270 } 1272 1273 if (area.width <= 0 || area.height <= 0 || items.length == 0) { 1274 return changed; 1275 } 1276 1277 int[] widths = new int[items.length]; 1278 GC gc = new GC(this); 1279 for (int i = 0; i < items.length; i++) { 1280 widths[i] = items[i].preferredWidth(gc); 1281 } 1282 gc.dispose(); 1283 1284 int oldAverageWidth = 0; 1285 int averageWidth = (area.width - borderLeft - borderRight) 1286 / items.length; 1287 while (averageWidth > oldAverageWidth) { 1288 int width = area.width - borderLeft - borderRight; 1289 int count = items.length; 1290 for (int i = 0; i < items.length; i++) { 1291 if (widths[i] < averageWidth) { 1292 width -= widths[i]; 1293 count--; 1294 } 1295 } 1296 oldAverageWidth = averageWidth; 1297 if (count > 0) { 1298 averageWidth = width / count; 1299 } 1300 } 1301 averageWidth = Math.max(averageWidth, MIN_TAB_WIDTH * tabHeight); 1302 for (int i = 0; i < items.length; i++) { 1303 if (widths[i] > averageWidth) { 1304 widths[i] = averageWidth; 1305 } 1306 } 1307 1308 int totalWidth = 0; 1309 for (int i = 0; i < items.length; i++) { 1310 CTabItem tab = items[i]; 1311 if (tab.height != tabHeight || tab.width != widths[i]) { 1312 changed = true; 1313 } 1314 tab.height = tabHeight; 1315 tab.width = widths[i]; 1316 totalWidth += widths[i]; 1317 } 1318 1319 int areaWidth = area.x + area.width - borderRight; 1320 if (totalWidth <= areaWidth) { 1321 topTabIndex = 0; 1322 } 1323 if (setItemLocation()) { 1324 changed = true; 1325 } 1326 1327 if (correctLastItem()) { 1329 changed = true; 1330 } 1331 return changed; 1332 } 1333 1334 private boolean onMnemonic(Event event) { 1335 char key = event.character; 1336 for (int i = 0; i < items.length; i++) { 1337 if (items[i] != null) { 1338 char mnemonic = getMnemonic(items[i].getText()); 1339 if (mnemonic != '\0') { 1340 if (Character.toUpperCase(key) == Character 1341 .toUpperCase(mnemonic)) { 1342 setSelection(i, true); 1343 return true; 1344 } 1345 } 1346 } 1347 } 1348 return false; 1349 } 1350 1351 1354 private void onPaint(Event event) { 1355 Font font = getFont(); 1356 if (oldFont == null || !oldFont.equals(font)) { 1357 oldFont = font; 1358 resetTabSize(true); 1359 } 1360 GC gc = event.gc; 1361 Rectangle rect = super.getClientArea(); 1362 if (items.length == 0) { 1363 if (showBorders) { 1364 if ((getStyle() & SWT.FLAT) != 0) { 1365 gc.setForeground(borderColor1); 1366 gc.drawRectangle(rect.x, rect.y, rect.x + rect.width - 1, 1367 rect.y + rect.height - 1); 1368 } else { 1369 gc.setForeground(borderColor1); 1370 gc.drawRectangle(rect.x, rect.y, rect.x + rect.width - 3, 1371 rect.y + rect.height - 3); 1372 1373 gc.setBackground(getParent().getBackground()); 1375 gc.fillRectangle(rect.x + rect.width - 2, rect.y, 2, 1376 rect.height); 1377 gc.fillRectangle(rect.x, rect.y + rect.height - 2, 1378 rect.width, 2); 1379 } 1380 gc.setForeground(getForeground()); 1381 } 1382 return; 1383 } 1384 1385 drawBorder(gc); 1387 1388 rect.x += borderLeft; 1389 rect.y += borderTop; 1390 rect.width -= borderLeft + borderRight; 1391 rect.height -= borderTop + borderBottom; 1392 Rectangle clip = gc.getClipping(); 1393 gc.setClipping(clip.intersection(rect)); 1394 1395 for (int i = 0; i < items.length; i++) { 1397 if (i != selectedIndex 1398 && event.getBounds().intersects(items[i].getBounds())) { 1399 items[i].onPaint(gc, false); 1400 } 1401 } 1402 if (selectedIndex != -1) { 1404 items[selectedIndex].onPaint(gc, true); 1405 } 1406 1407 if (insertionIndex > -2) { 1409 gc.setForeground(getDisplay().getSystemColor( 1410 SWT.COLOR_LIST_SELECTION)); 1411 if (insertionIndex == -1) { 1412 Rectangle bounds = items[0].getBounds(); 1413 gc.drawLine(bounds.x, bounds.y, bounds.x, bounds.y 1414 + bounds.height - 1); 1415 gc.drawLine(bounds.x - 2, bounds.y, bounds.x + 2, bounds.y); 1416 gc.drawLine(bounds.x - 1, bounds.y + 1, bounds.x + 1, 1417 bounds.y + 1); 1418 gc.drawLine(bounds.x - 1, bounds.y + bounds.height - 2, 1419 bounds.x + 1, bounds.y + bounds.height - 2); 1420 gc.drawLine(bounds.x - 2, bounds.y + bounds.height - 1, 1421 bounds.x + 2, bounds.y + bounds.height - 1); 1422 1423 } else { 1424 Rectangle bounds = items[insertionIndex].getBounds(); 1425 gc.drawLine(bounds.x + bounds.width, bounds.y, bounds.x 1426 + bounds.width, bounds.y + bounds.height - 1); 1427 gc.drawLine(bounds.x + bounds.width - 2, bounds.y, bounds.x 1428 + bounds.width + 2, bounds.y); 1429 gc.drawLine(bounds.x + bounds.width - 1, bounds.y + 1, bounds.x 1430 + bounds.width + 1, bounds.y + 1); 1431 gc.drawLine(bounds.x + bounds.width - 1, bounds.y 1432 + bounds.height - 2, bounds.x + bounds.width + 1, 1433 bounds.y + bounds.height - 2); 1434 gc.drawLine(bounds.x + bounds.width - 2, bounds.y 1435 + bounds.height - 1, bounds.x + bounds.width + 2, 1436 bounds.y + bounds.height - 1); 1437 } 1438 } 1439 1440 gc.setForeground(getForeground()); 1441 gc.setBackground(getBackground()); 1442 } 1443 1444 private void redrawTabArea(int index) { 1445 int x = 0, y = 0, width = 0, height = 0; 1446 if (index == -1) { 1447 Rectangle area = super.getClientArea(); 1448 if (area.width == 0 || area.height == 0) { 1449 return; 1450 } 1451 width = area.x + area.width - borderLeft - borderRight; 1452 height = tabHeight + 1; x = area.x + borderLeft; 1454 y = area.y + borderTop; 1455 if (onBottom) { 1456 y = Math.max(0, area.y + area.height - borderBottom - height); 1457 } 1458 } else { 1459 CTabItem item = items[index]; 1460 x = item.x; 1461 y = item.y; 1462 Rectangle area = super.getClientArea(); 1463 width = area.x + area.width - x; 1464 height = item.height; 1465 } 1466 redraw(x, y, width, height, false); 1467 } 1468 1469 1479 public void removeSelectionListener(SelectionListener listener) { 1480 checkWidget(); 1481 if (listener == null) { 1482 SWT.error(SWT.ERROR_NULL_ARGUMENT); 1483 } 1484 removeListener(SWT.Selection, listener); 1485 removeListener(SWT.DefaultSelection, listener); 1486 } 1487 1488 1498 public void removeCTabFolderListener(CTabFolderListener listener) { 1499 checkWidget(); 1500 if (listener == null) { 1501 SWT.error(SWT.ERROR_NULL_ARGUMENT); 1502 } 1503 if (tabListeners.length == 0) { 1504 return; 1505 } 1506 int index = -1; 1507 for (int i = 0; i < tabListeners.length; i++) { 1508 if (listener == tabListeners[i]) { 1509 index = i; 1510 break; 1511 } 1512 } 1513 if (index == -1) { 1514 return; 1515 } 1516 if (tabListeners.length == 1) { 1517 tabListeners = new CTabFolderListener[0]; 1518 showClose = false; 1519 setButtonBounds(); 1520 return; 1521 } 1522 CTabFolderListener[] newTabListeners = new CTabFolderListener[tabListeners.length - 1]; 1523 System.arraycopy(tabListeners, 0, newTabListeners, 0, index); 1524 System.arraycopy(tabListeners, index + 1, newTabListeners, index, 1525 tabListeners.length - index - 1); 1526 tabListeners = newTabListeners; 1527 } 1528 1529 1532 private void onResize() { 1533 1534 if (items.length == 0) { 1535 redraw(); 1536 return; 1537 } 1538 1539 if (setItemBounds()) { 1540 redrawTabArea(-1); 1541 } 1542 1543 Point size = getSize(); 1544 if (oldSize == null) { 1545 redraw(); 1546 } else { 1547 if (onBottom && size.y != oldSize.y) { 1548 redraw(); 1549 } else { 1550 int x1 = Math.min(size.x, oldSize.x); 1551 if (size.x != oldSize.x) { 1552 x1 -= 10; 1553 } 1554 int y1 = Math.min(size.y, oldSize.y); 1555 if (size.y != oldSize.y) { 1556 y1 -= 10; 1557 } 1558 int x2 = Math.max(size.x, oldSize.x); 1559 int y2 = Math.max(size.y, oldSize.y); 1560 redraw(0, y1, x2 + 10, y2 - y1, false); 1561 redraw(x1, 0, x2 - x1, y2, false); 1562 } 1563 } 1564 oldSize = size; 1565 1566 if (selectedIndex != -1) { 1568 Control control = items[selectedIndex].getControl(); 1569 if (control != null && !control.isDisposed()) { 1570 control.setBounds(getClientArea()); 1571 } 1572 } 1573 } 1574 1575 public void setBackground(Color color) { 1576 super.setBackground(color); 1577 background = color; 1578 inactiveCloseBar.setBackground(color); 1580 1581 arrowBar.setBackground(color); 1583 1584 if (topRight != null) { 1586 topRight.setBackground(color); 1587 } 1588 1589 if (gradientColors == null) { 1591 closeBar.setBackground(color); 1592 } 1593 } 1594 1595 1620 1621 public void setSelectionBackground(Color[] colors, int[] percents) { 1622 checkWidget(); 1623 if (colors != null) { 1624 if (percents == null || percents.length != colors.length - 1) { 1625 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 1626 } 1627 if (getDisplay().getDepth() < 15) { 1628 colors = new Color[] { colors[0] }; 1630 percents = new int[] {}; 1631 } 1632 for (int i = 0; i < percents.length; i++) { 1633 if (percents[i] < 0 || percents[i] > 100) { 1634 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 1635 } 1636 if (i > 0 && percents[i] < percents[i - 1]) { 1637 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 1638 } 1639 } 1640 } 1641 1642 if (backgroundImage == null) { 1644 if ((gradientColors != null) && (colors != null) 1645 && (gradientColors.length == colors.length)) { 1646 boolean same = false; 1647 for (int i = 0; i < gradientColors.length; i++) { 1648 if (gradientColors[i] == null) { 1649 same = colors[i] == null; 1650 } else { 1651 same = gradientColors[i].equals(colors[i]); 1652 } 1653 if (!same) { 1654 break; 1655 } 1656 } 1657 if (same) { 1658 for (int i = 0; i < gradientPercents.length; i++) { 1659 same = gradientPercents[i] == percents[i]; 1660 if (!same) { 1661 break; 1662 } 1663 } 1664 } 1665 if (same) { 1666 return; 1667 } 1668 } 1669 } else { 1670 backgroundImage = null; 1671 } 1672 if (colors == null) { 1674 gradientColors = null; 1675 gradientPercents = null; 1676 closeBar.setBackground(background); 1677 } else { 1678 gradientColors = new Color[colors.length]; 1679 for (int i = 0; i < colors.length; ++i) { 1680 gradientColors[i] = colors[i]; 1681 } 1682 gradientPercents = new int[percents.length]; 1683 for (int i = 0; i < percents.length; ++i) { 1684 gradientPercents[i] = percents[i]; 1685 } 1686 if (getDisplay().getDepth() < 15) { 1687 closeBar.setBackground(background); 1688 } else { 1689 closeBar 1690 .setBackground(gradientColors[gradientColors.length - 1]); 1691 } 1692 } 1693 1694 if (selectedIndex > -1) { 1696 redrawTabArea(selectedIndex); 1697 } 1698 } 1699 1700 1710 public void setSelectionBackground(Image image) { 1711 checkWidget(); 1712 if (image == backgroundImage) { 1713 return; 1714 } 1715 if (image != null) { 1716 gradientColors = null; 1717 gradientPercents = null; 1718 } 1719 backgroundImage = image; 1720 redrawTabArea(selectedIndex); 1721 } 1722 1723 1733 public void setBorderVisible(boolean show) { 1734 checkWidget(); 1735 1737 showBorders = show; 1738 if (showBorders) { 1739 if ((getStyle() & SWT.FLAT) != 0) { 1740 borderBottom = borderTop = borderLeft = borderRight = 1; 1741 } else { 1742 borderLeft = borderTop = 1; 1743 borderRight = borderBottom = 3; 1744 } 1745 } else { 1746 borderBottom = borderTop = borderLeft = borderRight = 0; 1747 } 1748 oldSize = null; 1749 notifyListeners(SWT.Resize, new Event()); 1750 } 1751 1752 public void setFont(Font font) { 1753 checkWidget(); 1754 if (font != null && font.equals(getFont())) { 1755 return; 1756 } 1757 super.setFont(font); 1758 oldFont = getFont(); 1759 resetTabSize(true); 1760 } 1761 1762 1772 public void setSelectionForeground(Color color) { 1773 checkWidget(); 1774 if (selectionForeground == color) { 1775 return; 1776 } 1777 if (color == null) { 1778 color = getForeground(); 1779 } 1780 selectionForeground = color; 1781 if (selectedIndex > -1) { 1782 redrawTabArea(selectedIndex); 1783 } 1784 } 1785 1786 1800 public void setInsertMark(CTabItem item, boolean after) { 1801 checkWidget(); 1802 int index = -1; 1803 if (item != null) { 1804 index = indexOf(item); 1805 } 1806 setInsertMark(index, after); 1807 } 1808 1809 1823 public void setInsertMark(int index, boolean after) { 1824 checkWidget(); 1825 if (index < -1 || index >= getItemCount()) { 1826 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 1827 } 1828 1829 if (index == -1) { 1830 index = -2; 1831 } else { 1832 index = after ? index : --index; 1833 } 1834 1835 if (insertionIndex == index) { 1836 return; 1837 } 1838 int oldIndex = insertionIndex; 1839 insertionIndex = index; 1840 if (index > -1) { 1841 redrawTabArea(index); 1842 } 1843 if (oldIndex > 1) { 1844 redrawTabArea(oldIndex); 1845 } 1846 } 1847 1848 1858 public void setSelection(int index) { 1859 checkWidget(); 1860 if (index < 0 || index >= items.length) { 1861 return; 1862 } 1863 if (selectedIndex == index) { 1864 return; 1865 } 1866 1867 int oldIndex = selectedIndex; 1868 selectedIndex = index; 1869 1870 Control control = items[index].control; 1871 if (control != null && !control.isDisposed()) { 1872 control.setBounds(getClientArea()); 1873 control.setVisible(true); 1874 } 1875 1876 if (oldIndex != -1) { 1877 control = items[oldIndex].control; 1878 if (control != null && !control.isDisposed()) { 1879 control.setVisible(false); 1880 } 1881 } 1882 showItem(items[selectedIndex]); 1883 setButtonBounds(); 1884 redrawTabArea(-1); 1885 } 1886 1887 1902 public void setTopRight(Control control) { 1903 checkWidget(); 1904 if (control != null && control.getParent() != this) { 1905 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 1906 } 1907 topRight = control; 1908 resetTabSize(true); 1909 } 1910 1911 1931 public void showItem(CTabItem item) { 1932 checkWidget(); 1933 if (item == null) { 1934 SWT.error(SWT.ERROR_NULL_ARGUMENT); 1935 } 1936 if (item.isDisposed()) { 1937 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 1938 } 1939 1940 int index = indexOf(item); 1941 if (index < topTabIndex) { 1942 topTabIndex = index; 1943 setItemLocation(); 1944 redrawTabArea(-1); 1945 return; 1946 } 1947 Rectangle area = getClientArea(); 1948 if (area.width <= 0) { 1949 topTabIndex = index; 1950 return; 1951 } 1952 int rightEdge = area.x + area.width; 1953 Rectangle rect = getToolSpace(); 1954 if (rect.width > 0) { 1955 rightEdge -= rect.width; 1956 } 1957 if (item.x + item.width < rightEdge) { 1958 return; 1959 } 1960 setLastItem(index); 1961 } 1962 1963 1981 public void showSelection() { 1982 checkWidget(); 1983 if (selectedIndex != -1) { 1984 showItem(getSelection()); 1985 } 1986 } 1987 1988 char getMnemonic(String string) { 1989 int index = 0; 1990 int length = string.length(); 1991 do { 1992 while ((index < length) && (string.charAt(index) != '&')) { 1993 index++; 1994 } 1995 if (++index >= length) { 1996 return '\0'; 1997 } 1998 if (string.charAt(index) != '&') { 1999 return string.charAt(index); 2000 } 2001 index++; 2002 } while (index < length); 2003 return '\0'; 2004 } 2005 2006 2017 public void setSelection(CTabItem item) { 2018 checkWidget(); 2019 if (item == null) { 2020 SWT.error(SWT.ERROR_NULL_ARGUMENT); 2021 } 2022 int index = indexOf(item); 2023 setSelection(index); 2024 } 2025 2026 2029 private void setSelection(int index, boolean notify) { 2030 int oldSelectedIndex = selectedIndex; 2031 setSelection(index); 2032 if (notify && selectedIndex != oldSelectedIndex && selectedIndex != -1) { 2033 Event event = new Event(); 2034 event.item = getItem(selectedIndex); 2035 notifyListeners(SWT.Selection, event); 2036 } 2037 } 2038 2039 private Image scaleImage(Image image, int oldSize, int newSize) { 2040 Display display = getDisplay(); 2041 Color foreground = getForeground(); 2042 Color black = display.getSystemColor(SWT.COLOR_BLACK); 2043 Color background = getBackground(); 2044 PaletteData palette = new PaletteData(new RGB[] { foreground.getRGB(), 2045 background.getRGB(), black.getRGB() }); 2046 ImageData imageData = new ImageData(newSize, newSize, 4, palette); 2047 imageData.transparentPixel = 1; 2048 Image temp = new Image(display, imageData); 2049 GC gc = new GC(temp); 2050 gc.setBackground(background); 2051 gc.fillRectangle(0, 0, newSize, newSize); 2052 gc.drawImage(image, 0, 0, oldSize, oldSize, 0, 0, newSize, newSize); 2053 gc.dispose(); 2054 return temp; 2055 } 2056 2057 private void updateCloseBar() { 2058 int toolbarTrim = 4; 2060 String platform = SWT.getPlatform(); 2061 if ("photon".equals(platform)) { toolbarTrim = 6; 2063 } 2064 if ("gtk".equals(platform)) { toolbarTrim = 8; 2066 } 2067 2068 int maxHeight = tabHeight - CTabItem.TOP_MARGIN 2069 - CTabItem.BOTTOM_MARGIN - toolbarTrim; 2070 if (maxHeight < 3) { 2071 return; 2072 } 2073 int imageHeight = (maxHeight < 9) ? 9 : maxHeight; 2074 2075 if (closeImage != null && closeImage.getBounds().height == imageHeight) { 2076 return; 2077 } 2078 2079 if (closeBar != null) { 2080 closeBar.dispose(); 2081 } 2082 closeBar = null; 2083 if (inactiveCloseBar != null) { 2084 inactiveCloseBar.dispose(); 2085 } 2086 inactiveCloseBar = null; 2087 createCloseBar(); 2088 2089 ToolItem closeItem = closeBar.getItems()[0]; 2090 ToolItem inactiveCloseItem = inactiveCloseBar.getItems()[0]; 2091 2092 if (closeImage != null) { 2093 closeImage.dispose(); 2094 } 2095 2096 Display display = getDisplay(); 2097 Color foreground = getForeground(); 2098 Color black = display.getSystemColor(SWT.COLOR_BLACK); 2099 Color background = getBackground(); 2100 2101 PaletteData palette = new PaletteData(new RGB[] { foreground.getRGB(), 2102 background.getRGB(), black.getRGB() }); 2103 ImageData imageData = new ImageData(imageHeight, imageHeight, 4, 2104 palette); 2105 imageData.transparentPixel = 1; 2106 closeImage = new Image(display, imageData); 2107 GC gc = new GC(closeImage); 2108 gc.setBackground(background); 2109 gc.fillRectangle(0, 0, imageHeight, imageHeight); 2110 gc.setForeground(black); 2111 2112 int h = (imageHeight / 2) * 2; 2114 int inset = (h - 8) / 2; 2115 gc.drawLine(inset, inset, h - inset - 1, h - inset - 1); 2116 gc.drawLine(inset + 1, inset, h - inset, h - inset - 1); 2117 gc.drawLine(inset, h - inset - 1, h - inset - 1, inset); 2118 gc.drawLine(inset + 1, h - inset - 1, h - inset, inset); 2119 2120 gc.dispose(); 2121 2122 if (maxHeight < imageHeight) { 2123 Image temp = scaleImage(closeImage, imageHeight, maxHeight); 2125 closeImage.dispose(); 2126 closeImage = temp; 2127 } 2128 closeItem.setImage(closeImage); 2129 inactiveCloseItem.setImage(closeImage); 2130 } 2131 2132 private void updateArrowBar() { 2133 int toolbarTrim = 6; String platform = SWT.getPlatform(); 2136 if ("gtk".equals(platform)) { toolbarTrim = 8; 2138 } 2139 2140 int maxHeight = tabHeight - toolbarTrim; 2141 if (maxHeight < 3) { 2142 return; 2143 } 2144 int imageHeight = (maxHeight < 9) ? 9 : maxHeight; 2145 2146 if (arrowLeftImage != null 2147 && arrowLeftImage.getBounds().height == imageHeight) { 2148 return; 2149 } 2150 2151 if (arrowBar != null) { 2152 arrowBar.dispose(); 2153 } 2154 arrowBar = null; 2155 if (arrowLeftImage != null) { 2156 arrowLeftImage.dispose(); 2157 } 2158 if (arrowRightImage != null) { 2159 arrowRightImage.dispose(); 2160 } 2161 2162 createArrowBar(); 2163 ToolItem[] items = arrowBar.getItems(); 2164 ToolItem left = items[0]; 2165 ToolItem right = items[1]; 2166 2167 Display display = getDisplay(); 2168 Color foreground = getForeground(); 2169 Color black = display.getSystemColor(SWT.COLOR_BLACK); 2170 Color background = getBackground(); 2171 2172 PaletteData palette = new PaletteData(new RGB[] { foreground.getRGB(), 2173 background.getRGB(), black.getRGB() }); 2174 ImageData imageData = new ImageData(7, imageHeight, 4, palette); 2175 imageData.transparentPixel = 1; 2176 arrowLeftImage = new Image(display, imageData); 2177 GC gc = new GC(arrowLeftImage); 2178 gc.setBackground(background); 2179 gc.fillRectangle(0, 0, 7, imageHeight); 2180 gc.setBackground(black); 2181 int h = (imageHeight / 2) * 2; 2183 int midpoint = h / 2 - 1; 2184 int[] pointArr = new int[] { 6, midpoint - 5, 1, midpoint, 6, 2185 midpoint + 5, }; 2186 gc.fillPolygon(pointArr); 2187 gc.dispose(); 2188 2189 palette = new PaletteData(new RGB[] { foreground.getRGB(), 2190 background.getRGB(), black.getRGB() }); 2191 imageData = new ImageData(7, imageHeight, 4, palette); 2192 imageData.transparentPixel = 1; 2193 arrowRightImage = new Image(display, imageData); 2194 gc = new GC(arrowRightImage); 2195 gc.setBackground(background); 2196 gc.fillRectangle(0, 0, 7, imageHeight); 2197 gc.setBackground(black); 2198 pointArr = new int[] { 1, midpoint - 5, 6, midpoint, 1, midpoint + 5, }; 2200 gc.fillPolygon(pointArr); 2201 gc.dispose(); 2202 2203 if (maxHeight < imageHeight) { 2204 Image leftTemp = scaleImage(arrowLeftImage, imageHeight, maxHeight); 2206 arrowLeftImage.dispose(); 2207 arrowLeftImage = leftTemp; 2208 2209 Image rightTemp = scaleImage(arrowRightImage, imageHeight, 2210 maxHeight); 2211 arrowRightImage.dispose(); 2212 arrowRightImage = rightTemp; 2213 } 2214 left.setImage(arrowLeftImage); 2215 right.setImage(arrowRightImage); 2216 } 2217 2218 private void onMouseDoubleClick(Event event) { 2219 Event e = new Event(); 2220 e.item = getItem(new Point(event.x, event.y)); 2221 notifyListeners(SWT.DefaultSelection, e); 2222 } 2223 2224 2228 private void onMouseDown(Event event) { 2229 for (int i = 0; i < items.length; i++) { 2230 if (items[i].getBounds().contains(new Point(event.x, event.y))) { 2231 if (i == selectedIndex) { 2232 showSelection(); 2233 return; 2234 } 2235 forceFocus(); 2236 setSelection(i, true); 2237 if (isFocusControl()) { 2238 setFocus(); 2239 } 2240 return; 2241 } 2242 } 2243 } 2244 2245 private void onMouseExit(Event event) { 2246 Rectangle inactiveBounds = inactiveCloseBar.getBounds(); 2247 if (inactiveBounds.contains(event.x, event.y)) { 2248 return; 2249 } 2250 inactiveCloseBar.setVisible(false); 2251 inactiveItem = null; 2252 2253 showToolTip = false; 2254 toolTipItem = null; 2255 if (tip != null && !tip.isDisposed() && tip.isVisible()) { 2256 tip.setVisible(false); 2257 } 2258 } 2259 2260 private void onMouseHover(Event event) { 2261 if (tip == null || tip.isDisposed()) { 2262 return; 2263 } 2264 showToolTip = true; 2265 showToolTip(event.x, event.y); 2266 } 2267 2268 private void showToolTip(int x, int y) { 2269 CTabItem item = getItem(new Point(x, y)); 2270 if (item != null) { 2271 if (item == toolTipItem) { 2272 return; 2273 } 2274 toolTipItem = item; 2275 String tooltip = item.getToolTipText(); 2276 if (tooltip != null && tooltip.length() > 0) { 2277 Display display = tip.getDisplay(); 2278 label.setForeground(display 2279 .getSystemColor(SWT.COLOR_INFO_FOREGROUND)); 2280 label.setBackground(display 2281 .getSystemColor(SWT.COLOR_INFO_BACKGROUND)); 2282 label.setText(tooltip); 2283 Point labelSize = label.computeSize(SWT.DEFAULT, SWT.DEFAULT); 2284 labelSize.x += 2; 2285 labelSize.y += 2; 2286 label.setSize(labelSize); 2287 tip.pack(); 2288 2294 Rectangle area = tip.getClientArea(); 2295 label.setSize(area.width, area.height); 2296 2300 Point pt = new Point(item.x + item.width / 4, item.y 2301 + item.height + 2); 2302 pt = toDisplay(pt); 2303 Rectangle rect = display.getBounds(); 2304 Point tipSize = tip.getSize(); 2305 pt.x = Math.max(0, Math.min(pt.x, rect.width - tipSize.x)); 2306 pt.y = Math.max(0, Math.min(pt.y, rect.height - tipSize.y)); 2307 tip.setLocation(pt); 2308 tip.setVisible(true); 2309 return; 2310 } 2311 } 2312 2313 toolTipItem = null; 2314 if (tip != null && !tip.isDisposed() && tip.isVisible()) { 2315 tip.setVisible(false); 2316 } 2317 } 2318 2319 private void onMouseMove(Event event) { 2320 if (showToolTip) { 2321 showToolTip(event.x, event.y); 2322 } 2323 2324 if (!showClose) { 2325 return; 2326 } 2327 2328 CTabItem item = null; 2329 for (int i = 0; i < items.length; i++) { 2330 Rectangle rect = items[i].getBounds(); 2331 if (rect.contains(new Point(event.x, event.y))) { 2332 item = items[i]; 2333 break; 2334 } 2335 } 2336 if (item == inactiveItem) { 2337 return; 2338 } 2339 2340 inactiveCloseBar.setVisible(false); 2341 inactiveItem = null; 2342 2343 if (item == null || item == getSelection()) { 2344 return; 2345 } 2346 2347 int toolbarHeight = tabHeight - CTabItem.TOP_MARGIN 2348 - CTabItem.BOTTOM_MARGIN + 2; Point size = inactiveCloseBar.computeSize(SWT.DEFAULT, toolbarHeight); 2350 int x = item.x + item.width - size.x - 2; int y = item.y + Math.max(0, (item.height - toolbarHeight) / 2); 2352 Rectangle toolspace = getToolSpace(); 2353 Point folderSize = getSize(); 2354 if ((toolspace.width == 0 || x < toolspace.x) 2355 && x + size.x < folderSize.x - borderRight) { 2356 inactiveCloseBar.setBounds(x, y, size.x, toolbarHeight); 2357 inactiveCloseBar.setVisible(true); 2358 inactiveItem = item; 2359 } 2360 } 2361 2362 private void onTraverse(Event event) { 2363 switch (event.detail) { 2364 case SWT.TRAVERSE_ESCAPE: 2365 case SWT.TRAVERSE_TAB_NEXT: 2368 case SWT.TRAVERSE_TAB_PREVIOUS: 2369 event.doit = true; 2370 break; 2371 case SWT.TRAVERSE_MNEMONIC: 2372 event.doit = onMnemonic(event); 2373 if (event.doit) { 2374 event.detail = SWT.TRAVERSE_NONE; 2375 } 2376 break; 2377 case SWT.TRAVERSE_PAGE_NEXT: 2378 case SWT.TRAVERSE_PAGE_PREVIOUS: 2379 event.doit = onPageTraversal(event); 2380 if (event.doit) { 2381 event.detail = SWT.TRAVERSE_NONE; 2382 } 2383 break; 2384 } 2385 } 2386 2387 private boolean onPageTraversal(Event event) { 2388 int count = getItemCount(); 2389 if (count == 0) { 2390 return false; 2391 } 2392 int index = getSelectionIndex(); 2393 if (index == -1) { 2394 index = 0; 2395 } else { 2396 int offset = (event.detail == SWT.TRAVERSE_PAGE_NEXT) ? 1 : -1; 2397 index = (index + offset + count) % count; 2398 } 2399 setSelection(index, true); 2400 return true; 2401 } 2402 2403 2407 private boolean scroll_leftVisible() { 2408 return topTabIndex > 0; 2409 } 2410 2411 2415 private boolean scroll_rightVisible() { 2416 if (items.length < 2) { 2419 return false; 2420 } 2421 Rectangle area = getClientArea(); 2422 int rightEdge = area.x + area.width; 2423 if (rightEdge <= 0) { 2424 return false; 2425 } 2426 if (topTabIndex > 0) { 2427 rightEdge -= arrowBar.getSize().x; 2428 } 2429 if (topRight != null) { 2430 rightEdge -= topRight.getSize().x; 2431 } 2432 CTabItem item = items[items.length - 1]; 2433 return (item.x + item.width > rightEdge); 2434 } 2435 2436 2439 private void scroll_scrollLeft() { 2440 if (items.length == 0) { 2441 return; 2442 } 2443 setLastItem(topTabIndex - 1); 2444 } 2445 2446 2449 private void scroll_scrollRight() { 2450 int lastIndex = getLastItem(); 2451 topTabIndex = lastIndex + 1; 2452 setItemLocation(); 2453 correctLastItem(); 2454 redrawTabArea(-1); 2455 } 2456 2457 private boolean correctLastItem() { 2458 Rectangle area = getClientArea(); 2459 int rightEdge = area.x + area.width; 2460 if (rightEdge <= 0) { 2461 return false; 2462 } 2463 Rectangle toolspace = getToolSpace(); 2464 if (toolspace.width > 0) { 2465 rightEdge -= toolspace.width; 2466 } 2467 CTabItem item = items[items.length - 1]; 2468 if (item.x + item.width < rightEdge) { 2469 setLastItem(items.length - 1); 2470 return true; 2471 } 2472 return false; 2473 } 2474 2475 2488 public void setTabHeight(int height) { 2489 checkWidget(); 2490 if (height < 0) { 2491 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 2492 } 2493 fixedTabHeight = true; 2494 if (tabHeight == height) { 2495 return; 2496 } 2497 tabHeight = height; 2498 oldSize = null; 2499 notifyListeners(SWT.Resize, new Event()); 2500 } 2501 2502 void resetTabSize(boolean checkHeight) { 2503 int oldHeight = tabHeight; 2504 if (!fixedTabHeight && checkHeight) { 2505 int tempHeight = 0; 2506 GC gc = new GC(this); 2507 for (int i = 0; i < items.length; i++) { 2508 tempHeight = Math.max(tempHeight, items[i].preferredHeight(gc)); 2509 } 2510 gc.dispose(); 2511 if (topRight != null) { 2512 tempHeight = Math.max(tempHeight, topRight.computeSize( 2513 SWT.DEFAULT, SWT.DEFAULT).y); 2514 } 2515 tabHeight = tempHeight; 2516 } 2517 2518 if (tabHeight != oldHeight) { 2519 oldSize = null; 2520 notifyListeners(SWT.Resize, new Event()); 2521 } else { 2522 setItemBounds(); 2523 redraw(); 2524 } 2525 } 2526 2527 2538 public void setTabPosition(int position) { 2539 checkWidget(); 2540 if (position != SWT.TOP && position != SWT.BOTTOM) { 2541 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 2542 } 2543 if (onBottom != (position == SWT.BOTTOM)) { 2544 onBottom = position == SWT.BOTTOM; 2545 setBorderVisible(showBorders); 2546 resetTabSize(true); 2547 } 2558 } 2559 2560 public int getTabPosition() { 2561 if (onBottom) { 2562 return SWT.BOTTOM; 2563 } 2564 return SWT.TOP; 2565 } 2566 2567} 2568 | Popular Tags |