1 14 package org.eclipse.ui.internal; 15 16 import java.util.ArrayList ; 17 18 import org.eclipse.core.runtime.Assert; 19 import org.eclipse.jface.util.Geometry; 20 import org.eclipse.swt.SWT; 21 import org.eclipse.swt.events.ControlAdapter; 22 import org.eclipse.swt.events.ControlEvent; 23 import org.eclipse.swt.events.ControlListener; 24 import org.eclipse.swt.graphics.Cursor; 25 import org.eclipse.swt.graphics.Point; 26 import org.eclipse.swt.graphics.Rectangle; 27 import org.eclipse.swt.widgets.Composite; 28 import org.eclipse.swt.widgets.Control; 29 import org.eclipse.ui.IPageLayout; 30 import org.eclipse.ui.IViewReference; 31 import org.eclipse.ui.internal.dnd.AbstractDropTarget; 32 import org.eclipse.ui.internal.dnd.DragUtil; 33 import org.eclipse.ui.internal.dnd.IDragOverListener; 34 import org.eclipse.ui.internal.dnd.IDropTarget; 35 import org.eclipse.ui.internal.dnd.SwtUtil; 36 37 44 public abstract class PartSashContainer extends LayoutPart implements 45 ILayoutContainer, IDragOverListener { 46 47 protected Composite parent; 48 49 protected ControlListener resizeListener; 50 51 protected LayoutTree root; 52 53 private Composite parentWidget; 54 55 private LayoutPart zoomedPart; 56 57 protected WorkbenchPage page; 58 59 boolean active = false; 60 boolean layoutDirty = false; 61 62 63 protected ArrayList children = new ArrayList (); 64 65 private SashContainerDropTarget dropTarget; 66 67 protected static class RelationshipInfo { 68 protected LayoutPart part; 69 70 protected LayoutPart relative; 71 72 protected int relationship; 73 74 78 protected int left; 79 80 84 protected int right; 85 86 94 public float getRatio() { 95 int total = left + right; 96 if (total > 0) { 97 return (float) left / (float) total; 98 } 99 100 return 0.5f; 101 } 102 } 103 104 private class SashContainerDropTarget extends AbstractDropTarget { 105 private int side; 106 107 private int cursor; 108 109 private LayoutPart targetPart; 110 111 private LayoutPart sourcePart; 112 113 public SashContainerDropTarget(LayoutPart sourcePart, int side, int cursor, LayoutPart targetPart) { 114 this.setTarget(sourcePart, side, cursor, targetPart); 115 } 116 117 public void setTarget(LayoutPart sourcePart, int side, int cursor, LayoutPart targetPart) { 118 this.side = side; 119 this.targetPart = targetPart; 120 this.sourcePart = sourcePart; 121 this.cursor = cursor; 122 } 123 124 public void drop() { 125 if (side != SWT.NONE) { 126 LayoutPart visiblePart = sourcePart; 127 128 if (sourcePart instanceof PartStack) { 129 visiblePart = getVisiblePart((PartStack) sourcePart); 130 } 131 132 dropObject(getVisibleParts(sourcePart), visiblePart, 133 targetPart, side); 134 } 135 } 136 137 public Cursor getCursor() { 138 return DragCursors.getCursor(DragCursors 139 .positionToDragCursor(cursor)); 140 } 141 142 public Rectangle getSnapRectangle() { 143 Rectangle targetBounds; 144 145 if (targetPart != null) { 146 targetBounds = DragUtil.getDisplayBounds(targetPart 147 .getControl()); 148 } else { 149 targetBounds = DragUtil.getDisplayBounds(getParent()); 150 } 151 152 if (side == SWT.CENTER || side == SWT.NONE) { 153 return targetBounds; 154 } 155 156 int distance = Geometry.getDimension(targetBounds, !Geometry 157 .isHorizontal(side)); 158 159 return Geometry.getExtrudedEdge(targetBounds, 160 (int) (distance * getDockingRatio(sourcePart, targetPart)), 161 side); 162 } 163 } 164 165 public PartSashContainer(String id, final WorkbenchPage page, Composite parentWidget) { 166 super(id); 167 this.page = page; 168 this.parentWidget = parentWidget; 169 resizeListener = new ControlAdapter() { 170 public void controlResized(ControlEvent e) { 171 resizeSashes(); 172 } 173 }; 174 } 175 176 179 public boolean childObscuredByZoom(LayoutPart toTest) { 180 LayoutPart zoomPart = getZoomedPart(); 181 182 if (zoomPart != null && toTest != zoomPart) { 183 return true; 184 } 185 return isObscuredByZoom(); 186 } 187 188 195 private PartPane[] getVisibleParts(LayoutPart pane) { 196 if (pane instanceof PartPane) { 197 return new PartPane[] { (PartPane) pane }; 198 } else if (pane instanceof PartStack) { 199 PartStack stack = (PartStack) pane; 200 201 LayoutPart[] children = stack.getChildren(); 202 ArrayList result = new ArrayList (children.length); 203 for (int idx = 0; idx < children.length; idx++) { 204 LayoutPart next = children[idx]; 205 if (next instanceof PartPane) { 206 result.add(next); 207 } 208 } 209 210 return (PartPane[]) result.toArray(new PartPane[result.size()]); 211 } 212 213 return new PartPane[0]; 214 } 215 216 219 public void findSashes(LayoutPart pane, PartPane.Sashes sashes) { 220 if (root == null) { 221 return; 222 } 223 LayoutTree part = root.find(pane); 224 if (part == null) { 225 return; 226 } 227 part.findSashes(sashes); 228 } 229 230 233 public void add(LayoutPart child) { 234 if (child == null) { 235 return; 236 } 237 238 addEnhanced(child, SWT.RIGHT, 0.5f, findBottomRight()); 239 } 240 241 255 void addEnhanced(LayoutPart child, int swtDirectionConstant, 256 float ratioForNewPart, LayoutPart relative) { 257 int relativePosition = PageLayout 258 .swtConstantToLayoutPosition(swtDirectionConstant); 259 260 float ratioForUpperLeftPart; 261 262 if (relativePosition == IPageLayout.RIGHT 263 || relativePosition == IPageLayout.BOTTOM) { 264 ratioForUpperLeftPart = 1.0f - ratioForNewPart; 265 } else { 266 ratioForUpperLeftPart = ratioForNewPart; 267 } 268 269 add(child, relativePosition, ratioForUpperLeftPart, relative); 270 } 271 272 281 public void add(LayoutPart child, int relationship, float ratio, 282 LayoutPart relative) { 283 boolean isHorizontal = (relationship == IPageLayout.LEFT || relationship == IPageLayout.RIGHT); 284 285 LayoutTree node = null; 286 if (root != null && relative != null) { 287 node = root.find(relative); 288 } 289 290 Rectangle bounds; 291 if (getParent() == null) { 292 Control control = getPage().getClientComposite(); 293 if (control != null && !control.isDisposed()) { 294 bounds = control.getBounds(); 295 } else { 296 bounds = new Rectangle(0, 0, 800, 600); 297 } 298 bounds.x = 0; 299 bounds.y = 0; 300 } else { 301 bounds = getBounds(); 302 } 303 304 int totalSize = measureTree(bounds, node, isHorizontal); 305 306 int left = (int) (totalSize * ratio); 307 int right = totalSize - left; 308 309 add(child, relationship, left, right, relative); 310 } 311 312 static int measureTree(Rectangle outerBounds, LayoutTree toMeasure, 313 boolean horizontal) { 314 if (toMeasure == null) { 315 return Geometry.getDimension(outerBounds, horizontal); 316 } 317 318 LayoutTreeNode parent = toMeasure.getParent(); 319 if (parent == null) { 320 return Geometry.getDimension(outerBounds, horizontal); 321 } 322 323 if (parent.getSash().isHorizontal() == horizontal) { 324 return measureTree(outerBounds, parent, horizontal); 325 } 326 327 boolean isLeft = parent.isLeftChild(toMeasure); 328 329 LayoutTree otherChild = parent.getChild(!isLeft); 330 if (otherChild.isVisible()) { 331 int left = parent.getSash().getLeft(); 332 int right = parent.getSash().getRight(); 333 int childSize = isLeft ? left : right; 334 335 int bias = parent.getCompressionBias(); 336 337 if (isLeft) { 339 bias = -bias; 340 } 341 342 if (bias == 1) { 343 return childSize; 345 } else if (bias == -1) { 346 347 return measureTree(outerBounds, parent, horizontal) 350 - (left + right - childSize); 351 } 352 353 return measureTree(outerBounds, parent, horizontal) * childSize 355 / (left + right); 356 } 357 358 return measureTree(outerBounds, parent, horizontal); 359 } 360 361 protected void addChild(RelationshipInfo info) { 362 LayoutPart child = info.part; 363 364 children.add(child); 365 366 if (root == null) { 367 root = new LayoutTree(child); 368 } else { 369 int vertical = (info.relationship == IPageLayout.LEFT || info.relationship == IPageLayout.RIGHT) ? SWT.VERTICAL 371 : SWT.HORIZONTAL; 372 boolean left = info.relationship == IPageLayout.LEFT 373 || info.relationship == IPageLayout.TOP; 374 LayoutPartSash sash = new LayoutPartSash(this, vertical); 375 sash.setSizes(info.left, info.right); 376 if ((parent != null) && !(child instanceof PartPlaceholder)) { 377 sash.createControl(parent); 378 } 379 root = root.insert(child, left, sash, info.relative); 380 } 381 382 childAdded(child); 383 384 if (active) { 385 child.createControl(parent); 386 child.setVisible(true); 387 child.setContainer(this); 388 resizeChild(child); 389 } 390 391 } 392 393 402 void addChildForPlaceholder(LayoutPart child, LayoutPart placeholder) { 403 RelationshipInfo newRelationshipInfo = new RelationshipInfo(); 404 newRelationshipInfo.part = child; 405 if (root != null) { 406 newRelationshipInfo.relationship = IPageLayout.RIGHT; 407 newRelationshipInfo.relative = root.findBottomRight(); 408 newRelationshipInfo.left = 200; 409 newRelationshipInfo.right = 200; 410 } 411 412 RelationshipInfo[] relationships = computeRelation(); 414 for (int i = 0; i < relationships.length; i++) { 415 RelationshipInfo info = relationships[i]; 416 if (info.part == placeholder) { 417 newRelationshipInfo.left = info.left; 418 newRelationshipInfo.right = info.right; 419 newRelationshipInfo.relationship = info.relationship; 420 newRelationshipInfo.relative = info.relative; 421 } 422 } 423 424 addChild(newRelationshipInfo); 425 flushLayout(); 426 } 427 428 431 public boolean allowsBorder() { 432 return true; 433 } 434 435 441 protected void childAdded(LayoutPart child) { 442 if (isDeferred()) { 443 child.deferUpdates(true); 444 } 445 } 446 447 453 protected void childRemoved(LayoutPart child) { 454 if (isDeferred()) { 455 child.deferUpdates(false); 456 } 457 } 458 459 463 public RelationshipInfo[] computeRelation() { 464 LayoutTree treeRoot = root; 465 ArrayList list = new ArrayList (); 466 if (treeRoot == null) { 467 return new RelationshipInfo[0]; 468 } 469 RelationshipInfo r = new RelationshipInfo(); 470 r.part = treeRoot.computeRelation(list); 471 list.add(0, r); 472 RelationshipInfo[] result = new RelationshipInfo[list.size()]; 473 list.toArray(result); 474 return result; 475 } 476 477 public void setActive(boolean isActive) { 478 if (isActive == active) { 479 return; 480 } 481 482 active = isActive; 483 484 ArrayList children = (ArrayList ) this.children.clone(); 485 for (int i = 0, length = children.size(); i < length; i++) { 486 LayoutPart child = (LayoutPart) children.get(i); 487 488 if (child instanceof PartStack) { 489 PartStack stack = (PartStack) child; 490 stack.setActive(isActive); 491 } 492 } 493 494 if (isActive) { 495 496 createControl(parentWidget); 497 498 parent.addControlListener(resizeListener); 499 500 DragUtil.addDragTarget(parent, this); 501 DragUtil.addDragTarget(parent.getShell(), this); 502 503 for (int i = 0, length = children.size(); i < length; i++) { 505 LayoutPart child = (LayoutPart) children.get(i); 506 child.setContainer(this); 507 child.setVisible(zoomedPart == null || child == zoomedPart); 508 if (!(child instanceof PartStack)) { 509 if (root != null) { 510 LayoutTree node = root.find(child); 511 if (node != null) { 512 node.flushCache(); 513 } 514 } 515 } 516 } 517 518 if (root != null) { 519 if (!isZoomed()) { 521 root.createControl(parent); 522 } 523 } 524 525 resizeSashes(); 526 } else { 527 DragUtil.removeDragTarget(parent, this); 528 DragUtil.removeDragTarget(parent.getShell(), this); 529 530 if (resizeListener != null && parent != null) { 532 parent.removeControlListener(resizeListener); 533 } 534 535 if (children != null) { 536 for (int i = 0, length = children.size(); i < length; i++) { 537 LayoutPart child = (LayoutPart) children.get(i); 538 child.setContainer(null); 539 if (child instanceof PartStack) { 540 child.setVisible(false); 541 } 542 } 543 } 544 545 disposeSashes(); 546 547 } 549 } 550 551 554 public void createControl(Composite parentWidget) { 555 if (this.parent != null) { 556 return; 557 } 558 559 parent = createParent(parentWidget); 560 561 ArrayList children = (ArrayList ) this.children.clone(); 562 for (int i = 0, length = children.size(); i < length; i++) { 563 LayoutPart child = (LayoutPart) children.get(i); 564 child.createControl(parent); 565 } 566 567 } 568 569 574 protected abstract Composite createParent(Composite parentWidget); 575 576 579 public void dispose() { 580 if (parent == null) { 581 return; 582 } 583 584 if (children != null) { 585 for (int i = 0, length = children.size(); i < length; i++) { 586 LayoutPart child = (LayoutPart) children.get(i); 587 588 if (child instanceof PartStack) { 591 child.dispose(); 592 } 593 } 594 } 595 disposeParent(); 596 this.parent = null; 597 } 598 599 603 protected abstract void disposeParent(); 604 605 608 public void disposeSashes() { 609 if (root != null) { 610 root.disposeSashes(); 611 } 612 } 613 614 617 public void setVisible(boolean makeVisible) { 618 619 if (makeVisible == getVisible()) { 620 return; 621 } 622 623 if (!SwtUtil.isDisposed(this.parent)) { 624 this.parent.setEnabled(makeVisible); 625 } 626 super.setVisible(makeVisible); 627 628 ArrayList children = (ArrayList ) this.children.clone(); 629 for (int i = 0, length = children.size(); i < length; i++) { 630 LayoutPart child = (LayoutPart) children.get(i); 631 child.setVisible(makeVisible && (zoomedPart == null || child == zoomedPart)); 632 } 633 } 634 635 638 public LayoutPart findBottomRight() { 639 if (root == null) { 640 return null; 641 } 642 return root.findBottomRight(); 643 } 644 645 648 public Rectangle getBounds() { 649 return this.parent.getBounds(); 650 } 651 652 655 public LayoutPart[] getChildren() { 656 LayoutPart[] result = new LayoutPart[children.size()]; 657 children.toArray(result); 658 return result; 659 } 660 661 664 public Control getControl() { 665 return this.parent; 666 } 667 668 public LayoutTree getLayoutTree() { 669 return root; 670 } 671 672 677 public WorkbenchPage getPage() { 678 return page; 679 } 680 681 685 public Composite getParent() { 686 return parent; 687 } 688 689 protected boolean isChild(LayoutPart part) { 690 return children.indexOf(part) >= 0; 691 } 692 693 696 public boolean isZoomed() { 697 return (zoomedPart != null); 698 } 699 700 703 public void resizeChild(LayoutPart childThatChanged) { 704 if (root != null) { 705 LayoutTree tree = root.find(childThatChanged); 706 707 if (tree != null) { 708 tree.flushCache(); 709 } 710 } 711 712 flushLayout(); 713 714 } 715 716 719 public void remove(LayoutPart child) { 720 if (child == getZoomedPart()) { 721 childRequestZoomOut(); 722 } 723 724 if (!isChild(child)) { 725 return; 726 } 727 728 children.remove(child); 729 if (root != null) { 730 root = root.remove(child); 731 } 732 childRemoved(child); 733 734 if (active) { 735 child.setVisible(false); 736 child.setContainer(null); 737 flushLayout(); 738 } 739 } 740 741 744 public void flushLayout() { 745 layoutDirty = true; 746 super.flushLayout(); 747 748 if (layoutDirty) { 749 resizeSashes(); 750 } 751 } 752 753 756 public void replace(LayoutPart oldChild, LayoutPart newChild) { 757 758 if (!isChild(oldChild)) { 759 return; 760 } 761 762 if (oldChild == getZoomedPart()) { 763 if (newChild instanceof PartPlaceholder) { 764 childRequestZoomOut(); 765 } else { 766 zoomedPart.setZoomed(false); 767 zoomedPart = newChild; 768 zoomedPart.setZoomed(true); 769 } 770 } 771 772 children.remove(oldChild); 773 children.add(newChild); 774 775 childAdded(newChild); 776 777 if (root != null) { 778 LayoutTree leaf = null; 779 780 leaf = root.find(oldChild); 781 if (leaf != null) { 782 leaf.setPart(newChild); 783 } 784 } 785 786 childRemoved(oldChild); 787 if (active) { 788 oldChild.setVisible(false); 789 oldChild.setContainer(null); 790 newChild.createControl(parent); 791 newChild.setContainer(this); 792 newChild.setVisible(zoomedPart == null || zoomedPart == newChild); 793 resizeChild(newChild); 794 } 795 } 796 797 private void resizeSashes() { 798 layoutDirty = false; 799 if (!active) { 800 return; 801 } 802 803 if (isZoomed()) { 804 getZoomedPart().setBounds(parent.getClientArea()); 805 } else { 806 if (root != null) { 807 root.setBounds(parent.getClientArea()); 808 } 809 } 810 } 811 812 820 public int computePreferredSize(boolean width, int availableParallel, int availablePerpendicular, int preferredParallel) { 821 if (isZoomed()) { 822 return getZoomedPart().computePreferredSize(width, availableParallel, availablePerpendicular, preferredParallel); 823 } 824 825 if (root != null) { 826 return root.computePreferredSize(width, availableParallel, availablePerpendicular, preferredParallel); 827 } 828 829 return preferredParallel; 830 } 831 832 public int getSizeFlags(boolean width) { 833 if (isZoomed()) { 834 return getZoomedPart().getSizeFlags(width); 835 } 836 837 if (root != null) { 838 return root.getSizeFlags(width); 839 } 840 841 return 0; 842 } 843 844 847 public void setBounds(Rectangle r) { 848 this.parent.setBounds(r); 849 } 850 851 861 private void zoomIn(LayoutPart part) { 862 if (isZoomed()) { 864 return; 865 } 866 867 root.disposeSashes(); 869 870 LayoutPart[] children = getChildren(); 872 for (int i = 0; i < children.length; i++) { 873 LayoutPart child = children[i]; 874 child.setVisible(child == part); 875 } 876 877 zoomedPart = part; 878 879 part.setZoomed(true); 881 882 layoutDirty = true; 884 } 885 886 892 public LayoutPart getZoomedPart() { 893 return zoomedPart; 894 } 895 896 public void childRequestZoomIn(LayoutPart toZoom) { 897 if (!SwtUtil.isDisposed(this.parent)) { 898 this.parent.setRedraw(false); 899 } 900 try { 901 zoomIn(toZoom); 902 903 requestZoomIn(); 904 905 if (layoutDirty) { 906 resizeSashes(); 907 } 908 } finally { 909 if (!SwtUtil.isDisposed(this.parent)) { 910 this.parent.setRedraw(true); 911 } 912 } 913 } 914 915 public void childRequestZoomOut() { 916 if (!SwtUtil.isDisposed(this.parent)) { 917 this.parent.setRedraw(false); 918 } 919 try { 920 zoomOut(); 921 922 requestZoomOut(); 923 924 if (layoutDirty) { 925 resizeSashes(); 926 } 927 } finally { 928 if (!SwtUtil.isDisposed(this.parent)) { 929 this.parent.setRedraw(true); 930 } 931 } 932 } 933 934 937 public void setZoomed(boolean isZoomed) { 938 if (!isZoomed) { 939 zoomOut(); 940 } else { 941 if (!isZoomed()) { 942 LayoutPart toZoom = pickPartToZoom(); 943 944 if (toZoom != null) { 945 zoomIn(toZoom); 946 } 947 } 948 } 949 super.setZoomed(isZoomed); 950 } 951 952 public LayoutPart pickPartToZoom() { 953 return findBottomRight(); 954 } 955 956 963 private void zoomOut() { 964 if (!isZoomed()) { 966 return; 967 } 968 969 LayoutPart zoomedPart = this.zoomedPart; 970 this.zoomedPart = null; 971 zoomedPart.setZoomed(false); 973 974 LayoutPart[] children = getChildren(); 976 for (int i = 0; i < children.length; i++) { 977 LayoutPart child = children[i]; 978 979 child.setVisible(true); 980 } 981 982 root.createControl(getParent()); 984 985 LayoutTree node = root.find(zoomedPart); 987 node.flushCache(); 988 989 layoutDirty = true; 990 } 991 992 995 public IDropTarget drag(Control currentControl, Object draggedObject, 996 Point position, Rectangle dragRectangle) { 997 if (!(draggedObject instanceof LayoutPart)) { 998 return null; 999 } 1000 1001 final LayoutPart sourcePart = (LayoutPart) draggedObject; 1002 1003 if (!isStackType(sourcePart) && !isPaneType(sourcePart)) { 1004 return null; 1005 } 1006 1007 boolean differentWindows = sourcePart.getWorkbenchWindow() != getWorkbenchWindow(); 1008 boolean editorDropOK = ((sourcePart instanceof EditorPane) && 1009 sourcePart.getWorkbenchWindow().getWorkbench() == 1010 getWorkbenchWindow().getWorkbench()); 1011 if (differentWindows && !editorDropOK) { 1012 return null; 1013 } 1014 1015 Rectangle containerBounds = DragUtil.getDisplayBounds(parent); 1016 LayoutPart targetPart = null; 1017 ILayoutContainer sourceContainer = isStackType(sourcePart) ? (ILayoutContainer) sourcePart 1018 : sourcePart.getContainer(); 1019 1020 if (getVisibleChildrenCount(this) == 0) { 1022 return createDropTarget(sourcePart, SWT.CENTER, SWT.CENTER, null); 1023 } 1024 1025 if (containerBounds.contains(position)) { 1026 1027 if (root != null) { 1028 targetPart = root.findPart(parent.toControl(position)); 1029 } 1030 1031 if (targetPart != null) { 1032 final Control targetControl = targetPart.getControl(); 1033 1034 final Rectangle targetBounds = DragUtil 1035 .getDisplayBounds(targetControl); 1036 1037 int side = Geometry.getClosestSide(targetBounds, position); 1038 int distance = Geometry.getDistanceFromEdge(targetBounds, position, side); 1039 1040 boolean standalone = (isStackType(sourcePart) 1042 && ((PartStack) sourcePart).isStandalone()) 1043 || (isPaneType(sourcePart) 1044 && ((PartPane) sourcePart).getStack()!=null 1045 && ((PartPane) sourcePart).getStack().isStandalone()); 1046 1047 if (differentWindows && targetPart instanceof EditorStack) { 1049 IDropTarget target = targetPart.getDropTarget(draggedObject, position); 1050 return target; 1051 } 1052 1053 if (distance >= 5 && !standalone) { 1055 IDropTarget target = targetPart.getDropTarget(draggedObject, position); 1057 if (target != null) { 1058 return target; 1059 } 1060 } 1061 1062 if (distance > 30 && isStackType(targetPart) && !standalone) { 1063 if (targetPart instanceof ILayoutContainer) { 1064 ILayoutContainer targetContainer = (ILayoutContainer)targetPart; 1065 if (targetContainer.allowsAdd(sourcePart)) { 1066 side = SWT.CENTER; 1067 } 1068 } 1069 } 1070 1071 1073 1077 boolean pointlessDrop = isZoomed(); 1078 1079 if (sourcePart == targetPart) { 1080 pointlessDrop = true; 1081 } 1082 1083 if ((sourceContainer != null) 1084 && (sourceContainer == targetPart) 1085 && getVisibleChildrenCount(sourceContainer) <= 1) { 1086 pointlessDrop = true; 1087 } 1088 1089 if (side == SWT.CENTER 1090 && sourcePart.getContainer() == targetPart) { 1091 pointlessDrop = true; 1092 } 1093 1094 int cursor = side; 1095 1096 if (pointlessDrop) { 1097 side = SWT.NONE; 1098 cursor = SWT.CENTER; 1099 } 1100 1101 return createDropTarget(sourcePart, side, cursor, targetPart); 1102 } 1103 } else { 1104 if (differentWindows) 1106 return null; 1107 1108 int side = Geometry.getClosestSide(containerBounds, position); 1109 1110 boolean pointlessDrop = isZoomed(); 1111 1112 if ((isStackType(sourcePart) && sourcePart.getContainer() == this) 1113 || (sourcePart.getContainer() != null 1114 && isPaneType(sourcePart) 1115 && getVisibleChildrenCount(sourcePart.getContainer()) <= 1) 1116 && ((LayoutPart)sourcePart.getContainer()).getContainer() == this) { 1117 if (root == null || getVisibleChildrenCount(this) <= 1) { 1118 pointlessDrop = true; 1119 } 1120 } 1121 1122 int cursor = Geometry.getOppositeSide(side); 1123 1124 if (pointlessDrop) { 1125 side = SWT.NONE; 1126 } 1127 1128 return createDropTarget(sourcePart, side, cursor, null); 1129 } 1130 1131 return null; 1132 } 1133 1134 1142 private SashContainerDropTarget createDropTarget(final LayoutPart sourcePart, int side, int cursor, LayoutPart targetPart) { 1143 if (dropTarget == null) { 1144 dropTarget = new SashContainerDropTarget(sourcePart, side, cursor, 1145 targetPart); 1146 } else { 1147 dropTarget.setTarget(sourcePart, side, cursor, targetPart); 1148 } 1149 return dropTarget; 1150 } 1151 1152 1159 public abstract boolean isStackType(LayoutPart toTest); 1160 1161 public abstract boolean isPaneType(LayoutPart toTest); 1162 1163 1166 protected void dropObject(PartPane[] toDrop, LayoutPart visiblePart, 1167 LayoutPart targetPart, int side) { 1168 getControl().setRedraw(false); 1169 1170 if (targetPart == null && side == SWT.CENTER) { 1177 side = SWT.BOTTOM; 1178 } 1179 1180 if (side == SWT.CENTER) { 1181 if (isStackType(targetPart)) { 1182 PartStack stack = (PartStack) targetPart; 1183 for (int idx = 0; idx < toDrop.length; idx++) { 1184 PartPane next = toDrop[idx]; 1185 stack(next, stack); 1186 } 1187 } 1188 } else { 1189 PartStack newPart = createStack(); 1190 1191 if (toDrop.length == 1 && toDrop[0].getStack()!=null) { 1194 toDrop[0].getStack().copyAppearanceProperties(newPart); 1195 } 1196 1197 for (int idx = 0; idx < toDrop.length; idx++) { 1198 PartPane next = toDrop[idx]; 1199 stack(next, newPart); 1200 } 1201 1202 addEnhanced(newPart, side, getDockingRatio(newPart, targetPart), 1203 targetPart); 1204 } 1205 1206 if (visiblePart != null) { 1207 setVisiblePart(visiblePart.getContainer(), visiblePart); 1208 } 1209 1210 getControl().setRedraw(true); 1211 1212 if (visiblePart != null) { 1213 visiblePart.setFocus(); 1214 } 1215 } 1216 1217 protected abstract PartStack createStack(); 1218 1219 public void stack(LayoutPart newPart, ILayoutContainer container) { 1220 getControl().setRedraw(false); 1221 1222 Perspective persp = page.getActivePerspective(); 1224 PerspectiveHelper pres = (persp != null) ? persp.getPresentation() : null; 1225 if (pres != null && newPart instanceof ViewPane) { 1226 ViewPane vp = (ViewPane) newPart; 1227 IViewReference vRef = vp.getViewReference(); 1228 LayoutPart fpp = pres.findPart(vRef.getId(), vRef.getSecondaryId()); 1229 1230 if (fpp != null) { 1231 derefPart(newPart); 1233 } 1234 } 1235 else { 1236 derefPart(newPart); 1238 } 1239 1240 newPart.reparent(getParent()); 1242 container.add(newPart); 1243 getControl().setRedraw(true); 1244 1245 } 1246 1247 1251 protected abstract void setVisiblePart(ILayoutContainer container, 1252 LayoutPart visiblePart); 1253 1254 1258 protected abstract LayoutPart getVisiblePart(ILayoutContainer container); 1259 1260 1263 protected void derefPart(LayoutPart sourcePart) { 1264 ILayoutContainer container = sourcePart.getContainer(); 1265 if (container != null) { 1266 container.remove(sourcePart); 1267 } 1268 1269 if (container instanceof LayoutPart) { 1270 if (isStackType((LayoutPart) container)) { 1271 PartStack stack = (PartStack) container; 1272 if (stack.getChildren().length == 0) { 1273 remove(stack); 1274 stack.dispose(); 1275 } 1276 } 1277 } 1278 } 1279 1280 protected int getVisibleChildrenCount(ILayoutContainer container) { 1281 if (container == null) { 1283 return 0; 1284 } 1285 1286 LayoutPart[] children = container.getChildren(); 1287 1288 int count = 0; 1289 for (int idx = 0; idx < children.length; idx++) { 1290 if (!(children[idx] instanceof PartPlaceholder)) { 1291 count++; 1292 } 1293 } 1294 1295 return count; 1296 } 1297 1298 protected float getDockingRatio(LayoutPart dragged, LayoutPart target) { 1299 return 0.5f; 1300 } 1301 1302 1312 public void describeLayout(StringBuffer buf) { 1313 if (root == null) { 1314 return; 1315 } 1316 1317 if (isZoomed()) { 1318 buf.append("zoomed "); root.describeLayout(buf); 1320 } else { 1321 buf.append("layout "); root.describeLayout(buf); 1323 } 1324 } 1325 1326 1335 void add(LayoutPart child, int relationship, int left, int right, 1336 LayoutPart relative) { 1337 1338 if (child == null) { 1339 return; 1340 } 1341 if (relative != null && !isChild(relative)) { 1342 return; 1343 } 1344 if (relationship < IPageLayout.LEFT 1345 || relationship > IPageLayout.BOTTOM) { 1346 relationship = IPageLayout.LEFT; 1347 } 1348 1349 RelationshipInfo info = new RelationshipInfo(); 1351 info.part = child; 1352 info.relationship = relationship; 1353 info.left = left; 1354 info.right = right; 1355 info.relative = relative; 1356 addChild(info); 1357 } 1358 1359 1362 public boolean childIsZoomed(LayoutPart toTest) { 1363 return toTest == getZoomedPart(); 1364 } 1365 1366 1369 public boolean allowsAutoFocus() { 1370 return true; 1371 } 1372 1373 1376 protected void startDeferringEvents() { 1377 super.startDeferringEvents(); 1378 1379 LayoutPart[] deferredChildren = (LayoutPart[]) children.toArray(new LayoutPart[children.size()]); 1380 for (int i = 0; i < deferredChildren.length; i++) { 1381 LayoutPart child = deferredChildren[i]; 1382 1383 child.deferUpdates(true); 1384 } 1385 } 1386 1387 1390 protected void handleDeferredEvents() { 1391 super.handleDeferredEvents(); 1392 1393 LayoutPart[] deferredChildren = (LayoutPart[]) children.toArray(new LayoutPart[children.size()]); 1394 for (int i = 0; i < deferredChildren.length; i++) { 1395 LayoutPart child = deferredChildren[i]; 1396 1397 child.deferUpdates(false); 1398 } 1399 } 1400 1401 1404 public void testInvariants() { 1405 super.testInvariants(); 1406 1407 if (getContainer() != null) { 1410 Assert.isTrue((getZoomedPart() != null) == (getContainer().childIsZoomed(this))); 1411 } 1412 1413 LayoutPart[] childArray = getChildren(); 1414 1415 for (int idx = 0; idx < childArray.length; idx++) { 1416 childArray[idx].testInvariants(); 1417 } 1418 1419 if (isZoomed()) { 1421 Assert.isTrue(children.contains(zoomedPart)); 1422 } 1423 } 1424} 1425 | Popular Tags |