- Timestamp:
- 07/11/08 14:13:14 (4 months ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/com/itmill/toolkit/terminal/gwt/client/ui/IOrderedLayout.java
r5079 r5093 126 126 * @param newOrientationMode 127 127 */ 128 private void rebuildRootDomStructure( boolean forceUpdate) {128 private void rebuildRootDomStructure(int oldOrientationMode) { 129 129 130 130 // Should we have table as a root element? … … 132 132 133 133 // Already in correct mode? 134 if ( !forceUpdate && newTableMode == tableMode) {134 if (oldOrientationMode == orientationMode && newTableMode == tableMode) { 135 135 return; 136 136 } … … 141 141 if (tableMode) { 142 142 Element tmp = DOM.createDiv(); 143 final String structure = "<table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr></tr></tbody></table>"; 143 final String structure = "<table cellspacing=\"0\" cellpadding=\"0\"><tbody>" 144 + (orientationMode == ORIENTATION_HORIZONTAL ? "<tr></tr>" 145 : "") + "</tbody></table>"; 144 146 DOM.setInnerHTML(tmp, structure); 145 147 root = DOM.getFirstChild(tmp); 146 148 DOM.removeChild(tmp, root); 147 wrappedChildContainer = DOM.getFirstChild(DOM.getFirstChild(root)); 149 // set TBODY to be the wrappedChildContainer 150 wrappedChildContainer = DOM.getFirstChild(root); 151 // In case of horizontal layouts, we must user TR instead of TBODY 152 if (orientationMode == ORIENTATION_HORIZONTAL) { 153 wrappedChildContainer = DOM 154 .getFirstChild(wrappedChildContainer); 155 } 148 156 } else { 149 157 wrappedChildContainer = root = DOM.createDiv(); … … 164 172 165 173 // Reinsert all widget wrappers to this container 174 final int currentOrientationMode = orientationMode; 166 175 for (int i = 0; i < childWidgetWrappers.size(); i++) { 167 176 WidgetWrapper wr = (WidgetWrapper) childWidgetWrappers.get(i); 168 Element oldWrElement = wr.getWrappingElement(); 177 orientationMode = oldOrientationMode; 178 Element oldWrElement = wr.getElementWrappingWidgetAndCaption(); 179 orientationMode = currentOrientationMode; 169 180 wr.resetRootElement(); 170 Element newWrElement = wr.get WrappingElement();181 Element newWrElement = wr.getElementWrappingWidgetAndCaption(); 171 182 while (DOM.getChildCount(oldWrElement) > 0) { 172 183 Element c = DOM.getFirstChild(oldWrElement); … … 204 215 .getStringAttribute("orientation")) ? ORIENTATION_HORIZONTAL 205 216 : ORIENTATION_VERTICAL; 206 rebuildRootDomStructure(oldO != orientationMode);217 rebuildRootDomStructure(oldO); 207 218 208 219 // Handle component spacing later in handleAlignments() method … … 306 317 307 318 // Update child layouts 308 // TODO This is most probably unne dessary and should be done within319 // TODO This is most probably unnecessary and should be done within 309 320 // update Child H/W 310 321 if (childLayoutsHaveChanged) { … … 367 378 int size; 368 379 if (tableMode) { 369 size = rootOffsetMeasure("offsetHeight"); 380 381 // If we know explicitly set pixel-size, use that 382 if (height != null && height.endsWith("px")) { 383 try { 384 size = Integer.parseInt(height.substring(0, height 385 .length() - 2)); 386 387 // For negative sizes, use measurements 388 if (size < 0) { 389 size = rootOffsetMeasure("offsetHeight"); 390 } 391 } catch (NumberFormatException e) { 392 393 // In case of invalid number, try to measure the size; 394 size = rootOffsetMeasure("offsetHeight"); 395 } 396 } 397 // If not, try to measure the size 398 else { 399 size = rootOffsetMeasure("offsetHeight"); 400 } 401 370 402 } else { 371 403 size = DOM.getElementPropertyInt(root, "offsetHeight"); … … 418 450 DOM.setStyleAttribute(measure, "height", "100%"); 419 451 Element parent = DOM.getParent(root); 420 DOM.insertBefore(parent, measure, getElement());452 DOM.insertBefore(parent, measure, root); 421 453 DOM.removeChild(parent, root); 422 454 int size = DOM.getElementPropertyInt(measure, offset); 423 455 DOM.insertBefore(parent, root, measure); 424 456 DOM.removeChild(parent, measure); 457 // In case the no space would be given for this element 458 // without pushing, use the current side of the root 425 459 return size; 426 460 } … … 432 466 433 467 // Calculate the space for fixed contents minus marginals 434 int size = rootOffsetMeasure("offsetWidth"); 468 int size; 469 // If we know explicitly set pixel-size, use that 470 if (width != null && width.endsWith("px")) { 471 try { 472 size = Integer.parseInt(width.substring(0, 473 width.length() - 2)); 474 475 // For negative sizes, use measurements 476 if (size < 0) { 477 size = rootOffsetMeasure("offsetWidth"); 478 } 479 480 } catch (NumberFormatException e) { 481 482 // In case of invalid number, try to measure the size; 483 size = rootOffsetMeasure("offsetWidth"); 484 } 485 } 486 // If not, try to measure the size 487 else { 488 size = rootOffsetMeasure("offsetWidth"); 489 } 435 490 436 491 size -= margins.hasLeft() ? marginLeft : 0; … … 500 555 501 556 /** 502 * Cell contained in the orderedlayout. This helper also manages for spacing 503 * and alignment for individual cells handling. 557 * Wrapper around single child in the layout. 504 558 * 559 * This helper also manages spacing, margins and alignment for individual 560 * cells handling. It also can put hard size limits for its contens by 561 * clipping the content to given pixel size. 562 * 505 563 */ 506 564 class WidgetWrapper extends UIObject { 507 565 508 Element td; 566 /** 567 * When alignment table structure is used, these elements correspond to 568 * the TD elements within the structure. If alignment is not used, these 569 * are null. 570 */ 571 Element alignmentTD, innermostTDinAlignmnetStructure; 572 573 /** 574 * When clipping must be done and the element wrapping clipped content 575 * would be TD instead of DIV, this element points to additional DIV 576 * that is used for clipping. 577 */ 509 578 Element clipperDiv; 579 580 /** Caption element when used. */ 510 581 Caption caption = null; 582 583 /** 584 * Last set pixel height for the wrapper. -1 if vertical clipping is not 585 * used. 586 */ 511 587 int lastForcedPixelHeight = -1; 588 589 /** 590 * Last set pidel width for the wrapper. -1 if horizontal clipping is 591 * not used. 592 */ 512 593 int lastForcedPixelWidth = -1; 513 594 … … 541 622 } 542 623 } 543 Element e = clipperDiv != null ? clipperDiv : getWrappingElement(); 624 Element e = clipperDiv != null ? clipperDiv 625 : getElementWrappingAlignmentStructures(); 544 626 545 627 // Overflow … … 579 661 } 580 662 } 581 Element e = clipperDiv != null ? clipperDiv : getWrappingElement(); 663 Element e = clipperDiv != null ? clipperDiv 664 : getElementWrappingAlignmentStructures(); 582 665 583 666 // Overflow … … 592 675 } 593 676 594 /** Create a DIV inside TD for clippingchild */677 /** Create a DIV for clipping the child */ 595 678 private void createClipperDiv() { 596 679 clipperDiv = DOM.createDiv(); 597 final Element e = get WrappingElement();680 final Element e = getElementWrappingClipperDiv(); 598 681 while (DOM.getChildCount(e) > 0) { 599 682 final Element c = DOM.getFirstChild(e); … … 606 689 /** Undo createClipperDiv() */ 607 690 private void removeClipperDiv() { 608 final Element e = get WrappingElement();691 final Element e = getElementWrappingClipperDiv(); 609 692 while (DOM.getChildCount(clipperDiv) > 0) { 610 693 final Element c = DOM.getFirstChild(clipperDiv); … … 616 699 } 617 700 618 /** Get the element containing the caption and the wrapped widget. */ 619 private Element getWrappingElement() { 701 /** 702 * Get the element containing the caption and the wrapped widget. 703 * Returned element can one of the following: 704 * <ul> 705 * <li>(a) Root DIV of the WrapperElement when not in tableMode</li> 706 * <li>(b) TD in just below the root TR of the WrapperElement when in 707 * tableMode</li> 708 * <li>(c) clipperDiv inside the (a) or (b)</li> 709 * <li>(d) The innermost TD within alignment structures located in (a), 710 * (b) or (c)</li> 711 * </ul> 712 * 713 * @return Element described above 714 */ 715 private Element getElementWrappingWidgetAndCaption() { 716 717 // When alignment is used, we will can safely return the innermost 718 // TD 719 if (innermostTDinAlignmnetStructure != null) { 720 return innermostTDinAlignmnetStructure; 721 } 722 723 // In all other cases element wrapping the potential alignment 724 // structures is the correct one 725 return getElementWrappingAlignmentStructures(); 726 } 727 728 /** 729 * Get the element where alignment structures should be placed in if 730 * they are in use. 731 * 732 * Returned element can one of the following: 733 * <ul> 734 * <li>(a) Root DIV of the WrapperElement when not in tableMode</li> 735 * <li>(b) TD in just below the root TR of the WrapperElement when in 736 * tableMode</li> 737 * <li>(c) clipperDiv inside the (a) or (b)</li> 738 * </ul> 739 * 740 * @return Element described above 741 */ 742 private Element getElementWrappingAlignmentStructures() { 743 744 // Clipper DIV wraps the alignment structures if present 745 if (clipperDiv != null) { 746 return clipperDiv; 747 } 748 749 // When Clipper DIV is not used, we just give the element 750 // that would wrap it if it would be used 751 return getElementWrappingClipperDiv(); 752 } 753 754 /** 755 * Get the element where clipperDiv should be placed in if they it is in 756 * use. 757 * 758 * Returned element can one of the following: 759 * <ul> 760 * <li>(a) Root DIV of the WrapperElement when not in tableMode</li> 761 * <li>(b) TD in just below the root TR of the WrapperElement when in 762 * tableMode</li> 763 * </ul> 764 * 765 * @return Element described above 766 */ 767 private Element getElementWrappingClipperDiv() { 768 769 // Only vertical layouts in non-table mode use TR as root, for the 770 // rest we can safely give root element 620 771 if (!tableMode || orientationMode == ORIENTATION_HORIZONTAL) { 621 772 return getElement(); 622 773 } 774 775 // The root is TR, we'll thus give the TD that is immediately within 776 // the root 623 777 return DOM.getFirstChild(getElement()); 624 778 } … … 627 781 * Create tr, td or div - depending on the orientation of the layout and 628 782 * set it as root. 783 * 784 * All contents of the wrapper are cleared. Caller is responsible for 785 * preserving the contents and moving them into new root. 629 786 * 630 787 * @return Previous root element. … … 647 804 } 648 805 } 806 807 // Clear any references to intermediate elements 808 clipperDiv = alignmentTD = innermostTDinAlignmnetStructure = null; 649 809 } 650 810 … … 653 813 654 814 final Widget widget = (Widget) paintable; 815 final Element captionWrapper = getElementWrappingWidgetAndCaption(); 655 816 656 817 // The widget needs caption … … 675 836 // As the caption has just been created, insert it to DOM 676 837 if (after) { 677 DOM.appendChild( getWrappingElement(), captionElement);678 DOM.setElementAttribute( getWrappingElement(), "class",838 DOM.appendChild(captionWrapper, captionElement); 839 DOM.setElementAttribute(captionWrapper, "class", 679 840 "i-orderedlayout-w"); 680 841 caption.addStyleName("i-orderedlayout-c"); 681 842 widget.addStyleName("i-orderedlayout-w-e"); 682 843 } else { 683 DOM 684 .insertChild(getWrappingElement(), 685 captionElement, 0); 844 DOM.insertChild(captionWrapper, captionElement, 0); 686 845 } 687 846 … … 689 848 690 849 // Caption exists. Move it to correct position if needed 691 if (after == (DOM.getChildIndex(getWrappingElement(), 692 widgetElement) > DOM.getChildIndex( 693 getWrappingElement(), captionElement))) { 694 Element firstElement = DOM.getChild(getWrappingElement(), 695 DOM.getChildCount(getWrappingElement()) - 2); 850 if (after == (DOM.getChildIndex(captionWrapper, widgetElement) > DOM 851 .getChildIndex(captionWrapper, captionElement))) { 852 Element firstElement = DOM.getChild(captionWrapper, DOM 853 .getChildCount(captionWrapper) - 2); 696 854 if (firstElement != null) { 697 DOM.removeChild( getWrappingElement(), firstElement);698 DOM.appendChild( getWrappingElement(), firstElement);699 } 700 DOM.setElementAttribute( getWrappingElement(), "class",855 DOM.removeChild(captionWrapper, firstElement); 856 DOM.appendChild(captionWrapper, firstElement); 857 } 858 DOM.setElementAttribute(captionWrapper, "class", 701 859 after ? "i-orderedlayout-w" : ""); 702 860 if (after) { … … 716 874 // Remove existing caption from DOM 717 875 if (caption != null) { 718 DOM.removeChild( getWrappingElement(), caption.getElement());876 DOM.removeChild(captionWrapper, caption.getElement()); 719 877 caption = null; 720 DOM.setElementAttribute( getWrappingElement(), "class", "");878 DOM.setElementAttribute(captionWrapper, "class", ""); 721 879 widget.removeStyleName("i-orderedlayout-w-e"); 722 880 caption.removeStyleName("i-orderedlayout-w-c"); … … 730 888 void setAlignment(String verticalAlignment, String horizontalAlignment) { 731 889 732 // Set vertical alignment733 if (BrowserInfo.get().isIE()) {734 DOM.setElementAttribute(getWrappingElement(), "vAlign",735 verticalAlignment);736 } else {737 if (orientationMode == ORIENTATION_VERTICAL) {738 if (verticalAlignment == null739 || verticalAlignment.equals("top")) {740 DOM.setStyleAttribute(getWrappingElement(), "display",741 "block");742 DOM743 .setStyleAttribute(getWrappingElement(),744 "width", "");745 } else {746 DOM.setStyleAttribute(getWrappingElement(), "display",747 "table-cell");748 DOM.setStyleAttribute(getWrappingElement(), "width",749 "1000000px");750 }751 }752 DOM.setStyleAttribute(getWrappingElement(), "verticalAlign",753 verticalAlignment);754 }755 756 // Set horizontal alignment757 758 890 // use one-cell table to implement horizontal alignments, only 759 // for values other than "left"(which is default)760 // build one cell table761 if (!horizontalAlignment.equals("left")) {891 // for values other than top-left (which is default) 892 if (!horizontalAlignment.equals("left") 893 || !verticalAlignment.equals("top")) { 762 894 763 895 // The previous positioning has been left (or unspecified). 764 896 // Thus we need to create a one-cell-table to position 765 897 // this element. 766 if ( td== null) {898 if (alignmentTD == null) { 767 899 768 900 // Store and remove the current childs (widget and caption) 769 Element c1 = DOM.getFirstChild(getWrappingElement()); 901 Element c1 = DOM 902 .getFirstChild(getElementWrappingWidgetAndCaption()); 770 903 if (c1 != null) { 771 DOM.removeChild(getWrappingElement(), c1); 772 } 773 Element c2 = DOM.getFirstChild(getWrappingElement()); 904 DOM.removeChild(getElementWrappingWidgetAndCaption(), 905 c1); 906 } 907 Element c2 = DOM 908 .getFirstChild(getElementWrappingWidgetAndCaption()); 774 909 if (c2 != null) { 775 DOM.removeChild(getWrappingElement(), c2); 910 DOM.removeChild(getElementWrappingWidgetAndCaption(), 911 c2); 776 912 } 777 913 778 914 // Construct table structure to align children 779 final String t = "<table cellpadding='0' cellspacing='0' width='100%' ><tbody><tr><td>"915 final String t = "<table cellpadding='0' cellspacing='0' width='100%' height='100%'><tbody><tr><td>" 780 916 + "<table cellpadding='0' cellspacing='0' ><tbody><tr><td align='left'>" 781 917 + "</td></tr></tbody></table></td></tr></tbody></table>"; 782 DOM.setInnerHTML(get WrappingElement(), t);783 td = DOM.getFirstChild(DOM.getFirstChild(DOM918 DOM.setInnerHTML(getElementWrappingWidgetAndCaption(), t); 919 alignmentTD = DOM 784 920 .getFirstChild(DOM 785 .getFirstChild(getWrappingElement())))); 786 Element itd = DOM.getFirstChild(DOM.getFirstChild(DOM 787 .getFirstChild(DOM.getFirstChild(td)))); 921 .getFirstChild(DOM 922 .getFirstChild(DOM 923 .getFirstChild(getElementWrappingWidgetAndCaption())))); 924 innermostTDinAlignmnetStructure = DOM.getFirstChild(DOM 925 .getFirstChild(DOM.getFirstChild(DOM 926 .getFirstChild(alignmentTD)))); 788 927 789 928 // Restore children inside the 790 929 if (c1 != null) { 791 DOM.appendChild(i td, c1);930 DOM.appendChild(innermostTDinAlignmnetStructure, c1); 792 931 if (c2 != null) { 793 DOM.appendChild(itd, c2); 932 DOM 933 .appendChild( 934 innermostTDinAlignmnetStructure, c2); 794 935 } 795 936 } … … 799 940 // Go around optimization bug in WebKit and ensure repaint 800 941 if (BrowserInfo.get().isSafari()) { 801 String prevValue = DOM.getElementAttribute(td, "align"); 942 String prevValue = DOM.getElementAttribute(alignmentTD, 943 "align"); 802 944 if (!horizontalAlignment.equals(prevValue)) { 803 Element parent = DOM.getParent( td);804 DOM.removeChild(parent, td);805 DOM.appendChild(parent, td);945 Element parent = DOM.getParent(alignmentTD); 946 DOM.removeChild(parent, alignmentTD); 947 DOM.appendChild(parent, alignmentTD); 806 948 } 807 949 } … … 809 951 } 810 952 811 // Seth the alignment in td 812 DOM.setElementAttribute(td, "align", horizontalAlignment); 813 814 } else 815 816 // In this case we are requested to position this left 817 // while as it has had some other position in the past. 818 // Thus the one-cell wrapper table must be removed. 819 if (td != null) { 820 821 // Move content to main container 822 Element itd = DOM.getFirstChild(DOM.getFirstChild(DOM 823 .getFirstChild(DOM.getFirstChild(td)))); 824 while (DOM.getChildCount(itd) > 0) { 825 Element content = DOM.getFirstChild(itd); 826 if (content != null) { 827 DOM.removeChild(itd, content); 828 DOM.appendChild(getWrappingElement(), content); 829 } 830 } 831 832 // Remove unneeded table element 833 DOM.removeChild(getWrappingElement(), DOM 834 .getFirstChild(getWrappingElement())); 835 836 td = null; 953 // Set the alignment in td 954 DOM.setElementAttribute(alignmentTD, "align", 955 horizontalAlignment); 956 DOM.setElementAttribute(alignmentTD, "valign", 957 verticalAlignment); 958 959 } else { 960 961 // In this case we are requested to position this left 962 // while as it has had some other position in the past. 963 // Thus the one-cell wrapper table must be removed. 964 if (alignmentTD != null) { 965 966 // Move content to main container 967 final Element itd = innermostTDinAlignmnetStructure; 968 final Element alignmentTable = DOM.getParent(DOM 969 .getParent(DOM.getParent(alignmentTD))); 970 final Element target = DOM.getParent(alignmentTable); 971 while (DOM.getChildCount(itd) > 0) { 972 Element content = DOM.getFirstChild(itd); 973 if (content != null) { 974 DOM.removeChild(itd, content); 975 DOM.appendChild(target, content); 976 } 977 } 978 979 // Remove unneeded table element 980 DOM.removeChild(target, alignmentTable); 981 982 alignmentTD = innermostTDinAlignmnetStructure = null; 983 } 837 984 } 838 985 } … … 841 988 void setSpacingAndMargins(boolean first, boolean last) { 842 989 990 final Element e = getElementWrappingWidgetAndCaption(); 991 843 992 if (orientationMode == ORIENTATION_HORIZONTAL) { 844 DOM 845 .setStyleAttribute(getWrappingElement(), "paddingLeft", 846 first ? (margins.hasLeft() ? marginLeft + "px" 847 &nb
