1 11 package org.eclipse.ui.internal.presentations; 12 13 import java.util.ArrayList ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 17 import org.eclipse.core.runtime.Assert; 18 import org.eclipse.jface.action.GroupMarker; 19 import org.eclipse.jface.action.IMenuManager; 20 import org.eclipse.jface.action.MenuManager; 21 import org.eclipse.jface.action.Separator; 22 import org.eclipse.jface.preference.IPreferenceStore; 23 import org.eclipse.jface.util.Geometry; 24 import org.eclipse.jface.window.Window; 25 import org.eclipse.swt.SWT; 26 import org.eclipse.swt.events.DisposeEvent; 27 import org.eclipse.swt.events.DisposeListener; 28 import org.eclipse.swt.events.MouseAdapter; 29 import org.eclipse.swt.events.MouseEvent; 30 import org.eclipse.swt.events.MouseListener; 31 import org.eclipse.swt.events.ShellAdapter; 32 import org.eclipse.swt.events.ShellEvent; 33 import org.eclipse.swt.graphics.Color; 34 import org.eclipse.swt.graphics.Image; 35 import org.eclipse.swt.graphics.Point; 36 import org.eclipse.swt.graphics.Rectangle; 37 import org.eclipse.swt.widgets.Composite; 38 import org.eclipse.swt.widgets.Control; 39 import org.eclipse.swt.widgets.Event; 40 import org.eclipse.swt.widgets.Listener; 41 import org.eclipse.swt.widgets.Menu; 42 import org.eclipse.ui.IMemento; 43 import org.eclipse.ui.IPropertyListener; 44 import org.eclipse.ui.internal.IPreferenceConstants; 45 import org.eclipse.ui.internal.IWorkbenchConstants; 46 import org.eclipse.ui.internal.WorkbenchPlugin; 47 import org.eclipse.ui.internal.WorkbenchWindow; 48 import org.eclipse.ui.internal.dnd.DragUtil; 49 import org.eclipse.ui.internal.presentations.r21.R21Colors; 50 import org.eclipse.ui.internal.presentations.r21.R21PresentationMessages; 51 import org.eclipse.ui.internal.presentations.r21.widgets.CTabFolder; 52 import org.eclipse.ui.internal.presentations.r21.widgets.CTabFolderEvent; 53 import org.eclipse.ui.internal.presentations.r21.widgets.CTabFolderListener; 54 import org.eclipse.ui.internal.presentations.r21.widgets.CTabItem; 55 import org.eclipse.ui.presentations.IPartMenu; 56 import org.eclipse.ui.presentations.IPresentablePart; 57 import org.eclipse.ui.presentations.IPresentationSerializer; 58 import org.eclipse.ui.presentations.IStackPresentationSite; 59 import org.eclipse.ui.presentations.PresentationUtil; 60 import org.eclipse.ui.presentations.StackDropResult; 61 import org.eclipse.ui.presentations.StackPresentation; 62 63 72 public class R21EditorStackPresentation extends StackPresentation { 73 74 75 private CTabFolder tabFolder; 76 77 78 private Listener dragListener = new Listener() { 79 80 public void handleEvent(Event event) { 81 Point localPos = new Point(event.x, event.y); 82 CTabItem tabUnderPointer = tabFolder.getItem(localPos); 83 84 if (tabUnderPointer == null) { 85 if (getSite().isStackMoveable()) { 87 getSite().dragStart(tabFolder.toDisplay(localPos), false); 88 } 89 return; 90 } 91 92 IPresentablePart part = getPartForTab(tabUnderPointer); 93 94 if (getSite().isPartMoveable(part)) { 95 getSite().dragStart(part, tabFolder.toDisplay(localPos), false); 97 } 98 } 99 }; 100 101 102 private CTabFolderListener closeListener = new CTabFolderListener() { 103 104 public void itemClosed(CTabFolderEvent e) { 105 CTabItem item = (CTabItem) e.item; 106 if (null != item) { 107 e.doit = false; getSite().close(new IPresentablePart[] { getPartForTab(item) }); 109 } 110 } 111 }; 112 113 114 private IPresentablePart current; 115 116 117 private MenuManager systemMenuManager = new MenuManager(); 118 119 120 private static IPreferenceStore preferenceStore = WorkbenchPlugin 121 .getDefault().getPreferenceStore(); 122 123 private static int tabPos = preferenceStore 128 .getInt(IPreferenceConstants.EDITOR_TAB_POSITION); 129 130 131 private final static String TAB_DATA = R21EditorStackPresentation.class 132 .getName() 133 + ".partId"; 135 136 private MouseListener mouseListener = new MouseAdapter() { 137 138 143 public void mouseDown(MouseEvent e) { 144 if (e.widget instanceof Control) { 145 Control ctrl = (Control) e.widget; 146 147 Point globalPos = ctrl.toDisplay(new Point(e.x, e.y)); 148 149 CTabItem newItem = tabFolder.getItem(tabFolder 150 .toControl(globalPos)); 151 if (newItem != null) { 152 153 if ((e.button == 1) && overImage(newItem, e.x)) { 155 getSite().selectPart(getPartForTab(newItem)); 156 showSystemMenu(); 157 } 158 159 CTabItem oldItem = tabFolder.getSelection(); 162 if (newItem != oldItem) { 163 return; 164 } 165 } 166 167 if (current != null) { 169 current.setFocus(); 170 } 171 } 172 } 173 174 179 public void mouseDoubleClick(MouseEvent e) { 180 if (getSite().getState() == IStackPresentationSite.STATE_MAXIMIZED) { 181 getSite().setState(IStackPresentationSite.STATE_RESTORED); 182 } else { 183 getSite().setState(IStackPresentationSite.STATE_MAXIMIZED); 184 } 185 } 186 }; 187 188 193 static boolean overImage(CTabItem item, int x) { 194 Rectangle imageBounds = item.getImage().getBounds(); 195 return x < (item.getBounds().x + imageBounds.x + imageBounds.width); 196 } 197 198 199 private Listener menuListener = new Listener() { 200 201 206 public void handleEvent(Event event) { 207 Point pos = new Point(event.x, event.y); 208 showSystemMenu(pos); 209 } 210 }; 211 212 213 private Listener selectionListener = new Listener() { 214 215 public void handleEvent(Event e) { 216 IPresentablePart item = getPartForTab((CTabItem) e.item); 217 if (item != null) { 218 getSite().selectPart(item); 219 } 220 } 221 }; 222 223 private Listener resizeListener = new Listener() { 224 225 public void handleEvent(Event e) { 226 setControlSize(); 227 } 228 }; 229 230 231 private IPropertyListener childPropertyChangeListener = new IPropertyListener() { 232 233 public void propertyChanged(Object source, int property) { 234 if (source instanceof IPresentablePart) { 235 IPresentablePart part = (IPresentablePart) source; 236 childPropertyChanged(part, property); 237 } 238 } 239 }; 240 241 242 private DisposeListener tabDisposeListener = new DisposeListener() { 243 244 public void widgetDisposed(DisposeEvent e) { 245 if (e.widget instanceof CTabItem) { 246 CTabItem item = (CTabItem) e.widget; 247 IPresentablePart part = getPartForTab(item); 248 part.removePropertyListener(childPropertyChangeListener); 249 } 250 } 251 }; 252 253 254 private ShellAdapter shellListener = new ShellAdapter() { 255 256 public void shellActivated(ShellEvent event) { 257 updateGradient(); 258 } 259 260 public void shellDeactivated(ShellEvent event) { 261 updateGradient(); 262 } 263 }; 264 265 273 public R21EditorStackPresentation(Composite parent, 274 IStackPresentationSite stackSite) { 275 super(stackSite); 276 277 tabFolder = new CTabFolder(parent, tabPos | SWT.BORDER); 279 280 tabFolder.MIN_TAB_WIDTH = preferenceStore 282 .getInt(IPreferenceConstants.EDITOR_TAB_WIDTH); 283 284 tabFolder.setTabList(new Control[0]); 286 287 tabFolder.addCTabFolderListener(closeListener); 289 290 tabFolder.addListener(SWT.Selection, selectionListener); 292 293 tabFolder.addListener(SWT.Resize, resizeListener); 295 296 tabFolder.addMouseListener(mouseListener); 299 300 tabFolder.addListener(SWT.MenuDetect, menuListener); 302 303 PresentationUtil.addDragListener(tabFolder, dragListener); 305 306 tabFolder.getShell().addShellListener(shellListener); 309 310 populateSystemMenu(systemMenuManager); 312 } 313 314 319 private void populateSystemMenu(IMenuManager menuManager) { 320 321 menuManager.add(new GroupMarker("misc")); menuManager.add(new GroupMarker("restore")); menuManager.add(new UpdatingActionContributionItem( 324 new SystemMenuRestore(getSite()))); 325 menuManager.add(new SystemMenuMove(getSite(), getPaneName())); 326 menuManager.add(new GroupMarker("size")); menuManager.add(new GroupMarker("state")); menuManager.add(new UpdatingActionContributionItem( 331 new SystemMenuMaximize(getSite()))); 332 menuManager.add(new Separator("close")); menuManager.add(new UpdatingActionContributionItem(new SystemMenuClose( 334 getSite()))); 335 336 getSite().addSystemActions(menuManager); 337 } 338 339 348 private final int indexOf(IPresentablePart part) { 349 if (part == null) { 350 return tabFolder.getItemCount(); 351 } 352 353 CTabItem[] items = tabFolder.getItems(); 354 for (int idx = 0; idx < items.length; idx++) { 355 if (part == getPartForTab(items[idx])) { 356 return idx; 357 } 358 } 359 360 return items.length; 361 } 362 363 370 protected final CTabItem getTab(IPresentablePart part) { 371 CTabItem[] items = tabFolder.getItems(); 372 int idx = indexOf(part); 373 return idx < items.length ? items[idx] : null; 374 } 375 376 380 protected void childPropertyChanged(IPresentablePart part, int property) { 381 initTab(getTab(part), part); 382 } 383 384 protected final IPresentablePart getPartForTab(CTabItem item) { 385 return (IPresentablePart) item.getData(TAB_DATA); 386 } 387 388 protected CTabFolder getTabFolder() { 389 return tabFolder; 390 } 391 392 397 public boolean isDisposed() { 398 return tabFolder == null || tabFolder.isDisposed(); 399 } 400 401 404 private void setControlSize() { 405 if (current != null && tabFolder != null) { 406 current.setBounds(calculatePageBounds(tabFolder)); 407 } 408 } 409 410 416 public static Rectangle calculatePageBounds(CTabFolder folder) { 417 if (folder == null) { 418 return new Rectangle(0, 0, 0, 0); 419 } 420 421 Rectangle bounds = folder.getBounds(); 422 Rectangle offset = folder.getClientArea(); 423 bounds.x += offset.x; 424 bounds.y += offset.y; 425 bounds.width = offset.width; 426 bounds.height = offset.height; 427 return bounds; 428 } 429 430 435 public void dispose() { 436 if (isDisposed()) { 437 return; 438 } 439 440 tabFolder.getShell().removeShellListener(shellListener); 442 443 tabFolder.removeCTabFolderListener(closeListener); 445 446 PresentationUtil.removeDragListener(tabFolder, dragListener); 448 449 systemMenuManager.dispose(); 451 systemMenuManager.removeAll(); 452 453 tabFolder.dispose(); 455 tabFolder = null; 456 } 457 458 459 private int activeState = AS_INACTIVE; 460 461 465 private void updateGradient() { 466 467 if (isDisposed()) { 468 return; 469 } 470 471 Color fgColor; 472 Color[] bgColors; 473 int[] bgPercents; 474 boolean vertical = false; 475 if (activeState == AS_ACTIVE_FOCUS) { 476 if (getShellActivated()) { 477 fgColor = R21Colors.getSystemColor(SWT.COLOR_TITLE_FOREGROUND); 478 bgColors = R21Colors.getActiveEditorGradient(); 479 bgPercents = R21Colors.getActiveEditorGradientPercents(); 480 } else { 481 fgColor = R21Colors 482 .getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND); 483 bgColors = R21Colors.getDeactivatedEditorGradient(); 484 bgPercents = R21Colors.getDeactivatedEditorGradientPercents(); 485 } 486 487 } else if (activeState == AS_ACTIVE_NOFOCUS) { 488 fgColor = R21Colors.getSystemColor(SWT.COLOR_LIST_FOREGROUND); 489 bgColors = R21Colors.getActiveNoFocusEditorGradient(); 490 bgPercents = R21Colors.getActiveNoFocusEditorGradientPercents(); 491 } else { 492 fgColor = null; 493 bgColors = null; 494 bgPercents = null; 495 } 496 497 drawGradient(fgColor, bgColors, bgPercents, vertical); 498 } 499 500 508 protected void drawGradient(Color fgColor, Color[] bgColors, 509 int[] percentages, boolean vertical) { 510 tabFolder.setSelectionForeground(fgColor); 511 tabFolder.setSelectionBackground(bgColors, percentages); 512 tabFolder.update(); 513 } 514 515 518 boolean getShellActivated() { 519 Window window = getWindow(); 520 if (window instanceof WorkbenchWindow) { 521 return ((WorkbenchWindow) window).getShellActivated(); 522 } 523 return false; 524 } 525 526 531 public Window getWindow() { 532 Control ctrl = getControl(); 533 if (ctrl != null) { 534 Object data = ctrl.getShell().getData(); 535 if (data instanceof Window) { 536 return (Window) data; 537 } 538 } 539 return null; 540 } 541 542 549 private CTabItem createPartTab(IPresentablePart part, int tabIndex) { 550 CTabItem tabItem = new CTabItem(tabFolder, SWT.NONE, tabIndex); 551 tabItem.setData(TAB_DATA, part); 552 part.addPropertyListener(childPropertyChangeListener); 553 tabItem.addDisposeListener(tabDisposeListener); 554 initTab(tabItem, part); 555 return tabItem; 556 } 557 558 569 protected void initTab(CTabItem tabItem, IPresentablePart part) { 570 571 tabItem.setText(getLabelText(part, true, false)); 573 tabItem.setToolTipText(getLabelToolTipText(part)); 574 575 tabItem.setImage(getLabelImage(part)); 577 578 581 609 } 610 611 620 String getLabelText(IPresentablePart presentablePart, boolean dirtyLeft, 621 boolean includePath) { 622 String title = presentablePart.getName().trim(); 623 String text = title; 624 625 if (includePath) { 626 String titleTooltip = presentablePart.getTitleToolTip().trim(); 627 628 if (titleTooltip.endsWith(title)) { 629 titleTooltip = titleTooltip.substring(0, 630 titleTooltip.lastIndexOf(title)).trim(); 631 } 632 633 if (titleTooltip.endsWith("\\")) { titleTooltip = titleTooltip.substring(0, 635 titleTooltip.lastIndexOf("\\")).trim(); } 637 638 if (titleTooltip.endsWith("/")) { titleTooltip = titleTooltip.substring(0, 640 titleTooltip.lastIndexOf("/")).trim(); } 642 643 if (titleTooltip.length() >= 1) { 644 text += " - " + titleTooltip; } 646 } 647 648 if (presentablePart.isDirty()) { 649 if (dirtyLeft) { 650 text = "* " + text; } else { 652 text = text + " *"; } 654 } 655 656 return text; 657 } 658 659 665 Image getLabelImage(IPresentablePart presentablePart) { 666 return presentablePart.getTitleImage(); 667 } 668 669 675 String getLabelToolTipText(IPresentablePart presentablePart) { 676 return presentablePart.getTitleToolTip(); 677 } 678 679 685 public void addPart(IPresentablePart newPart, Object cookie) { 686 687 int idx; 688 689 if (cookie instanceof Integer ) { 690 idx = ((Integer ) cookie).intValue(); 691 } else { 692 idx = tabFolder.getItemCount(); 694 } 695 696 addPart(newPart, idx); 697 } 698 699 706 public void addPart(IPresentablePart newPart, int index) { 707 if (getTab(newPart) != null) { 709 return; 710 } 711 createPartTab(newPart, index); 712 713 } 715 716 721 public void removePart(IPresentablePart oldPart) { 722 if (current == oldPart) { 723 current = null; 724 } 725 726 CTabItem item = getTab(oldPart); 727 if (item == null) { 728 return; 729 } 730 oldPart.setVisible(false); 731 732 item.dispose(); 733 } 734 735 740 public void selectPart(IPresentablePart toSelect) { 741 if (toSelect == current) { 742 return; 743 } 744 745 IPresentablePart oldPart = current; 746 747 current = toSelect; 748 749 if (current != null) { 750 tabFolder.setSelection(indexOf(current)); 751 current.setVisible(true); 752 setControlSize(); 753 754 } 755 756 if (oldPart != null) { 757 oldPart.setVisible(false); 758 } 759 } 760 761 766 public void setBounds(Rectangle bounds) { 767 tabFolder.setBounds(bounds); 768 setControlSize(); 769 } 770 771 776 public Point computeMinimumSize() { 777 return Geometry.getSize(tabFolder.computeTrim(0, 0, 0, 0)); 778 } 779 780 785 public void setVisible(boolean isVisible) { 786 if (current != null) { 787 current.setVisible(isVisible); 788 } 789 790 getTabFolder().setVisible(isVisible); 791 } 792 793 798 public void setState(int state) { 799 } 802 803 808 public IMenuManager getSystemMenuManager() { 809 return systemMenuManager; 810 } 811 812 817 protected void showSystemMenu(Point point) { 818 Menu aMenu = systemMenuManager.createContextMenu(tabFolder.getParent()); 819 systemMenuManager.update(true); 820 aMenu.setLocation(point.x, point.y); 821 aMenu.setVisible(true); 822 } 823 824 829 public Control getControl() { 830 return tabFolder; 831 } 832 833 839 public StackDropResult dragOver(Control currentControl, Point location) { 840 841 Point localPos = tabFolder.toControl(location); 843 final CTabItem tabUnderPointer = tabFolder.getItem(localPos); 844 845 if (tabUnderPointer == null) { 848 return null; 849 } 850 851 int dragOverIndex = tabFolder.indexOf(tabUnderPointer); 853 854 return new StackDropResult(Geometry.toDisplay(tabFolder, 855 tabUnderPointer.getBounds()), new Integer (dragOverIndex)); 856 } 857 858 863 public void showSystemMenu() { 864 if (null != current) { 865 CTabItem item = getTab(current); 867 getSite().selectPart(getCurrentPart()); 868 Rectangle bounds = item.getBounds(); 869 int y = bounds.height; 870 if (getTabFolder().getTabPosition() == SWT.BOTTOM) { 871 y += bounds.y; 872 } 873 showSystemMenu(getTabFolder().toDisplay(bounds.x, y)); 874 } 875 } 876 877 882 public void showPaneMenu() { 883 IPartMenu menu = getPartMenu(); 884 885 if (null != menu) { 886 CTabItem tab = getTab(getCurrentPart()); 887 888 if (null != tab && null != tab.getControl()) { 889 Rectangle bounds = DragUtil.getDisplayBounds(tab.getControl()); 890 menu.showMenu(new Point(bounds.x, bounds.y + bounds.height)); 891 } 892 } 893 } 894 895 901 protected IPartMenu getPartMenu() { 902 IPresentablePart part = getCurrentPart(); 903 if (part == null) { 904 return null; 905 } 906 907 return part.getMenu(); 908 } 909 910 915 public Control[] getTabList(IPresentablePart part) { 916 ArrayList list = new ArrayList (); 917 if (getControl() != null) { 918 list.add(getControl()); 919 } 920 if (part.getToolBar() != null) { 921 list.add(part.getToolBar()); 922 } 923 if (part.getControl() != null) { 924 list.add(part.getControl()); 925 } 926 return (Control[]) list.toArray(new Control[list.size()]); 927 } 928 929 934 public IPresentablePart getCurrentPart() { 935 return current; 936 } 937 938 protected String getPaneName() { 939 return R21PresentationMessages.getString("EditorPane.moveEditor"); } 941 942 947 public void setActive(int newState) { 948 activeState = newState; 949 updateGradient(); 950 } 951 952 958 public void restoreState(IPresentationSerializer serializer, IMemento savedState) { 959 IMemento[] parts = savedState.getChildren(IWorkbenchConstants.TAG_PART); 960 961 for (int idx = 0; idx < parts.length; idx++) { 962 String id = parts[idx].getString(IWorkbenchConstants.TAG_ID); 963 964 if (id != null) { 965 IPresentablePart part = serializer.getPart(id); 966 967 if (part != null) { 968 addPart(part, tabFolder.getItemCount()); 969 } 970 } 971 } 972 } 973 974 975 978 public void saveState(IPresentationSerializer context, IMemento memento) { 979 super.saveState(context, memento); 980 981 List parts = getPresentableParts(); 982 983 Iterator iter = parts.iterator(); 984 while (iter.hasNext()) { 985 IPresentablePart next = (IPresentablePart)iter.next(); 986 987 IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_PART); 988 childMem.putString(IWorkbenchConstants.TAG_ID, context.getId(next)); 989 } 990 } 991 992 995 private List getPresentableParts() { 996 Assert.isTrue(!isDisposed()); 997 998 CTabItem[] items = tabFolder.getItems(); 999 List result = new ArrayList (items.length); 1000 1001 for (int idx = 0; idx < tabFolder.getItemCount(); idx++) { 1002 result.add(getPartForTab(items[idx])); 1003 } 1004 1005 return result; 1006 } 1007 } 1008 | Popular Tags |