1 11 package org.eclipse.swt.custom; 12 13 import org.eclipse.swt.*; 14 import org.eclipse.swt.accessibility.*; 15 import org.eclipse.swt.events.*; 16 import org.eclipse.swt.graphics.*; 17 import org.eclipse.swt.widgets.*; 18 19 47 48 public class CTabFolder extends Composite { 49 50 56 public int marginWidth = 0; 57 63 public int marginHeight = 0; 64 65 74 public int MIN_TAB_WIDTH = 4; 75 76 84 public static RGB borderInsideRGB = new RGB (132, 130, 132); 85 93 public static RGB borderMiddleRGB = new RGB (143, 141, 138); 94 102 public static RGB borderOutsideRGB = new RGB (171, 168, 165); 103 104 105 int xClient, yClient; 106 boolean onBottom = false; 107 boolean single = false; 108 boolean simple = true; 109 int fixedTabHeight = SWT.DEFAULT; 110 int tabHeight; 111 int minChars = 20; 112 113 114 CTabItem items[] = new CTabItem[0]; 115 int firstIndex = -1; int selectedIndex = -1; 117 int[] priority = new int[0]; 118 boolean mru = false; 119 Listener listener; 120 121 122 CTabFolder2Listener[] folderListeners = new CTabFolder2Listener[0]; 123 CTabFolderListener[] tabListeners = new CTabFolderListener[0]; 125 126 127 Image selectionBgImage; 128 Color[] selectionGradientColors; 129 int[] selectionGradientPercents; 130 boolean selectionGradientVertical; 131 Color selectionForeground; 132 Color selectionBackground; Color selectionFadeStart; 134 135 Color selectionHighlightGradientBegin = null; Color[] selectionHighlightGradientColorsCache = null; 144 145 Image bgImage; 146 Color[] gradientColors; 147 int[] gradientPercents; 148 boolean gradientVertical; 149 boolean showUnselectedImage = true; 150 151 static Color borderColor; 152 153 boolean showClose = false; 155 boolean showUnselectedClose = true; 156 157 Rectangle chevronRect = new Rectangle(0, 0, 0, 0); 158 int chevronImageState = NORMAL; 159 boolean showChevron = false; 160 Menu showMenu; 161 162 boolean showMin = false; 163 Rectangle minRect = new Rectangle(0, 0, 0, 0); 164 boolean minimized = false; 165 int minImageState = NORMAL; 166 167 boolean showMax = false; 168 Rectangle maxRect = new Rectangle(0, 0, 0, 0); 169 boolean maximized = false; 170 int maxImageState = NORMAL; 171 172 Control topRight; 173 Rectangle topRightRect = new Rectangle(0, 0, 0, 0); 174 int topRightAlignment = SWT.RIGHT; 175 176 int borderLeft = 0; 178 int borderRight = 0; 179 int borderTop = 0; 180 int borderBottom = 0; 181 182 int highlight_margin = 0; 183 int highlight_header = 0; 184 185 int[] curve; 186 int[] topCurveHighlightStart; 187 int[] topCurveHighlightEnd; 188 int curveWidth = 0; 189 int curveIndent = 0; 190 191 boolean inDispose = false; 194 195 Point oldSize; 198 Font oldFont; 199 200 static final int DEFAULT_WIDTH = 64; 202 static final int DEFAULT_HEIGHT = 64; 203 static final int BUTTON_SIZE = 18; 204 205 static final int[] TOP_LEFT_CORNER = new int[] {0,6, 1,5, 1,4, 4,1, 5,1, 6,0}; 206 207 static final int[] TOP_LEFT_CORNER_HILITE = new int[] {5,2, 4,2, 3,3, 2,4, 2,5, 1,6}; 210 211 static final int[] TOP_RIGHT_CORNER = new int[] {-6,0, -5,1, -4,1, -1,4, -1,5, 0,6}; 212 static final int[] BOTTOM_LEFT_CORNER = new int[] {0,-6, 1,-5, 1,-4, 4,-1, 5,-1, 6,0}; 213 static final int[] BOTTOM_RIGHT_CORNER = new int[] {-6,0, -5,-1, -4,-1, -1,-4, -1,-5, 0,-6}; 214 215 static final int[] SIMPLE_TOP_LEFT_CORNER = new int[] {0,2, 1,1, 2,0}; 216 static final int[] SIMPLE_TOP_RIGHT_CORNER = new int[] {-2,0, -1,1, 0,2}; 217 static final int[] SIMPLE_BOTTOM_LEFT_CORNER = new int[] {0,-2, 1,-1, 2,0}; 218 static final int[] SIMPLE_BOTTOM_RIGHT_CORNER = new int[] {-2,0, -1,-1, 0,-2}; 219 static final int[] SIMPLE_UNSELECTED_INNER_CORNER = new int[] {0,0}; 220 221 static final int[] TOP_LEFT_CORNER_BORDERLESS = new int[] {0,6, 1,5, 1,4, 4,1, 5,1, 6,0}; 222 static final int[] TOP_RIGHT_CORNER_BORDERLESS = new int[] {-7,0, -6,1, -5,1, -2,4, -2,5, -1,6}; 223 static final int[] BOTTOM_LEFT_CORNER_BORDERLESS = new int[] {0,-6, 1,-6, 1,-5, 2,-4, 4,-2, 5,-1, 6,-1, 6,0}; 224 static final int[] BOTTOM_RIGHT_CORNER_BORDERLESS = new int[] {-7,0, -7,-1, -6,-1, -5,-2, -3,-4, -2,-5, -2,-6, -1,-6}; 225 226 static final int[] SIMPLE_TOP_LEFT_CORNER_BORDERLESS = new int[] {0,2, 1,1, 2,0}; 227 static final int[] SIMPLE_TOP_RIGHT_CORNER_BORDERLESS= new int[] {-3,0, -2,1, -1,2}; 228 static final int[] SIMPLE_BOTTOM_LEFT_CORNER_BORDERLESS = new int[] {0,-3, 1,-2, 2,-1, 3,0}; 229 static final int[] SIMPLE_BOTTOM_RIGHT_CORNER_BORDERLESS = new int[] {-4,0, -3,-1, -2,-2, -1,-3}; 230 231 static final int SELECTION_FOREGROUND = SWT.COLOR_LIST_FOREGROUND; 232 static final int SELECTION_BACKGROUND = SWT.COLOR_LIST_BACKGROUND; 233 static final int BORDER1_COLOR = SWT.COLOR_WIDGET_NORMAL_SHADOW; 234 static final int FOREGROUND = SWT.COLOR_WIDGET_FOREGROUND; 235 static final int BACKGROUND = SWT.COLOR_WIDGET_BACKGROUND; 236 static final int BUTTON_BORDER = SWT.COLOR_WIDGET_DARK_SHADOW; 237 static final int BUTTON_FILL = SWT.COLOR_LIST_BACKGROUND; 238 239 static final int NONE = 0; 240 static final int NORMAL = 1; 241 static final int HOT = 2; 242 static final int SELECTED = 3; 243 static final RGB CLOSE_FILL = new RGB(252, 160, 160); 244 245 static final int CHEVRON_CHILD_ID = 0; 246 static final int MINIMIZE_CHILD_ID = 1; 247 static final int MAXIMIZE_CHILD_ID = 2; 248 static final int EXTRA_CHILD_ID_COUNT = 3; 249 250 251 282 public CTabFolder(Composite parent, int style) { 283 super(parent, checkStyle (parent, style)); 284 super.setLayout(new CTabFolderLayout()); 285 int style2 = super.getStyle(); 286 oldFont = getFont(); 287 onBottom = (style2 & SWT.BOTTOM) != 0; 288 showClose = (style2 & SWT.CLOSE) != 0; 289 single = (style2 & SWT.SINGLE) != 0; 292 borderLeft = borderRight = (style & SWT.BORDER) != 0 ? 1 : 0; 293 borderTop = onBottom ? borderLeft : 0; 294 borderBottom = onBottom ? 0 : borderLeft; 295 highlight_header = (style & SWT.FLAT) != 0 ? 1 : 3; 296 highlight_margin = (style & SWT.FLAT) != 0 ? 0 : 2; 297 Display display = getDisplay(); 299 selectionForeground = display.getSystemColor(SELECTION_FOREGROUND); 300 selectionBackground = display.getSystemColor(SELECTION_BACKGROUND); 301 borderColor = display.getSystemColor(BORDER1_COLOR); 302 updateTabHeight(false); 303 304 initAccessible(); 305 306 listener = new Listener() { 308 public void handleEvent(Event event) { 309 switch (event.type) { 310 case SWT.Dispose: onDispose(event); break; 311 case SWT.DragDetect: onDragDetect(event); break; 312 case SWT.FocusIn: onFocus(event); break; 313 case SWT.FocusOut: onFocus(event); break; 314 case SWT.KeyDown: onKeyDown(event); break; 315 case SWT.MouseDoubleClick: onMouseDoubleClick(event); break; 316 case SWT.MouseDown: onMouse(event); break; 317 case SWT.MouseEnter: onMouse(event); break; 318 case SWT.MouseExit: onMouse(event); break; 319 case SWT.MouseMove: onMouse(event); break; 320 case SWT.MouseUp: onMouse(event); break; 321 case SWT.Paint: onPaint(event); break; 322 case SWT.Resize: onResize(); break; 323 case SWT.Traverse: onTraverse(event); break; 324 } 325 } 326 }; 327 328 int[] folderEvents = new int[]{ 329 SWT.Dispose, 330 SWT.DragDetect, 331 SWT.FocusIn, 332 SWT.FocusOut, 333 SWT.KeyDown, 334 SWT.MouseDoubleClick, 335 SWT.MouseDown, 336 SWT.MouseEnter, 337 SWT.MouseExit, 338 SWT.MouseMove, 339 SWT.MouseUp, 340 SWT.Paint, 341 SWT.Resize, 342 SWT.Traverse, 343 }; 344 for (int i = 0; i < folderEvents.length; i++) { 345 addListener(folderEvents[i], listener); 346 } 347 } 348 static int checkStyle (Composite parent, int style) { 349 int mask = SWT.CLOSE | SWT.TOP | SWT.BOTTOM | SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT | SWT.SINGLE | SWT.MULTI; 350 style = style & mask; 351 if ((style & SWT.TOP) != 0) style = style & ~SWT.BOTTOM; 354 if ((style & SWT.MULTI) != 0) style = style & ~SWT.SINGLE; 357 style |= SWT.NO_REDRAW_RESIZE; 359 367 String platform = SWT.getPlatform(); 368 if ("carbon".equals(platform) || "gtk".equals(platform)) return style; 370 377 if ((style & SWT.RIGHT_TO_LEFT) != 0) return style; 378 if ((parent.getStyle() & SWT.MIRRORED) != 0 && (style & SWT.LEFT_TO_RIGHT) == 0) return style; 379 380 return style | SWT.NO_BACKGROUND; 381 } 382 static void fillRegion(GC gc, Region region) { 383 Region clipping = new Region(); 385 gc.getClipping(clipping); 386 region.intersect(clipping); 387 gc.setClipping(region); 388 gc.fillRectangle(region.getBounds()); 389 gc.setClipping(clipping); 390 clipping.dispose(); 391 } 392 415 public void addCTabFolder2Listener(CTabFolder2Listener listener) { 416 checkWidget(); 417 if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 418 CTabFolder2Listener[] newListeners = new CTabFolder2Listener[folderListeners.length + 1]; 420 System.arraycopy(folderListeners, 0, newListeners, 0, folderListeners.length); 421 folderListeners = newListeners; 422 folderListeners[folderListeners.length - 1] = listener; 423 } 424 443 public void addCTabFolderListener(CTabFolderListener listener) { 444 checkWidget(); 445 if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 446 CTabFolderListener[] newTabListeners = new CTabFolderListener[tabListeners.length + 1]; 448 System.arraycopy(tabListeners, 0, newTabListeners, 0, tabListeners.length); 449 tabListeners = newTabListeners; 450 tabListeners[tabListeners.length - 1] = listener; 451 if (!showClose) { 453 showClose = true; 454 updateItems(); 455 redraw(); 456 } 457 } 458 482 public void addSelectionListener(SelectionListener listener) { 483 checkWidget(); 484 if (listener == null) { 485 SWT.error(SWT.ERROR_NULL_ARGUMENT); 486 } 487 TypedListener typedListener = new TypedListener(listener); 488 addListener(SWT.Selection, typedListener); 489 addListener(SWT.DefaultSelection, typedListener); 490 } 491 void antialias (int[] shape, RGB lineRGB, RGB innerRGB, RGB outerRGB, GC gc){ 492 if (simple || "carbon".equals(SWT.getPlatform()) || "wpf".equals(SWT.getPlatform())) return; if (getDisplay().getDepth() < 15) return; 497 if (outerRGB != null) { 498 int index = 0; 499 boolean left = true; 500 int oldY = onBottom ? 0 : getSize().y; 501 int[] outer = new int[shape.length]; 502 for (int i = 0; i < shape.length/2; i++) { 503 if (left && (index + 3 < shape.length)) { 504 left = onBottom ? oldY <= shape[index+3] : oldY >= shape[index+3]; 505 oldY = shape[index+1]; 506 } 507 outer[index] = shape[index++] + (left ? -1 : +1); 508 outer[index] = shape[index++]; 509 } 510 RGB from = lineRGB; 511 RGB to = outerRGB; 512 int red = from.red + 2*(to.red - from.red)/3; 513 int green = from.green + 2*(to.green - from.green)/3; 514 int blue = from.blue + 2*(to.blue - from.blue)/3; 515 Color color = new Color(getDisplay(), red, green, blue); 516 gc.setForeground(color); 517 gc.drawPolyline(outer); 518 color.dispose(); 519 } 520 if (innerRGB != null) { 521 int[] inner = new int[shape.length]; 522 int index = 0; 523 boolean left = true; 524 int oldY = onBottom ? 0 : getSize().y; 525 for (int i = 0; i < shape.length/2; i++) { 526 if (left && (index + 3 < shape.length)) { 527 left = onBottom ? oldY <= shape[index+3] : oldY >= shape[index+3]; 528 oldY = shape[index+1]; 529 } 530 inner[index] = shape[index++] + (left ? +1 : -1); 531 inner[index] = shape[index++]; 532 } 533 RGB from = lineRGB; 534 RGB to = innerRGB; 535 int red = from.red + 2*(to.red - from.red)/3; 536 int green = from.green + 2*(to.green - from.green)/3; 537 int blue = from.blue + 2*(to.blue - from.blue)/3; 538 Color color = new Color(getDisplay(), red, green, blue); 539 gc.setForeground(color); 540 gc.drawPolyline(inner); 541 color.dispose(); 542 } 543 } 544 public Rectangle computeTrim (int x, int y, int width, int height) { 545 checkWidget(); 546 int trimX = x - marginWidth - highlight_margin - borderLeft; 547 int trimWidth = width + borderLeft + borderRight + 2*marginWidth + 2*highlight_margin; 548 if (minimized) { 549 int trimY = onBottom ? y - borderTop : y - highlight_header - tabHeight - borderTop; 550 int trimHeight = borderTop + borderBottom + tabHeight + highlight_header; 551 return new Rectangle (trimX, trimY, trimWidth, trimHeight); 552 } else { 553 int trimY = onBottom ? y - marginHeight - highlight_margin - borderTop: y - marginHeight - highlight_header - tabHeight - borderTop; 554 int trimHeight = height + borderTop + borderBottom + 2*marginHeight + tabHeight + highlight_header + highlight_margin; 555 return new Rectangle (trimX, trimY, trimWidth, trimHeight); 556 } 557 } 558 void createItem (CTabItem item, int index) { 559 if (0 > index || index > getItemCount ())SWT.error (SWT.ERROR_INVALID_RANGE); 560 item.parent = this; 561 CTabItem[] newItems = new CTabItem [items.length + 1]; 562 System.arraycopy(items, 0, newItems, 0, index); 563 newItems[index] = item; 564 System.arraycopy(items, index, newItems, index + 1, items.length - index); 565 items = newItems; 566 if (selectedIndex >= index) selectedIndex ++; 567 int[] newPriority = new int[priority.length + 1]; 568 int next = 0, priorityIndex = priority.length; 569 for (int i = 0; i < priority.length; i++) { 570 if (!mru && priority[i] == index) { 571 priorityIndex = next++; 572 } 573 newPriority[next++] = priority[i] >= index ? priority[i] + 1 : priority[i]; 574 } 575 newPriority[priorityIndex] = index; 576 priority = newPriority; 577 578 if (items.length == 1) { 579 if (!updateTabHeight(false)) updateItems(); 580 redraw(); 581 } else { 582 updateItems(); 583 redrawTabs(); 584 } 585 } 586 void destroyItem (CTabItem item) { 587 if (inDispose) return; 588 int index = indexOf(item); 589 if (index == -1) return; 590 591 if (items.length == 1) { 592 items = new CTabItem[0]; 593 priority = new int[0]; 594 firstIndex = -1; 595 selectedIndex = -1; 596 597 Control control = item.getControl(); 598 if (control != null && !control.isDisposed()) { 599 control.setVisible(false); 600 } 601 setToolTipText(null); 602 setButtonBounds(); 603 redraw(); 604 return; 605 } 606 607 CTabItem[] newItems = new CTabItem [items.length - 1]; 608 System.arraycopy(items, 0, newItems, 0, index); 609 System.arraycopy(items, index + 1, newItems, index, items.length - index - 1); 610 items = newItems; 611 612 int[] newPriority = new int[priority.length - 1]; 613 int next = 0; 614 for (int i = 0; i < priority.length; i++) { 615 if (priority [i] == index) continue; 616 newPriority[next++] = priority[i] > index ? priority[i] - 1 : priority [i]; 617 } 618 priority = newPriority; 619 620 if (selectedIndex == index) { 622 Control control = item.getControl(); 623 selectedIndex = -1; 624 int nextSelection = mru ? priority[0] : Math.max(0, index - 1); 625 setSelection(nextSelection, true); 626 if (control != null && !control.isDisposed()) { 627 control.setVisible(false); 628 } 629 } else if (selectedIndex > index) { 630 selectedIndex --; 631 } 632 633 updateItems(); 634 redrawTabs(); 635 } 636 void drawBackground(GC gc, int[] shape, boolean selected) { 637 Color defaultBackground = selected ? selectionBackground : getBackground(); 638 Image image = selected ? selectionBgImage : bgImage; 639 Color[] colors = selected ? selectionGradientColors : gradientColors; 640 int[] percents = selected ? selectionGradientPercents : gradientPercents; 641 boolean vertical = selected ? selectionGradientVertical : gradientVertical; 642 Point size = getSize(); 643 int width = size.x; 644 int height = tabHeight + highlight_header; 645 int x = 0; 646 if (borderLeft > 0) { 647 x += 1; width -= 2; 648 } 649 int y = onBottom ? size.y - borderBottom - height : borderTop; 650 drawBackground(gc, shape, x, y, width, height, defaultBackground, image, colors, percents, vertical); 651 } 652 void drawBackground(GC gc, int[] shape, int x, int y, int width, int height, Color defaultBackground, Image image, Color[] colors, int[] percents, boolean vertical) { 653 Region clipping = new Region(); 654 gc.getClipping(clipping); 655 Region region = new Region(); 656 region.add(shape); 657 region.intersect(clipping); 658 gc.setClipping(region); 659 660 if (image != null) { 661 gc.setBackground(defaultBackground); 663 gc.fillRectangle(x, y, width, height); 664 Rectangle imageRect = image.getBounds(); 665 gc.drawImage(image, imageRect.x, imageRect.y, imageRect.width, imageRect.height, x, y, width, height); 666 } else if (colors != null) { 667 if (colors.length == 1) { 669 Color background = colors[0] != null ? colors[0] : defaultBackground; 670 gc.setBackground(background); 671 gc.fillRectangle(x, y, width, height); 672 } else { 673 if (vertical) { 674 if (onBottom) { 675 int pos = 0; 676 if (percents[percents.length - 1] < 100) { 677 pos = percents[percents.length - 1] * height / 100; 678 gc.setBackground(defaultBackground); 679 gc.fillRectangle(x, y, width, pos); 680 } 681 Color lastColor = colors[colors.length-1]; 682 if (lastColor == null) lastColor = defaultBackground; 683 for (int i = percents.length-1; i >= 0; i--) { 684 gc.setForeground(lastColor); 685 lastColor = colors[i]; 686 if (lastColor == null) lastColor = defaultBackground; 687 gc.setBackground(lastColor); 688 int gradientHeight = percents[i] * height / 100; 689 gc.fillGradientRectangle(x, y+pos, width, gradientHeight, true); 690 pos += gradientHeight; 691 } 692 } else { 693 Color lastColor = colors[0]; 694 if (lastColor == null) lastColor = defaultBackground; 695 int pos = 0; 696 for (int i = 0; i < percents.length; i++) { 697 gc.setForeground(lastColor); 698 lastColor = colors[i + 1]; 699 if (lastColor == null) lastColor = defaultBackground; 700 gc.setBackground(lastColor); 701 int gradientHeight = percents[i] * height / 100; 702 gc.fillGradientRectangle(x, y+pos, width, gradientHeight, true); 703 pos += gradientHeight; 704 } 705 if (pos < height) { 706 gc.setBackground(defaultBackground); 707 gc.fillRectangle(x, pos, width, height-pos+1); 708 } 709 } 710 } else { y = 0; 712 height = getSize().y; 713 Color lastColor = colors[0]; 714 if (lastColor == null) lastColor = defaultBackground; 715 int pos = 0; 716 for (int i = 0; i < percents.length; ++i) { 717 gc.setForeground(lastColor); 718 lastColor = colors[i + 1]; 719 if (lastColor == null) lastColor = defaultBackground; 720 gc.setBackground(lastColor); 721 int gradientWidth = (percents[i] * width / 100) - pos; 722 gc.fillGradientRectangle(x+pos, y, gradientWidth, height, false); 723 pos += gradientWidth; 724 } 725 if (pos < width) { 726 gc.setBackground(defaultBackground); 727 gc.fillRectangle(x+pos, y, width-pos, height); 728 } 729 } 730 } 731 } else { 732 if ((getStyle() & SWT.NO_BACKGROUND) != 0 || !defaultBackground.equals(getBackground())) { 734 gc.setBackground(defaultBackground); 735 gc.fillRectangle(x, y, width, height); 736 } 737 } 738 gc.setClipping(clipping); 739 clipping.dispose(); 740 region.dispose(); 741 } 742 void drawBody(Event event) { 743 GC gc = event.gc; 744 Point size = getSize(); 745 746 if (!minimized){ 748 int width = size.x - borderLeft - borderRight - 2*highlight_margin; 749 int height = size.y - borderTop - borderBottom - tabHeight - highlight_header - highlight_margin; 750 if (highlight_margin > 0) { 752 int[] shape = null; 753 if (onBottom) { 754 int x1 = borderLeft; 755 int y1 = borderTop; 756 int x2 = size.x - borderRight; 757 int y2 = size.y - borderBottom - tabHeight - highlight_header; 758 shape = new int[] {x1,y1, x2,y1, x2,y2, x2-highlight_margin,y2, 759 x2-highlight_margin, y1+highlight_margin, x1+highlight_margin,y1+highlight_margin, 760 x1+highlight_margin,y2, x1,y2}; 761 } else { 762 int x1 = borderLeft; 763 int y1 = borderTop + tabHeight + highlight_header; 764 int x2 = size.x - borderRight; 765 int y2 = size.y - borderBottom; 766 shape = new int[] {x1,y1, x1+highlight_margin,y1, x1+highlight_margin,y2-highlight_margin, 767 x2-highlight_margin,y2-highlight_margin, x2-highlight_margin,y1, 768 x2,y1, x2,y2, x1,y2}; 769 } 770 if (selectedIndex != -1 && selectionGradientColors != null && selectionGradientColors.length > 1 && !selectionGradientVertical) { 772 drawBackground(gc, shape, true); 773 } else if (selectedIndex == -1 && gradientColors != null && gradientColors.length > 1 && !gradientVertical) { 774 drawBackground(gc, shape, false); 775 } else { 776 gc.setBackground(selectedIndex == -1 ? getBackground() : selectionBackground); 777 gc.fillPolygon(shape); 778 } 779 } 780 if ((getStyle() & SWT.NO_BACKGROUND) != 0) { 782 gc.setBackground(getBackground()); 783 gc.fillRectangle(xClient - marginWidth, yClient - marginHeight, width, height); 784 } 785 } else { 786 if ((getStyle() & SWT.NO_BACKGROUND) != 0) { 787 int height = borderTop + tabHeight + highlight_header + borderBottom; 788 if (size.y > height) { 789 gc.setBackground(getParent().getBackground()); 790 gc.fillRectangle(0, height, size.x, size.y - height); 791 } 792 } 793 } 794 795 if (borderLeft > 0) { 797 gc.setForeground(borderColor); 798 int x1 = borderLeft - 1; 799 int x2 = size.x - borderRight; 800 int y1 = onBottom ? borderTop - 1 : borderTop + tabHeight; 801 int y2 = onBottom ? size.y - tabHeight - borderBottom - 1 : size.y - borderBottom; 802 gc.drawLine(x1, y1, x1, y2); gc.drawLine(x2, y1, x2, y2); if (onBottom) { 805 gc.drawLine(x1, y1, x2, y1); } else { 807 gc.drawLine(x1, y2, x2, y2); } 809 } 810 } 811 812 void drawChevron(GC gc) { 813 if (chevronRect.width == 0 || chevronRect.height == 0) return; 814 Display display = getDisplay(); 816 Point dpi = display.getDPI(); 817 int fontHeight = 72 * 10 / dpi.y; 818 FontData fd = getFont().getFontData()[0]; 819 fd.setHeight(fontHeight); 820 Font f = new Font(display, fd); 821 int fHeight = f.getFontData()[0].getHeight() * dpi.y / 72; 822 int indent = Math.max(2, (chevronRect.height - fHeight - 4) /2); 823 int x = chevronRect.x + 2; 824 int y = chevronRect.y + indent; 825 int count; 826 if (single) { 827 count = selectedIndex == -1 ? items.length : items.length - 1; 828 } else { 829 int showCount = 0; 830 while (showCount < priority.length && items[priority[showCount]].showing) { 831 showCount++; 832 } 833 count = items.length - showCount; 834 } 835 String chevronString = count > 99 ? "99+" : String.valueOf(count); switch (chevronImageState) { 837 case NORMAL: { 838 Color chevronBorder = single ? getSelectionForeground() : getForeground(); 839 gc.setForeground(chevronBorder); 840 gc.setFont(f); 841 gc.drawLine(x,y, x+2,y+2); 842 gc.drawLine(x+2,y+2, x,y+4); 843 gc.drawLine(x+1,y, x+3,y+2); 844 gc.drawLine(x+3,y+2, x+1,y+4); 845 gc.drawLine(x+4,y, x+6,y+2); 846 gc.drawLine(x+6,y+2, x+5,y+4); 847 gc.drawLine(x+5,y, x+7,y+2); 848 gc.drawLine(x+7,y+2, x+4,y+4); 849 gc.drawString(chevronString, x+7, y+3, true); 850 break; 851 } 852 case HOT: { 853 gc.setForeground(display.getSystemColor(BUTTON_BORDER)); 854 gc.setBackground(display.getSystemColor(BUTTON_FILL)); 855 gc.setFont(f); 856 gc.fillRoundRectangle(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, 6, 6); 857 gc.drawRoundRectangle(chevronRect.x, chevronRect.y, chevronRect.width - 1, chevronRect.height - 1, 6, 6); 858 gc.drawLine(x,y, x+2,y+2); 859 gc.drawLine(x+2,y+2, x,y+4); 860 gc.drawLine(x+1,y, x+3,y+2); 861 gc.drawLine(x+3,y+2, x+1,y+4); 862 gc.drawLine(x+4,y, x+6,y+2); 863 gc.drawLine(x+6,y+2, x+5,y+4); 864 gc.drawLine(x+5,y, x+7,y+2); 865 gc.drawLine(x+7,y+2, x+4,y+4); 866 gc.drawString(chevronString, x+7, y+3, true); 867 break; 868 } 869 case SELECTED: { 870 gc.setForeground(display.getSystemColor(BUTTON_BORDER)); 871 gc.setBackground(display.getSystemColor(BUTTON_FILL)); 872 gc.setFont(f); 873 gc.fillRoundRectangle(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, 6, 6); 874 gc.drawRoundRectangle(chevronRect.x, chevronRect.y, chevronRect.width - 1, chevronRect.height - 1, 6, 6); 875 gc.drawLine(x+1,y+1, x+3,y+3); 876 gc.drawLine(x+3,y+3, x+1,y+5); 877 gc.drawLine(x+2,y+1, x+4,y+3); 878 gc.drawLine(x+4,y+3, x+2,y+5); 879 gc.drawLine(x+5,y+1, x+7,y+3); 880 gc.drawLine(x+7,y+3, x+6,y+5); 881 gc.drawLine(x+6,y+1, x+8,y+3); 882 gc.drawLine(x+8,y+3, x+5,y+5); 883 gc.drawString(chevronString, x+8, y+4, true); 884 break; 885 } 886 } 887 f.dispose(); 888 } 889 void drawMaximize(GC gc) { 890 if (maxRect.width == 0 || maxRect.height == 0) return; 891 Display display = getDisplay(); 892 int x = maxRect.x + (CTabFolder.BUTTON_SIZE - 10)/2; 894 int y = maxRect.y + 3; 895 896 gc.setForeground(display.getSystemColor(BUTTON_BORDER)); 897 gc.setBackground(display.getSystemColor(BUTTON_FILL)); 898 899 switch (maxImageState) { 900 case NORMAL: { 901 if (!maximized) { 902 gc.fillRectangle(x, y, 9, 9); 903 gc.drawRectangle(x, y, 9, 9); 904 gc.drawLine(x+1, y+2, x+8, y+2); 905 } else { 906 gc.fillRectangle(x, y+3, 5, 4); 907 gc.fillRectangle(x+2, y, 5, 4); 908 gc.drawRectangle(x, y+3, 5, 4); 909 gc.drawRectangle(x+2, y, 5, 4); 910 gc.drawLine(x+3, y+1, x+6, y+1); 911 gc.drawLine(x+1, y+4, x+4, y+4); 912 } 913 break; 914 } 915 case HOT: { 916 gc.fillRoundRectangle(maxRect.x, maxRect.y, maxRect.width, maxRect.height, 6, 6); 917 gc.drawRoundRectangle(maxRect.x, maxRect.y, maxRect.width - 1, maxRect.height - 1, 6, 6); 918 if (!maximized) { 919 gc.fillRectangle(x, y, 9, 9); 920 gc.drawRectangle(x, y, 9, 9); 921 gc.drawLine(x+1, y+2, x+8, y+2); 922 } else { 923 gc.fillRectangle(x, y+3, 5, 4); 924 gc.fillRectangle(x+2, y, 5, 4); 925 gc.drawRectangle(x, y+3, 5, 4); 926 gc.drawRectangle(x+2, y, 5, 4); 927 gc.drawLine(x+3, y+1, x+6, y+1); 928 gc.drawLine(x+1, y+4, x+4, y+4); 929 } 930 break; 931 } 932 case SELECTED: { 933 gc.fillRoundRectangle(maxRect.x, maxRect.y, maxRect.width, maxRect.height, 6, 6); 934 gc.drawRoundRectangle(maxRect.x, maxRect.y, maxRect.width - 1, maxRect.height - 1, 6, 6); 935 if (!maximized) { 936 gc.fillRectangle(x+1, y+1, 9, 9); 937 gc.drawRectangle(x+1, y+1, 9, 9); 938 gc.drawLine(x+2, y+3, x+9, y+3); 939 } else { 940 gc.fillRectangle(x+1, y+4, 5, 4); 941 gc.fillRectangle(x+3, y+1, 5, 4); 942 gc.drawRectangle(x+1, y+4, 5, 4); 943 gc.drawRectangle(x+3, y+1, 5, 4); 944 gc.drawLine(x+4, y+2, x+7, y+2); 945 gc.drawLine(x+2, y+5, x+5, y+5); 946 } 947 break; 948 } 949 } 950 } 951 void drawMinimize(GC gc) { 952 if (minRect.width == 0 || minRect.height == 0) return; 953 Display display = getDisplay(); 954 int x = minRect.x + (BUTTON_SIZE - 10)/2; 956 int y = minRect.y + 3; 957 958 gc.setForeground(display.getSystemColor(BUTTON_BORDER)); 959 gc.setBackground(display.getSystemColor(BUTTON_FILL)); 960 961 switch (minImageState) { 962 case NORMAL: { 963 if (!minimized) { 964 gc.fillRectangle(x, y, 9, 3); 965 gc.drawRectangle(x, y, 9, 3); 966 } else { 967 gc.fillRectangle(x, y+3, 5, 4); 968 gc.fillRectangle(x+2, y, 5, 4); 969 gc.drawRectangle(x, y+3, 5, 4); 970 gc.drawRectangle(x+2, y, 5, 4); 971 gc.drawLine(x+3, y+1, x+6, y+1); 972 gc.drawLine(x+1, y+4, x+4, y+4); 973 } 974 break; 975 } 976 case HOT: { 977 gc.fillRoundRectangle(minRect.x, minRect.y, minRect.width, minRect.height, 6, 6); 978 gc.drawRoundRectangle(minRect.x, minRect.y, minRect.width - 1, minRect.height - 1, 6, 6); 979 if (!minimized) { 980 gc.fillRectangle(x, y, 9, 3); 981 gc.drawRectangle(x, y, 9, 3); 982 } else { 983 gc.fillRectangle(x, y+3, 5, 4); 984 gc.fillRectangle(x+2, y, 5, 4); 985 gc.drawRectangle(x, y+3, 5, 4); 986 gc.drawRectangle(x+2, y, 5, 4); 987 gc.drawLine(x+3, y+1, x+6, y+1); 988 gc.drawLine(x+1, y+4, x+4, y+4); 989 } 990 break; 991 } 992 case SELECTED: { 993 gc.fillRoundRectangle(minRect.x, minRect.y, minRect.width, minRect.height, 6, 6); 994 gc.drawRoundRectangle(minRect.x, minRect.y, minRect.width - 1, minRect.height - 1, 6, 6); 995 if (!minimized) { 996 gc.fillRectangle(x+1, y+1, 9, 3); 997 gc.drawRectangle(x+1, y+1, 9, 3); 998 } else { 999 gc.fillRectangle(x+1, y+4, 5, 4); 1000 gc.fillRectangle(x+3, y+1, 5, 4); 1001 gc.drawRectangle(x+1, y+4, 5, 4); 1002 gc.drawRectangle(x+3, y+1, 5, 4); 1003 gc.drawLine(x+4, y+2, x+7, y+2); 1004 gc.drawLine(x+2, y+5, x+5, y+5); 1005 } 1006 break; 1007 } 1008 } 1009} 1010void drawTabArea(Event event) { 1011 GC gc = event.gc; 1012 Point size = getSize(); 1013 int[] shape = null; 1014 1015 if (tabHeight == 0) { 1016 int style = getStyle(); 1017 if ((style & SWT.FLAT) != 0 && (style & SWT.BORDER) == 0) return; 1018 int x1 = borderLeft - 1; 1019 int x2 = size.x - borderRight; 1020 int y1 = onBottom ? size.y - borderBottom - highlight_header - 1 : borderTop + highlight_header; 1021 int y2 = onBottom ? size.y - borderBottom : borderTop; 1022 if (borderLeft > 0 && onBottom) y2 -= 1; 1023 1024 shape = new int[] {x1, y1, x1,y2, x2,y2, x2,y1}; 1025 1026 if (selectedIndex != -1 && selectionGradientColors != null && selectionGradientColors.length > 1 && !selectionGradientVertical) { 1028 drawBackground(gc, shape, true); 1029 } else if (selectedIndex == -1 && gradientColors != null && gradientColors.length > 1 && !gradientVertical) { 1030 drawBackground(gc, shape, false); 1031 } else { 1032 gc.setBackground(selectedIndex == -1 ? getBackground() : selectionBackground); 1033 gc.fillPolygon(shape); 1034 } 1035 1036 if (borderLeft > 0) { 1038 gc.setForeground(borderColor); 1039 gc.drawPolyline(shape); 1040 } 1041 return; 1042 } 1043 1044 int x = Math.max(0, borderLeft - 1); 1045 int y = onBottom ? size.y - borderBottom - tabHeight : borderTop; 1046 int width = size.x - borderLeft - borderRight + 1; 1047 int height = tabHeight - 1; 1048 1049 if (onBottom) { 1051 int[] left, right; 1052 if ((getStyle() & SWT.BORDER) != 0) { 1053 left = simple ? SIMPLE_BOTTOM_LEFT_CORNER : BOTTOM_LEFT_CORNER; 1054 right = simple ? SIMPLE_BOTTOM_RIGHT_CORNER : BOTTOM_RIGHT_CORNER; 1055 } else { 1056 left = simple ? SIMPLE_BOTTOM_LEFT_CORNER_BORDERLESS : BOTTOM_LEFT_CORNER_BORDERLESS; 1057 right = simple ? SIMPLE_BOTTOM_RIGHT_CORNER_BORDERLESS : BOTTOM_RIGHT_CORNER_BORDERLESS; 1058 } 1059 shape = new int[left.length + right.length + 4]; 1060 int index = 0; 1061 shape[index++] = x; 1062 shape[index++] = y-highlight_header; 1063 for (int i = 0; i < left.length/2; i++) { 1064 shape[index++] = x+left[2*i]; 1065 shape[index++] = y+height+left[2*i+1]; 1066 if (borderLeft == 0) shape[index-1] += 1; 1067 } 1068 for (int i = 0; i < right.length/2; i++) { 1069 shape[index++] = x+width+right[2*i]; 1070 shape[index++] = y+height+right[2*i+1]; 1071 if (borderLeft == 0) shape[index-1] += 1; 1072 } 1073 shape[index++] = x+width; 1074 shape[index++] = y-highlight_header; 1075 } else { 1076 int[] left, right; 1077 if ((getStyle() & SWT.BORDER) != 0) { 1078 left = simple ? SIMPLE_TOP_LEFT_CORNER : TOP_LEFT_CORNER; 1079 right = simple ? SIMPLE_TOP_RIGHT_CORNER : TOP_RIGHT_CORNER; 1080 } else { 1081 left = simple ? SIMPLE_TOP_LEFT_CORNER_BORDERLESS : TOP_LEFT_CORNER_BORDERLESS; 1082 right = simple ? SIMPLE_TOP_RIGHT_CORNER_BORDERLESS : TOP_RIGHT_CORNER_BORDERLESS; 1083 } 1084 shape = new int[left.length + right.length + 4]; 1085 int index = 0; 1086 shape[index++] = x; 1087 shape[index++] = y+height+highlight_header + 1; 1088 for (int i = 0; i < left.length/2; i++) { 1089 shape[index++] = x+left[2*i]; 1090 shape[index++] = y+left[2*i+1]; 1091 } 1092 for (int i = 0; i < right.length/2; i++) { 1093 shape[index++] = x+width+right[2*i]; 1094 shape[index++] = y+right[2*i+1]; 1095 } 1096 shape[index++] = x+width; 1097 shape[index++] = y+height+highlight_header + 1; 1098 } 1099 boolean bkSelected = single && selectedIndex != -1; 1101 drawBackground(gc, shape, bkSelected); 1102 Region r = new Region(); 1104 r.add(new Rectangle(x, y, width + 1, height + 1)); 1105 r.subtract(shape); 1106 gc.setBackground(getParent().getBackground()); 1107 fillRegion(gc, r); 1108 r.dispose(); 1109 1110 if (!single) { 1112 for (int i=0; i < items.length; i++) { 1113 if (i != selectedIndex && event.getBounds().intersects(items[i].getBounds())) { 1114 items[i].onPaint(gc, false); 1115 } 1116 } 1117 } 1118 1119 if (selectedIndex != -1) { 1121 CTabItem item = items[selectedIndex]; 1122 item.onPaint(gc, true); 1123 } else { 1124 int x1 = borderLeft; 1126 int y1 = (onBottom) ? size.y - borderBottom - tabHeight - 1 : borderTop + tabHeight; 1127 int x2 = size.x - borderRight; 1128 gc.setForeground(borderColor); 1129 gc.drawLine(x1, y1, x2, y1); 1130 } 1131 1132 drawChevron(gc); 1134 drawMinimize(gc); 1135 drawMaximize(gc); 1136 1137 if (borderLeft > 0) { 1139 RGB outside = getParent().getBackground().getRGB(); 1140 antialias(shape, borderColor.getRGB(), null, outside, gc); 1141 gc.setForeground(borderColor); 1142 gc.drawPolyline(shape); 1143 } 1144} 1145 1157public boolean getBorderVisible() { 1158 checkWidget(); 1159 return borderLeft == 1; 1160} 1161public Rectangle getClientArea() { 1162 checkWidget(); 1163 if (minimized) return new Rectangle(xClient, yClient, 0, 0); 1164 Point size = getSize(); 1165 int width = size.x - borderLeft - borderRight - 2*marginWidth - 2*highlight_margin; 1166 int height = size.y - borderTop - borderBottom - 2*marginHeight - highlight_margin - highlight_header; 1167 height -= tabHeight; 1168 return new Rectangle(xClient, yClient, width, height); 1169} 1170 1184public CTabItem getItem (int index) { 1185 if (index < 0 || index >= items.length) 1187 SWT.error(SWT.ERROR_INVALID_RANGE); 1188 return items [index]; 1189} 1190 1201public CTabItem getItem (Point pt) { 1202 if (items.length == 0) return null; 1204 Point size = getSize(); 1205 if (size.x <= borderLeft + borderRight) return null; 1206 if (showChevron && chevronRect.contains(pt)) return null; 1207 for (int i = 0; i < priority.length; i++) { 1208 CTabItem item = items[priority[i]]; 1209 Rectangle rect = item.getBounds(); 1210 if (rect.contains(pt)) return item; 1211 } 1212 return null; 1213} 1214 1224public int getItemCount(){ 1225 return items.length; 1227} 1228 1238public CTabItem [] getItems() { 1239 CTabItem[] tabItems = new CTabItem [items.length]; 1241 System.arraycopy(items, 0, tabItems, 0, items.length); 1242 return tabItems; 1243} 1244 1249char _findMnemonic (String string) { 1250 if (string == null) return '\0'; 1251 int index = 0; 1252 int length = string.length (); 1253 do { 1254 while (index < length && string.charAt (index) != '&') index++; 1255 if (++index >= length) return '\0'; 1256 if (string.charAt (index) != '&') return Character.toLowerCase (string.charAt (index)); 1257 index++; 1258 } while (index < length); 1259 return '\0'; 1260} 1261String stripMnemonic (String string) { 1262 int index = 0; 1263 int length = string.length (); 1264 do { 1265 while ((index < length) && (string.charAt (index) != '&')) index++; 1266 if (++index >= length) return string; 1267 if (string.charAt (index) != '&') { 1268 return string.substring(0, index-1) + string.substring(index, length); 1269 } 1270 index++; 1271 } while (index < length); 1272 return string; 1273} 1274 1286public boolean getMinimized() { 1287 checkWidget(); 1288 return minimized; 1289} 1290 1303public boolean getMinimizeVisible() { 1304 checkWidget(); 1305 return showMin; 1306} 1307 1315public int getMinimumCharacters() { 1316 checkWidget(); 1317 return minChars; 1318} 1319 1332public boolean getMaximized() { 1333 checkWidget(); 1334 return maximized; 1335} 1336 1349public boolean getMaximizeVisible() { 1350 checkWidget(); 1351 return showMax; 1352} 1353 1382public boolean getMRUVisible() { 1383 checkWidget(); 1384 return mru; 1385} 1386int getRightItemEdge (){ 1387 int x = getSize().x - borderRight - 3; 1388 if (showMin) x -= BUTTON_SIZE; 1389 if (showMax) x -= BUTTON_SIZE; 1390 if (showChevron) x -= 3*BUTTON_SIZE/2; 1391 if (topRight != null && topRightAlignment != SWT.FILL) { 1392 Point rightSize = topRight.computeSize(SWT.DEFAULT, SWT.DEFAULT); 1393 x -= rightSize.x + 3; 1394 } 1395 return Math.max(0, x); 1396} 1397 1407public CTabItem getSelection() { 1408 if (selectedIndex == -1) return null; 1410 return items[selectedIndex]; 1411} 1412 1424public Color getSelectionBackground() { 1425 checkWidget(); 1426 return selectionBackground; 1427} 1428 1440public Color getSelectionForeground() { 1441 checkWidget(); 1442 return selectionForeground; 1443} 1444 1455public int getSelectionIndex() { 1456 return selectedIndex; 1458} 1459 1467public boolean getSimple() { 1468 checkWidget(); 1469 return simple; 1470} 1471 1479public boolean getSingle() { 1480 checkWidget(); 1481 return single; 1482} 1483 1484public int getStyle() { 1485 int style = super.getStyle(); 1486 style &= ~(SWT.TOP | SWT.BOTTOM); 1487 style |= onBottom ? SWT.BOTTOM : SWT.TOP; 1488 style &= ~(SWT.SINGLE | SWT.MULTI); 1489 style |= single ? SWT.SINGLE : SWT.MULTI; 1490 if (borderLeft != 0) style |= SWT.BORDER; 1491 return style; 1492} 1493 1503public int getTabHeight(){ 1504 checkWidget(); 1505 if (fixedTabHeight != SWT.DEFAULT) return fixedTabHeight; 1506 return tabHeight - 1; } 1508 1518public int getTabPosition(){ 1519 checkWidget(); 1520 return onBottom ? SWT.BOTTOM : SWT.TOP; 1521} 1522 1535public Control getTopRight() { 1536 checkWidget(); 1537 return topRight; 1538} 1539 1547public boolean getUnselectedCloseVisible() { 1548 checkWidget(); 1549 return showUnselectedClose; 1550} 1551 1559public boolean getUnselectedImageVisible() { 1560 checkWidget(); 1561 return showUnselectedImage; 1562} 1563 1580public int indexOf(CTabItem item) { 1581 checkWidget(); 1582 if (item == null) { 1583 SWT.error(SWT.ERROR_NULL_ARGUMENT); 1584 } 1585 for (int i = 0; i < items.length; i++) { 1586 if (items[i] == item) return i; 1587 } 1588 return -1; 1589} 1590void initAccessible() { 1591 final Accessible accessible = getAccessible(); 1592 accessible.addAccessibleListener(new AccessibleAdapter() { 1593 public void getName(AccessibleEvent e) { 1594 String name = null; 1595 int childID = e.childID; 1596 if (childID >= 0 && childID < items.length) { 1597 name = stripMnemonic(items[childID].getText()); 1598 } else if (childID == items.length + CHEVRON_CHILD_ID) { 1599 name = SWT.getMessage("SWT_ShowList"); } else if (childID == items.length + MINIMIZE_CHILD_ID) { 1601 name = minimized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Minimize"); } else if (childID == items.length + MAXIMIZE_CHILD_ID) { 1603 name = maximized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Maximize"); } 1605 e.result = name; 1606 } 1607 1608 public void getHelp(AccessibleEvent e) { 1609 String help = null; 1610 int childID = e.childID; 1611 if (childID == ACC.CHILDID_SELF) { 1612 help = getToolTipText(); 1613 } else if (childID >= 0 && childID < items.length) { 1614 help = items[childID].getToolTipText(); 1615 } 1616 e.result = help; 1617 } 1618 1619 public void getKeyboardShortcut(AccessibleEvent e) { 1620 String shortcut = null; 1621 int childID = e.childID; 1622 if (childID >= 0 && childID < items.length) { 1623 String text = items[childID].getText(); 1624 if (text != null) { 1625 char mnemonic = _findMnemonic(text); 1626 if (mnemonic != '\0') { 1627 shortcut = "Alt+"+mnemonic; } 1629 } 1630 } 1631 e.result = shortcut; 1632 } 1633 }); 1634 1635 accessible.addAccessibleControlListener(new AccessibleControlAdapter() { 1636 public void getChildAtPoint(AccessibleControlEvent e) { 1637 Point testPoint = toControl(e.x, e.y); 1638 int childID = ACC.CHILDID_NONE; 1639 for (int i = 0; i < items.length; i++) { 1640 if (items[i].getBounds().contains(testPoint)) { 1641 childID = i; 1642 break; 1643 } 1644 } 1645 if (childID == ACC.CHILDID_NONE) { 1646 if (showChevron && chevronRect.contains(testPoint)) { 1647 childID = items.length + CHEVRON_CHILD_ID; 1648 } else if (showMin && minRect.contains(testPoint)) { 1649 childID = items.length + MINIMIZE_CHILD_ID; 1650 } else if (showMax && maxRect.contains(testPoint)) { 1651 childID = items.length + MAXIMIZE_CHILD_ID; 1652 } else { 1653 Rectangle location = getBounds(); 1654 location.height = location.height - getClientArea().height; 1655 if (location.contains(testPoint)) { 1656 childID = ACC.CHILDID_SELF; 1657 } 1658 } 1659 } 1660 e.childID = childID; 1661 } 1662 1663 public void getLocation(AccessibleControlEvent e) { 1664 Rectangle location = null; 1665 int childID = e.childID; 1666 if (childID == ACC.CHILDID_SELF) { 1667 location = getBounds(); 1668 } else if (childID >= 0 && childID < items.length) { 1669 location = items[childID].getBounds(); 1670 } else if (showChevron && childID == items.length + CHEVRON_CHILD_ID) { 1671 location = chevronRect; 1672 } else if (showMin && childID == items.length + MINIMIZE_CHILD_ID) { 1673 location = minRect; 1674 } else if (showMax && childID == items.length + MAXIMIZE_CHILD_ID) { 1675 location = maxRect; 1676 } 1677 if (location != null) { 1678 Point pt = toDisplay(location.x, location.y); 1679 e.x = pt.x; 1680 e.y = pt.y; 1681 e.width = location.width; 1682 e.height = location.height; 1683 } 1684 } 1685 1686 public void getChildCount(AccessibleControlEvent e) { 1687 e.detail = items.length + EXTRA_CHILD_ID_COUNT; 1688 } 1689 1690 public void getDefaultAction(AccessibleControlEvent e) { 1691 String action = null; 1692 int childID = e.childID; 1693 if (childID >= 0 && childID < items.length) { 1694 action = SWT.getMessage ("SWT_Switch"); } 1696 if (childID >= items.length && childID < items.length + EXTRA_CHILD_ID_COUNT) { 1697 action = SWT.getMessage ("SWT_Press"); } 1699 e.result = action; 1700 } 1701 1702 public void getFocus(AccessibleControlEvent e) { 1703 int childID = ACC.CHILDID_NONE; 1704 if (isFocusControl()) { 1705 if (selectedIndex == -1) { 1706 childID = ACC.CHILDID_SELF; 1707 } else { 1708 childID = selectedIndex; 1709 } 1710 } 1711 e.childID = childID; 1712 } 1713 1714 public void getRole(AccessibleControlEvent e) { 1715 int role = 0; 1716 int childID = e.childID; 1717 if (childID == ACC.CHILDID_SELF) { 1718 role = ACC.ROLE_TABFOLDER; 1719 } else if (childID >= 0 && childID < items.length) { 1720 role = ACC.ROLE_TABITEM; 1721 } else if (childID >= items.length && childID < items.length + EXTRA_CHILD_ID_COUNT) { 1722 role = ACC.ROLE_PUSHBUTTON; 1723 } 1724 e.detail = role; 1725 } 1726 1727 public void getSelection(AccessibleControlEvent e) { 1728 e.childID = (selectedIndex == -1) ? ACC.CHILDID_NONE : selectedIndex; 1729 } 1730 1731 public void getState(AccessibleControlEvent e) { 1732 int state = 0; 1733 int childID = e.childID; 1734 if (childID == ACC.CHILDID_SELF) { 1735 state = ACC.STATE_NORMAL; 1736 } else if (childID >= 0 && childID < items.length) { 1737 state = ACC.STATE_SELECTABLE; 1738 if (isFocusControl()) { 1739 state |= ACC.STATE_FOCUSABLE; 1740 } 1741 if (selectedIndex == childID) { 1742 state |= ACC.STATE_SELECTED; 1743 if (isFocusControl()) { 1744 state |= ACC.STATE_FOCUSED; 1745 } 1746 } 1747 } else if (childID == items.length + CHEVRON_CHILD_ID) { 1748 state = showChevron ? ACC.STATE_NORMAL : ACC.STATE_INVISIBLE; 1749 } else if (childID == items.length + MINIMIZE_CHILD_ID) { 1750 state = showMin ? ACC.STATE_NORMAL : ACC.STATE_INVISIBLE; 1751 } else if (childID == items.length + MAXIMIZE_CHILD_ID) { 1752 state = showMax ? ACC.STATE_NORMAL : ACC.STATE_INVISIBLE; 1753 } 1754 e.detail = state; 1755 } 1756 1757 public void getChildren(AccessibleControlEvent e) { 1758 int childIdCount = items.length + EXTRA_CHILD_ID_COUNT; 1759 Object [] children = new Object [childIdCount]; 1760 for (int i = 0; i < childIdCount; i++) { 1761 children[i] = new Integer (i); 1762 } 1763 e.children = children; 1764 } 1765 }); 1766 1767 addListener(SWT.Selection, new Listener() { 1768 public void handleEvent(Event event) { 1769 if (isFocusControl()) { 1770 if (selectedIndex == -1) { 1771 accessible.setFocus(ACC.CHILDID_SELF); 1772 } else { 1773 accessible.setFocus(selectedIndex); 1774 } 1775 } 1776 } 1777 }); 1778 1779 addListener(SWT.FocusIn, new Listener() { 1780 public void handleEvent(Event event) { 1781 if (selectedIndex == -1) { 1782 accessible.setFocus(ACC.CHILDID_SELF); 1783 } else { 1784 accessible.setFocus(selectedIndex); 1785 } 1786 } 1787 }); 1788} 1789void onKeyDown (Event event) { 1790 switch (event.keyCode) { 1791 case SWT.ARROW_LEFT: 1792 case SWT.ARROW_RIGHT: 1793 int count = items.length; 1794 if (count == 0) return; 1795 if (selectedIndex == -1) return; 1796 int leadKey = (getStyle() & SWT.RIGHT_TO_LEFT) != 0 ? SWT.ARROW_RIGHT : SWT.ARROW_LEFT; 1797 int offset = event.keyCode == leadKey ? -1 : 1; 1798 int index; 1799 if (!mru) { 1800 index = selectedIndex + offset; 1801 } else { 1802 int[] visible = new int[items.length]; 1803 int idx = 0; 1804 int current = -1; 1805 for (int i = 0; i < items.length; i++) { 1806 if (items[i].showing) { 1807 if (i == selectedIndex) current = idx; 1808 visible [idx++] = i; 1809 } 1810 } 1811 if (current + offset >= 0 && current + offset < idx){ 1812 index = visible [current + offset]; 1813 } else { 1814 if (showChevron) { 1815 CTabFolderEvent e = new CTabFolderEvent(this); 1816 e.widget = this; 1817 e.time = event.time; 1818 e.x = chevronRect.x; 1819 e.y = chevronRect.y; 1820 e.width = chevronRect.width; 1821 e.height = chevronRect.height; 1822 e.doit = true; 1823 for (int i = 0; i < folderListeners.length; i++) { 1824 folderListeners[i].showList(e); 1825 } 1826 if (e.doit && !isDisposed()) { 1827 showList(chevronRect); 1828 } 1829 } 1830 return; 1831 } 1832 } 1833 if (index < 0 || index >= count) return; 1834 setSelection (index, true); 1835 forceFocus(); 1836 } 1837} 1838void onDispose(Event event) { 1839 removeListener(SWT.Dispose, listener); 1840 notifyListeners(SWT.Dispose, event); 1841 event.type = SWT.None; 1842 1848 inDispose = true; 1849 1850 if (showMenu != null && !showMenu.isDisposed()) { 1851 showMenu.dispose(); 1852 showMenu = null; 1853 } 1854 int length = items.length; 1855 for (int i = 0; i < length; i++) { 1856 if (items[i] != null) { 1857 items[i].dispose(); 1858 } 1859 } 1860 1861 selectionGradientColors = null; 1862 selectionGradientPercents = null; 1863 selectionBgImage = null; 1864 1865 selectionBackground = null; 1866 selectionForeground = null; 1867 disposeSelectionHighlightGradientColors(); 1868} 1869void onDragDetect(Event event) { 1870 boolean consume = false; 1871 if (chevronRect.contains(event.x, event.y) || 1872 minRect.contains(event.x, event.y) || 1873 maxRect.contains(event.x, event.y)){ 1874 consume = true; 1875 } else { 1876 for (int i = 0; i < items.length; i++) { 1877 if (items[i].closeRect.contains(event.x, event.y)) { 1878 consume = true; 1879 break; 1880 } 1881 } 1882 } 1883 if (consume) { 1884 event.type = SWT.None; 1885 } 1886} 1887void onFocus(Event event) { 1888 checkWidget(); 1889 if (selectedIndex >= 0) { 1890 redraw(); 1891 } else { 1892 setSelection(0, true); 1893 } 1894} 1895boolean onMnemonic (Event event) { 1896 char key = event.character; 1897 for (int i = 0; i < items.length; i++) { 1898 if (items[i] != null) { 1899 char mnemonic = _findMnemonic (items[i].getText ()); 1900 if (mnemonic != '\0') { 1901 if (Character.toLowerCase (key) == mnemonic) { 1902 setSelection(i, true); 1903 return true; 1904 } 1905 } 1906 } 1907 } 1908 return false; 1909} 1910void onMouseDoubleClick(Event event) { 1911 if (event.button != 1 || 1912 (event.stateMask & SWT.BUTTON2) != 0 || 1913 (event.stateMask & SWT.BUTTON3) != 0) return; 1914 Event e = new Event(); 1915 e.item = getItem(new Point(event.x, event.y)); 1916 if (e.item != null) { 1917 notifyListeners(SWT.DefaultSelection, e); 1918 } 1919} 1920void onMouse(Event event) { 1921 int x = event.x, y = event.y; 1922 switch (event.type) { 1923 case SWT.MouseEnter: { 1924 setToolTipText(null); 1925 break; 1926 } 1927 case SWT.MouseExit: { 1928 if (minImageState != NORMAL) { 1929 minImageState = NORMAL; 1930 redraw(minRect.x, minRect.y, minRect.width, minRect.height, false); 1931 } 1932 if (maxImageState != NORMAL) { 1933 maxImageState = NORMAL; 1934 redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false); 1935 } 1936 if (chevronImageState != NORMAL) { 1937 chevronImageState = NORMAL; 1938 redraw(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, false); 1939 } 1940 for (int i=0; i<items.length; i++) { 1941 CTabItem item = items[i]; 1942 if (i != selectedIndex && item.closeImageState != NONE) { 1943 item.closeImageState = NONE; 1944 redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false); 1945 } 1946 if (i == selectedIndex && item.closeImageState != NORMAL) { 1947 item.closeImageState = NORMAL; 1948 redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false); 1949 } 1950 } 1951 break; 1952 } 1953 case SWT.MouseDown: { 1954 if (minRect.contains(x, y)) { 1955 if (event.button != 1) return; 1956 minImageState = SELECTED; 1957 redraw(minRect.x, minRect.y, minRect.width, minRect.height, false); 1958 update(); 1959 return; 1960 } 1961 if (maxRect.contains(x, y)) { 1962 if (event.button != 1) return; 1963 maxImageState = SELECTED; 1964 redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false); 1965 update(); 1966 return; 1967 } 1968 if (chevronRect.contains(x, y)) { 1969 if (event.button != 1) return; 1970 if (chevronImageState != HOT) { 1971 chevronImageState = HOT; 1972 } else { 1973 chevronImageState = SELECTED; 1974 } 1975 redraw(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, false); 1976 update(); 1977 return; 1978 } 1979 CTabItem item = null; 1980 if (single) { 1981 if (selectedIndex != -1) { 1982 Rectangle bounds = items[selectedIndex].getBounds(); 1983 if (bounds.contains(x, y)){ 1984 item = items[selectedIndex]; 1985 } 1986 } 1987 } else { 1988 for (int i=0; i<items.length; i++) { 1989 Rectangle bounds = items[i].getBounds(); 1990 if (bounds.contains(x, y)){ 1991 item = items[i]; 1992 } 1993 } 1994 } 1995 if (item != null) { 1996 if (item.closeRect.contains(x,y)){ 1997 if (event.button != 1) return; 1998 item.closeImageState = SELECTED; 1999 redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false); 2000 update(); 2001 return; 2002 } 2003 int index = indexOf(item); 2004 if (item.showing){ 2005 setSelection(index, true); 2006 } 2007 return; 2008 } 2009 break; 2010 } 2011 case SWT.MouseMove: { 2012 _setToolTipText(event.x, event.y); 2013 boolean close = false, minimize = false, maximize = false, chevron = false; 2014 if (minRect.contains(x, y)) { 2015 minimize = true; 2016 if (minImageState != SELECTED && minImageState != HOT) { 2017 minImageState = HOT; 2018 redraw(minRect.x, minRect.y, minRect.width, minRect.height, false); 2019 } 2020 } 2021 if (maxRect.contains(x, y)) { 2022 maximize = true; 2023 if (maxImageState != SELECTED && maxImageState != HOT) { 2024 maxImageState = HOT; 2025 redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false); 2026 } 2027 } 2028 if (chevronRect.contains(x, y)) { 2029 chevron = true; 2030 if (chevronImageState != SELECTED && chevronImageState != HOT) { 2031 chevronImageState = HOT; 2032 redraw(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, false); 2033 } 2034 } 2035 if (minImageState != NORMAL && !minimize) { 2036 minImageState = NORMAL; 2037 redraw(minRect.x, minRect.y, minRect.width, minRect.height, false); 2038 } 2039 if (maxImageState != NORMAL && !maximize) { 2040 maxImageState = NORMAL; 2041 redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false); 2042 } 2043 if (chevronImageState != NORMAL && !chevron) { 2044 chevronImageState = NORMAL; 2045 redraw(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, false); 2046 } 2047 for (int i=0; i<items.length; i++) { 2048 CTabItem item = items[i]; 2049 close = false; 2050 if (item.getBounds().contains(x, y)) { 2051 close = true; 2052 if (item.closeRect.contains(x, y)) { 2053 if (item.closeImageState != SELECTED && item.closeImageState != HOT) { 2054 item.closeImageState = HOT; 2055 redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false); 2056 } 2057 } else { 2058 if (item.closeImageState != NORMAL) { 2059 item.closeImageState = NORMAL; 2060 redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false); 2061 } 2062 } 2063 } 2064 if (i != selectedIndex && item.closeImageState != NONE && !close) { 2065 item.closeImageState = NONE; 2066 redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false); 2067 } 2068 if (i == selectedIndex && item.closeImageState != NORMAL && !close) { 2069 item.closeImageState = NORMAL; 2070 redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false); 2071 } 2072 } 2073 break; 2074 } 2075 case SWT.MouseUp: { 2076 if (event.button != 1) return; 2077 if (chevronRect.contains(x, y)) { 2078 boolean selected = chevronImageState == SELECTED; 2079 if (!selected) return; 2080 CTabFolderEvent e = new CTabFolderEvent(this); 2081 e.widget = this; 2082 e.time = event.time; 2083 e.x = chevronRect.x; 2084 e.y = chevronRect.y; 2085 e.width = chevronRect.width; 2086 e.height = chevronRect.height; 2087 e.doit = true; 2088 for (int i = 0; i < folderListeners.length; i++) { 2089 folderListeners[i].showList(e); 2090 } 2091 if (e.doit && !isDisposed()) { 2092 showList(chevronRect); 2093 } 2094 return; 2095 } 2096 if (minRect.contains(x, y)) { 2097 boolean selected = minImageState == SELECTED; 2098 minImageState = HOT; 2099 redraw(minRect.x, minRect.y, minRect.width, minRect.height, false); 2100 if (!selected) return; 2101 CTabFolderEvent e = new CTabFolderEvent(this); 2102 e.widget = this; 2103 e.time = event.time; 2104 for (int i = 0; i < folderListeners.length; i++) { 2105 if (minimized) { 2106 folderListeners[i].restore(e); 2107 } else { 2108 folderListeners[i].minimize(e); 2109 } 2110 } 2111 return; 2112 } 2113 if (maxRect.contains(x, y)) { 2114 boolean selected = maxImageState == SELECTED; 2115 maxImageState = HOT; 2116 redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false); 2117 if (!selected) return; 2118 CTabFolderEvent e = new CTabFolderEvent(this); 2119 e.widget = this; 2120 e.time = event.time; 2121 for (int i = 0; i < folderListeners.length; i++) { 2122 if (maximized) { 2123 folderListeners[i].restore(e); 2124 } else { 2125 folderListeners[i].maximize(e); 2126 } 2127 } 2128 return; 2129 } 2130 CTabItem item = null; 2131 if (single) { 2132 if (selectedIndex != -1) { 2133 Rectangle bounds = items[selectedIndex].getBounds(); 2134 if (bounds.contains(x, y)){ 2135 item = items[selectedIndex]; 2136 } 2137 } 2138 } else { 2139 for (int i=0; i<items.length; i++) { 2140 Rectangle bounds = items[i].getBounds(); 2141 if (bounds.contains(x, y)){ 2142 item = items[i]; 2143 } 2144 } 2145 } 2146 if (item != null) { 2147 if (item.closeRect.contains(x,y)) { 2148 boolean selected = item.closeImageState == SELECTED; 2149 item.closeImageState = HOT; 2150 redraw(item.closeRect.x, item.closeRect.y, item.closeRect.width, item.closeRect.height, false); 2151 if (!selected) return; 2152 CTabFolderEvent e = new CTabFolderEvent(this); 2153 e.widget = this; 2154 e.time = event.time; 2155 e.item = item; 2156 e.doit = true; 2157 for (int j = 0; j < folderListeners.length; j++) { 2158 CTabFolder2Listener listener = folderListeners[j]; 2159 listener.close(e); 2160 } 2161 for (int j = 0; j < tabListeners.length; j++) { 2162 CTabFolderListener listener = tabListeners[j]; 2163 listener.itemClosed(e); 2164 } 2165 if (e.doit) { 2166 item.dispose(); 2167 Display display = getDisplay(); 2168 Point pt = display.getCursorLocation(); 2169 pt = display.map(null, this, pt.x, pt.y); 2170 CTabItem nextItem = getItem(pt); 2171 if (nextItem != null) { 2172 if (nextItem.closeRect.contains(pt)) { 2173 if (nextItem.closeImageState != SELECTED && nextItem.closeImageState != HOT) { 2174 nextItem.closeImageState = HOT; 2175 redraw(nextItem.closeRect.x, nextItem.closeRect.y, nextItem.closeRect.width, nextItem.closeRect.height, false); 2176 } 2177 } else { 2178 if (nextItem.closeImageState != NORMAL) { 2179 nextItem.closeImageState = NORMAL; 2180 redraw(nextItem.closeRect.x, nextItem.closeRect.y, nextItem.closeRect.width, nextItem.closeRect.height, false); 2181 } 2182 } 2183 } 2184 } 2185 return; 2186 } 2187 } 2188 } 2189 } 2190} 2191boolean onPageTraversal(Event event) { 2192 int count = items.length; 2193 if (count == 0) return false; 2194 int index = selectedIndex; 2195 if (index == -1) { 2196 index = 0; 2197 } else { 2198 int offset = (event.detail == SWT.TRAVERSE_PAGE_NEXT) ? 1 : -1; 2199 if (!mru) { 2200 index = (selectedIndex + offset + count) % count; 2201 } else { 2202 int[] visible = new int[items.length]; 2203 int idx = 0; 2204 int current = -1; 2205 for (int i = 0; i < items.length; i++) { 2206 if (items[i].showing) { 2207 if (i == selectedIndex) current = idx; 2208 visible [idx++] = i; 2209 } 2210 } 2211 if (current + offset >= 0 && current + offset < idx){ 2212 index = visible [current + offset]; 2213 } else { 2214 if (showChevron) { 2215 CTabFolderEvent e = new CTabFolderEvent(this); 2216 e.widget = this; 2217 e.time = event.time; 2218 e.x = chevronRect.x; 2219 e.y = chevronRect.y; 2220 e.width = chevronRect.width; 2221 e.height = chevronRect.height; 2222 e.doit = true; 2223 for (int i = 0; i < folderListeners.length; i++) { 2224 folderListeners[i].showList(e); 2225 } 2226 if (e.doit && !isDisposed()) { 2227 showList(chevronRect); 2228 } 2229 } 2230 return true; 2231 } 2232 } 2233 } 2234 setSelection (index, true); 2235 return true; 2236} 2237void onPaint(Event event) { 2238 if (inDispose) return; 2239 Font font = getFont(); 2240 if (oldFont == null || !oldFont.equals(font)) { 2241 oldFont = font; 2243 if (!updateTabHeight(false)) { 2244 updateItems(); 2245 redraw(); 2246 return; 2247 } 2248 } 2249 2250 GC gc = event.gc; 2251 Font gcFont = gc.getFont(); 2252 Color gcBackground = gc.getBackground(); 2253 Color gcForeground = gc.getForeground(); 2254 2255 2262 drawBody(event); 2263 2264 gc.setFont(gcFont); 2265 gc.setForeground(gcForeground); 2266 gc.setBackground(gcBackground); 2267 2268 drawTabArea(event); 2269 2270 gc.setFont(gcFont); 2271 gc.setForeground(gcForeground); 2272 gc.setBackground(gcBackground); 2273} 2274 2275void onResize() { 2276 if (updateItems()) redrawTabs(); 2277 2278 Point size = getSize(); 2279 if (oldSize == null) { 2280 redraw(); 2281 } else { 2282 if (onBottom && size.y != oldSize.y) { 2283 redraw(); 2284 } else { 2285 int x1 = Math.min(size.x, oldSize.x); 2286 if (size.x != oldSize.x) x1 -= borderRight + highlight_margin + 2; 2287 if (!simple) x1 -= 5; int y1 = Math.min(size.y, oldSize.y); 2289 if (size.y != oldSize.y) y1 -= borderBottom + highlight_margin; 2290 int x2 = Math.max(size.x, oldSize.x); 2291 int y2 = Math.max(size.y, oldSize.y); 2292 redraw(0, y1, x2, y2 - y1, false); 2293 redraw(x1, 0, x2 - x1, y2, false); 2294 } 2295 } 2296 oldSize = size; 2297} 2298void onTraverse (Event event) { 2299 switch (event.detail) { 2300 case SWT.TRAVERSE_ESCAPE: 2301 case SWT.TRAVERSE_RETURN: 2302 case SWT.TRAVERSE_TAB_NEXT: 2303 case SWT.TRAVERSE_TAB_PREVIOUS: 2304 Control focusControl = getDisplay().getFocusControl(); 2305 if (focusControl == this) event.doit = true; 2306 break; 2307 case SWT.TRAVERSE_MNEMONIC: 2308 event.doit = onMnemonic(event); 2309 if (event.doit) event.detail = SWT.TRAVERSE_NONE; 2310 break; 2311 case SWT.TRAVERSE_PAGE_NEXT: 2312 case SWT.TRAVERSE_PAGE_PREVIOUS: 2313 event.doit = onPageTraversal(event); 2314 event.detail = SWT.TRAVERSE_NONE; 2315 break; 2316 } 2317} 2318void redrawTabs() { 2319 Point size = getSize(); 2320 if (onBottom) { 2321 redraw(0, size.y - borderBottom - tabHeight - highlight_header - 1, size.x, borderBottom + tabHeight + highlight_header + 1, false); 2322 } else { 2323 redraw(0, 0, size.x, borderTop + tabHeight + highlight_header + 1, false); 2324 } 2325} 2326 2344public void removeCTabFolder2Listener(CTabFolder2Listener listener) { 2345 checkWidget(); 2346 if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 2347 if (folderListeners.length == 0) return; 2348 int index = -1; 2349 for (int i = 0; i < folderListeners.length; i++) { 2350 if (listener == folderListeners[i]){ 2351 index = i; 2352 break; 2353 } 2354 } 2355 if (index == -1) return; 2356 if (folderListeners.length == 1) { 2357 folderListeners = new CTabFolder2Listener[0]; 2358 return; 2359 } 2360 CTabFolder2Listener[] newTabListeners = new CTabFolder2Listener[folderListeners.length - 1]; 2361 System.arraycopy(folderListeners, 0, newTabListeners, 0, index); 2362 System.arraycopy(folderListeners, index + 1, newTabListeners, index, folderListeners.length - index - 1); 2363 folderListeners = newTabListeners; 2364} 2365 2381public void removeCTabFolderListener(CTabFolderListener listener) { 2382 checkWidget(); 2383 if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 2384 if (tabListeners.length == 0) return; 2385 int index = -1; 2386 for (int i = 0; i < tabListeners.length; i++) { 2387 if (listener == tabListeners[i]){ 2388 index = i; 2389 break; 2390 } 2391 } 2392 if (index == -1) return; 2393 if (tabListeners.length == 1) { 2394 tabListeners = new CTabFolderListener[0]; 2395 return; 2396 } 2397 CTabFolderListener[] newTabListeners = new CTabFolderListener[tabListeners.length - 1]; 2398 System.arraycopy(tabListeners, 0, newTabListeners, 0, index); 2399 System.arraycopy(tabListeners, index + 1, newTabListeners, index, tabListeners.length - index - 1); 2400 tabListeners = newTabListeners; 2401} 2402 2419public void removeSelectionListener(SelectionListener listener) { 2420 checkWidget(); 2421 if (listener == null) { 2422 SWT.error(SWT.ERROR_NULL_ARGUMENT); 2423 } 2424 removeListener(SWT.Selection, listener); 2425 removeListener(SWT.DefaultSelection, listener); 2426} 2427public void setBackground (Color color) { 2428 super.setBackground(color); 2429 redraw(); 2430} 2431 2458void setBackground(Color[] colors, int[] percents) { 2459 setBackground(colors, percents, false); 2460} 2461 2490void setBackground(Color[] colors, int[] percents, boolean vertical) { 2491 checkWidget(); 2492 if (colors != null) { 2493 if (percents == null || percents.length != colors.length - 1) { 2494 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 2495 } 2496 for (int i = 0; i < percents.length; i++) { 2497 if (percents[i] < 0 || percents[i] > 100) { 2498 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 2499 } 2500 if (i > 0 && percents[i] < percents[i-1]) { 2501 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 2502 } 2503 } 2504 if (getDisplay().getDepth() < 15) { 2505 colors = new Color[] {colors[colors.length - 1]}; 2507 percents = new int[] {}; 2508 } 2509 } 2510 2511 if (bgImage == null) { 2513 if ((gradientColors != null) && (colors != null) && 2514 (gradientColors.length == colors.length)) { 2515 boolean same = false; 2516 for (int i = 0; i < gradientColors.length; i++) { 2517 if (gradientColors[i] == null) { 2518 same = colors[i] == null; 2519 } else { 2520 same = gradientColors[i].equals(colors[i]); 2521 } 2522 if (!same) break; 2523 } 2524 if (same) { 2525 for (int i = 0; i < gradientPercents.length; i++) { 2526 same = gradientPercents[i] == percents[i]; 2527 if (!same) break; 2528 } 2529 } 2530 if (same && this.gradientVertical == vertical) return; 2531 } 2532 } else { 2533 bgImage = null; 2534 } 2535 if (colors == null) { 2537 gradientColors = null; 2538 gradientPercents = null; 2539 gradientVertical = false; 2540 setBackground((Color)null); 2541 } else { 2542 gradientColors = new Color[colors.length]; 2543 for (int i = 0; i < colors.length; ++i) { 2544 gradientColors[i] = colors[i]; 2545 } 2546 gradientPercents = new int[percents.length]; 2547 for (int i = 0; i < percents.length; ++i) { 2548 gradientPercents[i] = percents[i]; 2549 } 2550 gradientVertical = vertical; 2551 setBackground(gradientColors[gradientColors.length-1]); 2552 } 2553 2554 redraw(); 2556} 2557 2558 2571void setBackground(Image image) { 2572 checkWidget(); 2573 if (image == bgImage) return; 2574 if (image != null) { 2575 gradientColors = null; 2576 gradientPercents = null; 2577 } 2578 bgImage = image; 2579 redraw(); 2580} 2581 2591public void setBorderVisible(boolean show) { 2592 checkWidget(); 2593 if ((borderLeft == 1) == show) return; 2594 borderLeft = borderRight = show ? 1 : 0; 2595 borderTop = onBottom ? borderLeft : 0; 2596 borderBottom = onBottom ? 0 : borderLeft; 2597 Rectangle rectBefore = getClientArea(); 2598 updateItems(); 2599 Rectangle rectAfter = getClientArea(); 2600 if (!rectBefore.equals(rectAfter)) { 2601 notifyListeners(SWT.Resize, new Event()); 2602 } 2603 redraw(); 2604} 2605void setButtonBounds() { 2606 Point size = getSize(); 2607 int oldX, oldY, oldWidth, oldHeight; 2608 oldX = maxRect.x; 2610 oldY = maxRect.y; 2611 oldWidth = maxRect.width; 2612 oldHeight = maxRect.height; 2613 maxRect.x = maxRect.y = maxRect.width = maxRect.height = 0; 2614 if (showMax) { 2615 maxRect.x = size.x - borderRight - BUTTON_SIZE - 3; 2616 if (borderRight > 0) maxRect.x += 1; 2617 maxRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - BUTTON_SIZE)/2: borderTop + (tabHeight - BUTTON_SIZE)/2; 2618 maxRect.width = BUTTON_SIZE; 2619 maxRect.height = BUTTON_SIZE; 2620 } 2621 if (oldX != maxRect.x || oldWidth != maxRect.width || 2622 oldY != maxRect.y || oldHeight != maxRect.height) { 2623 int left = Math.min(oldX, maxRect.x); 2624 int right = Math.max(oldX + oldWidth, maxRect.x + maxRect.width); 2625 int top = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1; 2626 redraw(left, top, right - left, tabHeight, false); 2627 } 2628 2629 oldX = minRect.x; 2631 oldY = minRect.y; 2632 oldWidth = minRect.width; 2633 oldHeight = minRect.height; 2634 minRect.x = minRect.y = minRect.width = minRect.height = 0; 2635 if (showMin) { 2636 minRect.x = size.x - borderRight - maxRect.width - BUTTON_SIZE - 3; 2637 if (borderRight > 0) minRect.x += 1; 2638 minRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - BUTTON_SIZE)/2: borderTop + (tabHeight - BUTTON_SIZE)/2; 2639 minRect.width = BUTTON_SIZE; 2640 minRect.height = BUTTON_SIZE; 2641 } 2642 if (oldX != minRect.x || oldWidth != minRect.width || 2643 oldY != minRect.y || oldHeight != minRect.height) { 2644 int left = Math.min(oldX, minRect.x); 2645 int right = Math.max(oldX + oldWidth, minRect.x + minRect.width); 2646 int top = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1; 2647 redraw(left, top, right - left, tabHeight, false); 2648 } 2649 2650 oldX = topRightRect.x; 2652 oldY = topRightRect.y; 2653 oldWidth = topRightRect.width; 2654 oldHeight = topRightRect.height; 2655 topRightRect.x = topRightRect.y = topRightRect.width = topRightRect.height = 0; 2656 if (topRight != null) { 2657 switch (topRightAlignment) { 2658 case SWT.FILL: { 2659 int rightEdge = size.x - borderRight - 3 - maxRect.width - minRect.width; 2660 if (!simple && borderRight > 0 && !showMax && !showMin) rightEdge -= 2; 2661 if (single) { 2662 if (items.length == 0 || selectedIndex == -1) { 2663 topRightRect.x = borderLeft + 3; 2664 topRightRect.width = rightEdge - topRightRect.x; 2665 } else { 2666 CTabItem item = items[selectedIndex]; 2668 if (item.x + item.width + 7 + 3*BUTTON_SIZE/2 >= rightEdge) break; 2669 topRightRect.x = item.x + item.width + 7 + 3*BUTTON_SIZE/2; 2670 topRightRect.width = rightEdge - topRightRect.x; 2671 } 2672 } else { 2673 if (showChevron) break; 2675 if (items.length == 0) { 2676 topRightRect.x = borderLeft + 3; 2677 } else { 2678 CTabItem item = items[items.length - 1]; 2679 topRightRect.x = item.x + item.width; 2680 if (!simple && items.length - 1 == selectedIndex) topRightRect.x += curveWidth - curveIndent; 2681 } 2682 topRightRect.width = Math.max(0, rightEdge - topRightRect.x); 2683 } 2684 topRightRect.y = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1; 2685 topRightRect.height = tabHeight - 1; 2686 break; 2687 } 2688 case SWT.RIGHT: { 2689 Point topRightSize = topRight.computeSize(SWT.DEFAULT, tabHeight, false); 2690 int rightEdge = size.x - borderRight - 3 - maxRect.width - minRect.width; 2691 if (!simple && borderRight > 0 && !showMax && !showMin) rightEdge -= 2; 2692 topRightRect.x = rightEdge - topRightSize.x; 2693 topRightRect.width = topRightSize.x; 2694 topRightRect.y = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1; 2695 topRightRect.height = tabHeight - 1; 2696 } 2697 } 2698 topRight.setBounds(topRightRect); 2699 } 2700 if (oldX != topRightRect.x || oldWidth != topRightRect.width || 2701 oldY != topRightRect.y || oldHeight != topRightRect.height) { 2702 int left = Math.min(oldX, topRightRect.x); 2703 int right = Math.max(oldX + oldWidth, topRightRect.x + topRightRect.width); 2704 int top = onBottom ? size.y - borderBottom - tabHeight : borderTop + 1; 2705 redraw(left, top, right - left, tabHeight, false); 2706 } 2707 2708 oldX = chevronRect.x; 2710 oldY = chevronRect.y; 2711 oldWidth = chevronRect.width; 2712 oldHeight = chevronRect.height; 2713 chevronRect.x = chevronRect.y = chevronRect.height = chevronRect.width = 0; 2714 if (single) { 2715 if (selectedIndex == -1 || items.length > 1) { 2716 chevronRect.width = 3*BUTTON_SIZE/2; 2717 chevronRect.height = BUTTON_SIZE; 2718 chevronRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - chevronRect.height)/2 : borderTop + (tabHeight - chevronRect.height)/2; 2719 if (selectedIndex == -1) { 2720 chevronRect.x = size.x - borderRight - 3 - minRect.width - maxRect.width - topRightRect.width - chevronRect.width; 2721 } else { 2722 CTabItem item = items[selectedIndex]; 2723 int w = size.x - borderRight - 3 - minRect.width - maxRect.width - chevronRect.width; 2724 if (topRightRect.width > 0) w -= topRightRect.width + 3; 2725 chevronRect.x = Math.min(item.x + item.width + 3, w); 2726 } 2727 if (borderRight > 0) chevronRect.x += 1; 2728 } 2729 } else { 2730 if (showChevron) { 2731 chevronRect.width = 3*BUTTON_SIZE/2; 2732 chevronRect.height = BUTTON_SIZE; 2733 int i = 0, lastIndex = -1; 2734 while (i < priority.length && items[priority[i]].showing) { 2735 lastIndex = Math.max(lastIndex, priority[i++]); 2736 } 2737 if (lastIndex == -1) lastIndex = firstIndex; 2738 CTabItem lastItem = items[lastIndex]; 2739 int w = lastItem.x + lastItem.width + 3; 2740 if (!simple && lastIndex == selectedIndex) w += curveWidth - 2*curveIndent; 2741 chevronRect.x = Math.min(w, getRightItemEdge()); 2742 chevronRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - chevronRect.height)/2 : borderTop + (tabHeight - chevronRect.height)/2; 2743 } 2744 } 2745 if (oldX != chevronRect.x || oldWidth != chevronRect.width || 2746 oldY != chevronRect.y || oldHeight != chevronRect.height) { 2747 int left = Math.min(oldX, chevronRect.x); 2748 int right = Math.max(oldX + oldWidth, chevronRect.x + chevronRect.width); 2749 int top = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1; 2750 redraw(left, top, right - left, tabHeight, false); 2751 } 2752} 2753public void setFont(Font font) { 2754 checkWidget(); 2755 if (font != null && font.equals(getFont())) return; 2756 super.setFont(font); 2757 oldFont = getFont(); 2758 if (!updateTabHeight(false)) { 2759 updateItems(); 2760 redraw(); 2761 } 2762} 2763public void setForeground (Color color) { 2764 super.setForeground(color); 2765 redraw(); 2766} 2767 2781public void setInsertMark(CTabItem item, boolean after) { 2782 checkWidget(); 2783} 2784 2801public void setInsertMark(int index, boolean after) { 2802 checkWidget(); 2803 if (index < -1 || index >= getItemCount()) { 2804 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 2805 } 2806} 2807boolean setItemLocation() { 2808 boolean changed = false; 2809 if (items.length == 0) return false; 2810 Point size = getSize(); 2811 int y = onBottom ? Math.max(borderBottom, size.y - borderBottom - tabHeight) : borderTop; 2812 if (single) { 2813 int defaultX = getDisplay().getBounds().width + 10; for (int i = 0; i < items.length; i++) { 2815 CTabItem item = items[i]; 2816 if (i == selectedIndex) { 2817 firstIndex = selectedIndex; 2818 int oldX = item.x, oldY = item.y; 2819 item.x = borderLeft; 2820 item.y = y; 2821 item.showing = true; 2822 if (showClose || item.showClose) { 2823 item.closeRect.x = borderLeft + CTabItem.LEFT_MARGIN; 2824 item.closeRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - BUTTON_SIZE)/2: borderTop + (tabHeight - BUTTON_SIZE)/2; 2825 } 2826 if (item.x != oldX || item.y != oldY) changed = true; 2827 } else { 2828 item.x = defaultX; 2829 item.showing = false; 2830 } 2831 } 2832 } else { 2833 int rightItemEdge = getRightItemEdge(); 2834 int maxWidth = rightItemEdge - borderLeft; 2835 int width = 0; 2836 for (int i = 0; i < priority.length; i++) { 2837 CTabItem item = items[priority[i]]; 2838 width += item.width; 2839 item.showing = i == 0 ? true : item.width > 0 && width <= maxWidth; 2840 if (!simple && priority[i] == selectedIndex) width += curveWidth - 2*curveIndent; 2841 } 2842 int x = 0; 2843 int defaultX = getDisplay().getBounds().width + 10; firstIndex = items.length - 1; 2845 for (int i = 0; i < items.length; i++) { 2846 CTabItem item = items[i]; 2847 if (!item.showing) { 2848 if (item.x != defaultX) changed = true; 2849 item.x = defaultX; 2850 } else { 2851 firstIndex = Math.min(firstIndex, i); 2852 if (item.x != x || item.y != y) changed = true; 2853 item.x = x; 2854 item.y = y; 2855 if (i == selectedIndex) { 2856 int edge = Math.min(item.x + item.width, rightItemEdge); 2857 item.closeRect.x = edge - CTabItem.RIGHT_MARGIN - BUTTON_SIZE; 2858 } else { 2859 item.closeRect.x = item.x + item.width - CTabItem.RIGHT_MARGIN - BUTTON_SIZE; 2860 } 2861 item.closeRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - BUTTON_SIZE)/2: borderTop + (tabHeight - BUTTON_SIZE)/2; 2862 x = x + item.width; 2863 if (!simple && i == selectedIndex) x += curveWidth - 2*curveIndent; 2864 } 2865 } 2866 } 2867 return changed; 2868} 2869boolean setItemSize() { 2870 boolean changed = false; 2871 if (isDisposed()) return changed; 2872 Point size = getSize(); 2873 if (size.x <= 0 || size.y <= 0) return changed; 2874 xClient = borderLeft + marginWidth + highlight_margin; 2875 if (onBottom) { 2876 yClient = borderTop + highlight_margin + marginHeight; 2877 } else { 2878 yClient = borderTop + tabHeight + highlight_header + marginHeight; 2879 } 2880 showChevron = false; 2881 if (single) { 2882 showChevron = true; 2883 if (selectedIndex != -1) { 2884 CTabItem tab = items[selectedIndex]; 2885 GC gc = new GC(this); 2886 int width = tab.preferredWidth(gc, true, false); 2887 gc.dispose(); 2888 width = Math.min(width, getRightItemEdge() - borderLeft); 2889 if (tab.height != tabHeight || tab.width != width) { 2890 changed = true; 2891 tab.shortenedText = null; 2892 tab.shortenedTextWidth = 0; 2893 tab.height = tabHeight; 2894 tab.width = width; 2895 tab.closeRect.width = tab.closeRect.height = 0; 2896 if (showClose || tab.showClose) { 2897 tab.closeRect.width = BUTTON_SIZE; 2898 tab.closeRect.height = BUTTON_SIZE; 2899 } 2900 } 2901 } 2902 return changed; 2903 } 2904 2905 if (items.length == 0) return changed; 2906 2907 int[] widths; 2908 GC gc = new GC(this); 2909 int tabAreaWidth = size.x - borderLeft - borderRight - 3; 2910 if (showMin) tabAreaWidth -= BUTTON_SIZE; 2911 if (showMax) tabAreaWidth -= BUTTON_SIZE; 2912 if (topRightAlignment == SWT.RIGHT && topRight != null) { 2913 Point rightSize = topRight.computeSize(SWT.DEFAULT, SWT.DEFAULT, false); 2914 tabAreaWidth -= rightSize.x + 3; 2915 } 2916 if (!simple) tabAreaWidth -= curveWidth - 2*curveIndent; 2917 tabAreaWidth = Math.max(0, tabAreaWidth); 2918 2919 int minWidth = 0; 2921 int[] minWidths = new int[items.length]; 2922 for (int i = 0; i < priority.length; i++) { 2923 int index = priority[i]; 2924 minWidths[index] = items[index].preferredWidth(gc, index == selectedIndex, true); 2925 minWidth += minWidths[index]; 2926 if (minWidth > tabAreaWidth) break; 2927 } 2928 if (minWidth > tabAreaWidth) { 2929 showChevron = items.length > 1; 2931 if (showChevron) tabAreaWidth -= 3*BUTTON_SIZE/2; 2932 widths = minWidths; 2933 int index = selectedIndex != -1 ? selectedIndex : 0; 2934 if (tabAreaWidth < widths[index]) { 2935 widths[index] = Math.max(0, tabAreaWidth); 2936 } 2937 } else { 2938 int maxWidth = 0; 2939 int[] maxWidths = new int[items.length]; 2940 for (int i = 0; i < items.length; i++) { 2941 maxWidths[i] = items[i].preferredWidth(gc, i == selectedIndex, false); 2942 maxWidth += maxWidths[i]; 2943 } 2944 if (maxWidth <= tabAreaWidth) { 2945 widths = maxWidths; 2947 } else { 2948 int extra = (tabAreaWidth - minWidth) / items.length; 2950 while (true) { 2951 int large = 0, totalWidth = 0; 2952 for (int i = 0 ; i < items.length; i++) { 2953 if (maxWidths[i] > minWidths[i] + extra) { 2954 totalWidth += minWidths[i] + extra; 2955 large++; 2956 } else { 2957 totalWidth += maxWidths[i]; 2958 } 2959 } 2960 if (totalWidth >= tabAreaWidth) { 2961 extra--; 2962 break; 2963 } 2964 if (large == 0 || tabAreaWidth - totalWidth < large) break; 2965 extra++; 2966 } 2967 widths = new int[items.length]; 2968 for (int i = 0; i < items.length; i++) { 2969 widths[i] = Math.min(maxWidths[i], minWidths[i] + extra); 2970 } 2971 } 2972 } 2973 gc.dispose(); 2974 2975 for (int i = 0; i < items.length; i++) { 2976 CTabItem tab = items[i]; 2977 int width = widths[i]; 2978 if (tab.height != tabHeight || tab.width != width) { 2979 changed = true; 2980 tab.shortenedText = null; 2981 tab.shortenedTextWidth = 0; 2982 tab.height = tabHeight; 2983 tab.width = width; 2984 tab.closeRect.width = tab.closeRect.height = 0; 2985 if (showClose || tab.showClose) { 2986 if (i == selectedIndex || showUnselectedClose) { 2987 tab.closeRect.width = BUTTON_SIZE; 2988 tab.closeRect.height = BUTTON_SIZE; 2989 } 2990 } 2991 } 2992 } 2993 return changed; 2994} 2995 3008public void setMaximizeVisible(boolean visible) { 3009 checkWidget(); 3010 if (showMax == visible) return; 3011 showMax = visible; 3013 updateItems(); 3014 redraw(); 3015} 3016 3031public void setLayout (Layout layout) { 3032 checkWidget(); 3033 return; 3034} 3035 3047public void setMaximized(boolean maximize) { 3048 checkWidget (); 3049 if (this.maximized == maximize) return; 3050 if (maximize && this.minimized) setMinimized(false); 3051 this.maximized = maximize; 3052 redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false); 3053} 3054 3067public void setMinimizeVisible(boolean visible) { 3068 checkWidget(); 3069 if (showMin == visible) return; 3070 showMin = visible; 3072 updateItems(); 3073 redraw(); 3074} 3075 3087public void setMinimized(boolean minimize) { 3088 checkWidget (); 3089 if (this.minimized == minimize) return; 3090 if (minimize && this.maximized) setMaximized(false); 3091 this.minimized = minimize; 3092 redraw(minRect.x, minRect.y, minRect.width, minRect.height, false); 3093} 3094 3095 3109public void setMinimumCharacters(int count) { 3110 checkWidget (); 3111 if (count < 0) SWT.error(SWT.ERROR_INVALID_RANGE); 3112 if (minChars == count) return; 3113 minChars = count; 3114 if (updateItems()) redrawTabs(); 3115} 3116 3117 3143public void setMRUVisible(boolean show) { 3144 checkWidget(); 3145 if (mru == show) return; 3146 mru = show; 3147 if (!mru) { 3148 int idx = firstIndex; 3149 int next = 0; 3150 for (int i = firstIndex; i < items.length; i++) { 3151 priority[next++] = i; 3152 } 3153 for (int i = 0; i < idx; i++) { 3154 priority[next++] = i; 3155 } 3156 if (updateItems()) redrawTabs(); 3157 } 3158} 3159 3173public void setSelection(CTabItem item) { 3174 checkWidget(); 3175 if (item == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 3176 int index = indexOf(item); 3177 setSelection(index); 3178} 3179 3189public void setSelection(int index) { 3190 checkWidget(); 3191 if (index < 0 || index >= items.length) return; 3192 CTabItem selection = items[index]; 3193 if (selectedIndex == index) { 3194 showItem(selection); 3195 return; 3196 } 3197 3198 int oldIndex = selectedIndex; 3199 selectedIndex = index; 3200 if (oldIndex != -1) { 3201 items[oldIndex].closeImageState = NONE; 3202 } 3203 selection.closeImageState = NORMAL; 3204 selection.showing = false; 3205 3206 Control control = selection.control; 3207 if (control != null && !control.isDisposed()) { 3208 control.setBounds(getClientArea()); 3209 control.setVisible(true); 3210 } 3211 3212 if (oldIndex != -1) { 3213 control = items[oldIndex].control; 3214 if (control != null && !control.isDisposed()) { 3215 control.setVisible(false); 3216 } 3217 } 3218 showItem(selection); 3219 redraw(); 3220} 3221void setSelection(int index, boolean notify) { 3222 int oldSelectedIndex = selectedIndex; 3223 setSelection(index); 3224 if (notify && selectedIndex != oldSelectedIndex && selectedIndex != -1) { 3225 Event event = new Event(); 3226 event.item = getItem(selectedIndex); 3227 notifyListeners(SWT.Selection, event); 3228 } 3229} 3230 3247public void setSelectionBackground (Color color) { 3248 checkWidget(); 3249 setSelectionHighlightGradientColor(null); 3250 if (selectionBackground == color) return; 3251 if (color == null) color = getDisplay().getSystemColor(SELECTION_BACKGROUND); 3252 selectionBackground = color; 3253 if (selectedIndex > -1) redraw(); 3254} 3255 3280public void setSelectionBackground(Color[] colors, int[] percents) { 3281 setSelectionBackground(colors, percents, false); 3282} 3283 3312public void setSelectionBackground(Color[] colors, int[] percents, boolean vertical) { 3313 checkWidget(); 3314 int colorsLength; 3315 Color highlightBeginColor = null; 3317 if (colors != null) { 3318 if (percents == null || 3321 ! ((percents.length == colors.length - 1) || (percents.length == colors.length - 2))){ 3322 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3323 } 3324 for (int i = 0; i < percents.length; i++) { 3325 if (percents[i] < 0 || percents[i] > 100) { 3326 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3327 } 3328 if (i > 0 && percents[i] < percents[i-1]) { 3329 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3330 } 3331 } 3332 if(percents.length == colors.length - 2) { 3335 highlightBeginColor = colors[colors.length - 1]; 3336 colorsLength = colors.length - 1; 3337 } else { 3338 colorsLength = colors.length; 3339 } 3340 if (getDisplay().getDepth() < 15) { 3341 colors = new Color[] {colors[colorsLength - 1]}; 3343 colorsLength = colors.length; 3344 percents = new int[] {}; 3345 } 3346 } else { 3347 colorsLength = 0; 3348 } 3349 3350 if (selectionBgImage == null) { 3352 if ((selectionGradientColors != null) && (colors != null) && 3353 (selectionGradientColors.length == colorsLength)) { 3354 boolean same = false; 3355 for (int i = 0; i < selectionGradientColors.length; i++) { 3356 if (selectionGradientColors[i] == null) { 3357 same = colors[i] == null; 3358 } else { 3359 same = selectionGradientColors[i].equals(colors[i]); 3360 } 3361 if (!same) break; 3362 } 3363 if (same) { 3364 for (int i = 0; i < selectionGradientPercents.length; i++) { 3365 same = selectionGradientPercents[i] == percents[i]; 3366 if (!same) break; 3367 } 3368 } 3369 if (same && this.selectionGradientVertical == vertical) return; 3370 } 3371 } else { 3372 selectionBgImage = null; 3373 } 3374 if (colors == null) { 3376 selectionGradientColors = null; 3377 selectionGradientPercents = null; 3378 selectionGradientVertical = false; 3379 setSelectionBackground((Color)null); 3380 setSelectionHighlightGradientColor(null); 3381 } else { 3382 selectionGradientColors = new Color[colorsLength]; 3383 for (int i = 0; i < colorsLength; ++i) { 3384 selectionGradientColors[i] = colors[i]; 3385 } 3386 selectionGradientPercents = new int[percents.length]; 3387 for (int i = 0; i < percents.length; ++i) { 3388 selectionGradientPercents[i] = percents[i]; 3389 } 3390 selectionGradientVertical = vertical; 3391 setSelectionBackground(selectionGradientColors[selectionGradientColors.length-1]); 3392 setSelectionHighlightGradientColor(highlightBeginColor); 3393 } 3394 3395 if (selectedIndex > -1) redraw(); 3397} 3398 3399 3403 3404void setSelectionHighlightGradientColor(Color start) { 3405 selectionHighlightGradientBegin = null; 3408 3409 if(start == null) 3410 return; 3411 3412 if (getDisplay().getDepth() < 15) 3414 return; 3415 3416 if(selectionGradientColors.length < 2) 3418 return; 3419 3420 selectionHighlightGradientBegin = start; 3422 3423 if(! isSelectionHighlightColorsCacheHit(start)) 3424 createSelectionHighlightGradientColors(start); } 3426 3427 3431boolean isSelectionHighlightColorsCacheHit(Color start) { 3432 3433 if(selectionHighlightGradientColorsCache == null) 3434 return false; 3435 3436 if(selectionHighlightGradientColorsCache.length < 2) 3438 return false; 3439 3440 Color highlightBegin = selectionHighlightGradientColorsCache[0]; 3441 Color highlightEnd = selectionHighlightGradientColorsCache[selectionHighlightGradientColorsCache.length - 1]; 3442 3443 if(! highlightBegin.equals(start)) 3444 return false; 3445 3446 if(selectionHighlightGradientColorsCache.length != tabHeight) 3448 return false; 3449 3450 if(! highlightEnd.equals(selectionBackground)) 3452 return false; 3453 3454 return true; 3455} 3456 3457 3468public void setSelectionBackground(Image image) { 3469 checkWidget(); 3470 setSelectionHighlightGradientColor(null); 3471 if (image == selectionBgImage) return; 3472 if (image != null) { 3473 selectionGradientColors = null; 3474 selectionGradientPercents = null; 3475 disposeSelectionHighlightGradientColors(); 3476 } 3477 selectionBgImage = image; 3478 if (selectedIndex > -1) redraw(); 3479} 3480 3490public void setSelectionForeground (Color color) { 3491 checkWidget(); 3492 if (selectionForeground == color) return; 3493 if (color == null) color = getDisplay().getSystemColor(SELECTION_FOREGROUND); 3494 selectionForeground = color; 3495 if (selectedIndex > -1) redraw(); 3496} 3497 3498 3505void createSelectionHighlightGradientColors(Color start) { 3506 disposeSelectionHighlightGradientColors(); 3508 if(start == null) return; 3510 3511 int fadeGradientSize = tabHeight; 3513 3514 RGB from = start.getRGB(); 3515 RGB to = selectionBackground.getRGB(); 3516 3517 selectionHighlightGradientColorsCache = new Color[fadeGradientSize]; 3518 int denom = fadeGradientSize - 1; 3519 3520 for (int i = 0; i < fadeGradientSize; i++) { 3521 int propFrom = denom - i; 3522 int propTo = i; 3523 int red = (to.red * propTo + from.red * propFrom) / denom; 3524 int green = (to.green * propTo + from.green * propFrom) / denom; 3525 int blue = (to.blue * propTo + from.blue * propFrom) / denom; 3526 selectionHighlightGradientColorsCache[i] = new Color(getDisplay(), red, green, blue); 3527 } 3528} 3529 3530void disposeSelectionHighlightGradientColors() { 3531 if(selectionHighlightGradientColorsCache == null) 3532 return; 3533 for (int i = 0; i < selectionHighlightGradientColorsCache.length; i++) { 3534 selectionHighlightGradientColorsCache[i].dispose(); 3535 } 3536 selectionHighlightGradientColorsCache = null; 3537} 3538 3539 3543Color getSelectionBackgroundGradientBegin() { 3544 if (selectionGradientColors == null) 3545 return getSelectionBackground(); 3546 if (selectionGradientColors.length == 0) 3547 return getSelectionBackground(); 3548 return selectionGradientColors[0]; 3549} 3550 3551 3563public void setSimple(boolean simple) { 3564 checkWidget(); 3565 if (this.simple != simple) { 3566 this.simple = simple; 3567 Rectangle rectBefore = getClientArea(); 3568 updateItems(); 3569 Rectangle rectAfter = getClientArea(); 3570 if (!rectBefore.equals(rectAfter)) { 3571 notifyListeners(SWT.Resize, new Event()); 3572 } 3573 redraw(); 3574 } 3575} 3576 3588public void setSingle(boolean single) { 3589 checkWidget(); 3590 if (this.single != single) { 3591 this.single = single; 3592 if (!single) { 3593 for (int i = 0; i < items.length; i++) { 3594 if (i != selectedIndex && items[i].closeImageState == NORMAL) { 3595 items[i].closeImageState = NONE; 3596 } 3597 } 3598 } 3599 Rectangle rectBefore = getClientArea(); 3600 updateItems(); 3601 Rectangle rectAfter = getClientArea(); 3602 if (!rectBefore.equals(rectAfter)) { 3603 notifyListeners(SWT.Resize, new Event()); 3604 } 3605 redraw(); 3606 } 3607} 3608 3621public void setTabHeight(int height) { 3622 checkWidget(); 3623 if (height < -1) { 3624 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3625 } 3626 fixedTabHeight = height; 3627 updateTabHeight(false); 3628} 3629 3643public void setTabPosition(int position) { 3644 checkWidget(); 3645 if (position != SWT.TOP && position != SWT.BOTTOM) { 3646 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3647 } 3648 if (onBottom != (position == SWT.BOTTOM)) { 3649 onBottom = position == SWT.BOTTOM; 3650 borderTop = onBottom ? borderLeft : 0; 3651 borderBottom = onBottom ? 0 : borderRight; 3652 updateTabHeight(true); 3653 Rectangle rectBefore = getClientArea(); 3654 updateItems(); 3655 Rectangle rectAfter = getClientArea(); 3656 if (!rectBefore.equals(rectAfter)) { 3657 notifyListeners(SWT.Resize, new Event()); 3658 } 3659 redraw(); 3660 } 3661} 3662 3678public void setTopRight(Control control) { 3679 setTopRight(control, SWT.RIGHT); 3680} 3681 3705public void setTopRight(Control control, int alignment) { 3706 checkWidget(); 3707 if (alignment != SWT.RIGHT && alignment != SWT.FILL) { 3708 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3709 } 3710 if (control != null && control.getParent() != this) { 3711 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3712 } 3713 topRight = control; 3714 topRightAlignment = alignment; 3715 if (updateItems()) redraw(); 3716} 3717 3730public void setUnselectedCloseVisible(boolean visible) { 3731 checkWidget(); 3732 if (showUnselectedClose == visible) return; 3733 showUnselectedClose = visible; 3735 updateItems(); 3736 redraw(); 3737} 3738 3750public void setUnselectedImageVisible(boolean visible) { 3751 checkWidget(); 3752 if (showUnselectedImage == visible) return; 3753 showUnselectedImage = visible; 3755 updateItems(); 3756 redraw(); 3757} 3758 3778public void showItem (CTabItem item) { 3779 checkWidget(); 3780 if (item == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); 3781 if (item.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3782 int index = indexOf(item); 3783 if (index == -1) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 3784 int idx = -1; 3785 for (int i = 0; i < priority.length; i++) { 3786 if (priority[i] == index) { 3787 idx = i; 3788 break; 3789 } 3790 } 3791 if (mru) { 3792 int[] newPriority = new int[priority.length]; 3794 System.arraycopy(priority, 0, newPriority, 1, idx); 3795 System.arraycopy(priority, idx+1, newPriority, idx+1, priority.length - idx - 1); 3796 newPriority[0] = index; 3797 priority = newPriority; 3798 } 3799 if (item.isShowing()) return; 3800 updateItems(index); 3801 redrawTabs(); 3802} 3803void showList (Rectangle rect) { 3804 if (items.length == 0 || !showChevron) return; 3805 if (showMenu == null || showMenu.isDisposed()) { 3806 showMenu = new Menu(this); 3807 } else { 3808 MenuItem[] items = showMenu.getItems(); 3809 for (int i = 0; i < items.length; i++) { 3810 items[i].dispose(); 3811 } 3812 } 3813 final String id = "CTabFolder_showList_Index"; for (int i = 0; i < items.length; i++) { 3815 CTabItem tab = items[i]; 3816 if (tab.showing) continue; 3817 MenuItem item = new MenuItem(showMenu, SWT.NONE); 3818 item.setText(tab.getText()); 3819 item.setImage(tab.getImage()); 3820 item.setData(id, tab); 3821 item.addSelectionListener(new SelectionAdapter() { 3822 public void widgetSelected(SelectionEvent e) { 3823 MenuItem menuItem = (MenuItem)e.widget; 3824 int index = indexOf((CTabItem)menuItem.getData(id)); 3825 CTabFolder.this.setSelection(index, true); 3826 } 3827 }); 3828 } 3829 int x = rect.x; 3830 int y = rect.y + rect.height; 3831 Point location = getDisplay().map(this, null, x, y); 3832 showMenu.setLocation(location.x, location.y); 3833 showMenu.setVisible(true); 3834} 3835 3849public void showSelection () { 3850 checkWidget (); 3851 if (selectedIndex != -1) { 3852 showItem(getSelection()); 3853 } 3854} 3855 3856void _setToolTipText (int x, int y) { 3857 String oldTip = getToolTipText(); 3858 String newTip = _getToolTip(x, y); 3859 if (newTip == null || !newTip.equals(oldTip)) { 3860 setToolTipText(newTip); 3861 } 3862} 3863 3864boolean updateItems() { 3865 return updateItems(selectedIndex); 3866} 3867 3868boolean updateItems(int showIndex) { 3869 if (!single && !mru && showIndex != -1) { 3870 int firstIndex = showIndex; 3872 if (priority[0] < showIndex) { 3873 int maxWidth = getRightItemEdge() - borderLeft; 3874 if (!simple) maxWidth -= curveWidth - 2*curveIndent; 3875 int width = 0; 3876 int[] widths = new int[items.length]; 3877 GC gc = new GC(this); 3878 for (int i = priority[0]; i <= showIndex; i++) { 3879 widths[i] = items[i].preferredWidth(gc, i == selectedIndex, true); 3880 width += widths[i]; 3881 if (width > maxWidth) break; 3882 } 3883 if (width > maxWidth) { 3884 width = 0; 3885 for (int i = showIndex; i >= 0; i--) { 3886 if (widths[i] == 0) widths[i] = items[i].preferredWidth(gc, i == selectedIndex, true); 3887 width += widths[i]; 3888 if (width > maxWidth) break; 3889 firstIndex = i; 3890 } 3891 } else { 3892 firstIndex = priority[0]; 3893 for (int i = showIndex + 1; i < items.length; i++) { 3894 widths[i] = items[i].preferredWidth(gc, i == selectedIndex, true); 3895 width += widths[i]; 3896 if (width >= maxWidth) break; 3897 } 3898 if (width < maxWidth) { 3899 for (int i = priority[0] - 1; i >= 0; i--) { 3900 if (widths[i] == 0) widths[i] = items[i].preferredWidth(gc, i == selectedIndex, true); 3901 width += widths[i]; 3902 if (width > maxWidth) break; 3903 firstIndex = i; 3904 } 3905 } 3906 } 3907 gc.dispose(); 3908 } 3909 if (firstIndex != priority[0]) { 3910 int index = 0; 3911 for (int i = firstIndex; i < items.length; i++) { 3912 priority[index++] = i; 3913 } 3914 for (int i = 0; i < firstIndex; i++) { 3915 priority[index++] = i; 3916 } 3917 } 3918 } 3919 3920 boolean oldShowChevron = showChevron; 3921 boolean changed = setItemSize(); 3922 changed |= setItemLocation(); 3923 setButtonBounds(); 3924 changed |= showChevron != oldShowChevron; 3925 if (changed && getToolTipText() != null) { 3926 Point pt = getDisplay().getCursorLocation(); 3927 pt = toControl(pt); 3928 _setToolTipText(pt.x, pt.y); 3929 } 3930 return changed; 3931} 3932boolean updateTabHeight(boolean force){ 3933 int style = getStyle(); 3934 if (fixedTabHeight == 0 && (style & SWT.FLAT) != 0 && (style & SWT.BORDER) == 0) highlight_header = 0; 3935 int oldHeight = tabHeight; 3936 if (fixedTabHeight != SWT.DEFAULT) { 3937 tabHeight = fixedTabHeight == 0 ? 0 : fixedTabHeight + 1; } else { 3939 int tempHeight = 0; 3940 GC gc = new GC(this); 3941 if (items.length == 0) { 3942 tempHeight = gc.textExtent("Default", CTabItem.FLAGS).y + CTabItem.TOP_MARGIN + CTabItem.BOTTOM_MARGIN; } else { 3944 for (int i=0; i < items.length; i++) { 3945 tempHeight = Math.max(tempHeight, items[i].preferredHeight(gc)); 3946 } 3947 } 3948 gc.dispose(); 3949 tabHeight = tempHeight; 3950 } 3951 if (!force && tabHeight == oldHeight) return false; 3952 3953 oldSize = null; 3954 if (onBottom) { 3955 int d = tabHeight - 12; 3956 curve = new int[]{0,13+d, 0,12+d, 2,12+d, 3,11+d, 5,11+d, 6,10+d, 7,10+d, 9,8+d, 10,8+d, 3957 11,7+d, 11+d,7, 3958 12+d,6, 13+d,6, 15+d,4, 16+d,4, 17+d,3, 19+d,3, 20+d,2, 22+d,2, 23+d,1}; 3959 curveWidth = 26+d; 3960 curveIndent = curveWidth/3; 3961 } else { 3962 int d = tabHeight - 12; 3963 curve = new int[]{0,0, 0,1, 2,1, 3,2, 5,2, 6,3, 7,3, 9,5, 10,5, 3964 11,6, 11+d,6+d, 3965 12+d,7+d, 13+d,7+d, 15+d,9+d, 16+d,9+d, 17+d,10+d, 19+d,10+d, 20+d,11+d, 22+d,11+d, 23+d,12+d}; 3966 curveWidth = 26+d; 3967 curveIndent = curveWidth/3; 3968 3969 topCurveHighlightStart = new int[] { 3971 0, 2, 1, 2, 2, 2, 3972 3, 3, 4, 3, 5, 3, 3973 6, 4, 7, 4, 3974 8, 5, 3975 9, 6, 10, 6}; 3976 3977 topCurveHighlightEnd = new int[] { 3979 10+d, 6+d, 3980 11+d, 7+d, 3981 12+d, 8+d, 13+d, 8+d, 3982 14+d, 9+d, 3983 15+d, 10+d, 16+d, 10+d, 3984 17+d, 11+d, 18+d, 11+d, 19+d, 11+d, 3985 20+d, 12+d, 21+d, 12+d, 22+d, 12+d }; 3986 } 3987 notifyListeners(SWT.Resize, new Event()); 3988 return true; 3989} 3990String _getToolTip(int x, int y) { 3991 if (showMin && minRect.contains(x, y)) return minimized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Minimize"); if (showMax && maxRect.contains(x, y)) return maximized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Maximize"); if (showChevron && chevronRect.contains(x, y)) return SWT.getMessage("SWT_ShowList"); CTabItem item = getItem(new Point (x, y)); 3995 if (item == null) return null; 3996 if (!item.showing) return null; 3997 if ((showClose || item.showClose) && item.closeRect.contains(x, y)) { 3998 return SWT.getMessage("SWT_Close"); } 4000 return item.getToolTipText(); 4001} 4002} 4003 | Popular Tags |