Show
Ignore:
Timestamp:
07/11/08 16:41:58 (4 months ago)
Author:
joonas.lehtinen@…
Message:

Optimizing IOrderedLayout

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/com/itmill/toolkit/terminal/gwt/client/ui/IOrderedLayout.java

    r5095 r5096  
    135135            return; 
    136136        } 
     137        boolean oldTableMode = tableMode; 
    137138        tableMode = newTableMode; 
    138139 
     
    176177            WidgetWrapper wr = (WidgetWrapper) childWidgetWrappers.get(i); 
    177178            orientationMode = oldOrientationMode; 
     179            tableMode = oldTableMode; 
    178180            Element oldWrElement = wr.getElementWrappingWidgetAndCaption(); 
    179181            orientationMode = currentOrientationMode; 
     182            tableMode = newTableMode; 
     183            String classe = DOM.getElementAttribute(oldWrElement, "class"); 
    180184            wr.resetRootElement(); 
    181185            Element newWrElement = wr.getElementWrappingWidgetAndCaption(); 
     186            if (classe != null && classe.length() > 0) { 
     187                DOM.setElementAttribute(newWrElement, "class", classe); 
     188            } 
    182189            while (DOM.getChildCount(oldWrElement) > 0) { 
    183190                Element c = DOM.getFirstChild(oldWrElement); 
     
    306313 
    307314        // Reset sizes for the children 
    308         // TODO These might be optimized by combining these methods 
    309         updateChildHeights(); 
    310         updateChildWidths(); 
     315        updateChildSizes(); 
    311316 
    312317        // Paint children 
     
    369374    } 
    370375 
    371     /** Recalculate and apply child heights */ 
    372     private void updateChildHeights() { 
     376    /** Recalculate and apply the space given for each child in this layout. */ 
     377    private void updateChildSizes() { 
     378 
     379        int numChild = childWidgets.size(); 
     380        int childHeightTotal = -1; 
     381        int childHeightDivisor = 1; 
     382        int childWidthTotal = -1; 
     383        int childWidthDivisor = 1; 
    373384 
    374385        // Vertical layout is calculated by us 
     
    376387 
    377388            // Calculate the space for fixed contents minus marginals 
    378             int size; 
    379389            if (tableMode) { 
    380390 
     
    382392                if (height != null && height.endsWith("px")) { 
    383393                    try { 
    384                         size = Integer.parseInt(height.substring(0, height 
    385                                 .length() - 2)); 
     394                        childHeightTotal = Integer.parseInt(height.substring(0, 
     395                                height.length() - 2)); 
    386396 
    387397                        // For negative sizes, use measurements 
    388                         if (size < 0) { 
    389                             size = rootOffsetMeasure("offsetHeight"); 
     398                        if (childHeightTotal < 0) { 
     399                            childHeightTotal = rootOffsetMeasure("offsetHeight"); 
    390400                        } 
    391401                    } catch (NumberFormatException e) { 
    392402 
    393403                        // In case of invalid number, try to measure the size; 
    394                         size = rootOffsetMeasure("offsetHeight"); 
     404                        childHeightTotal = rootOffsetMeasure("offsetHeight"); 
    395405                    } 
    396406                } 
    397407                // If not, try to measure the size 
    398408                else { 
    399                     size = rootOffsetMeasure("offsetHeight"); 
     409                    childHeightTotal = rootOffsetMeasure("offsetHeight"); 
    400410                } 
    401411 
    402412            } else { 
    403                 size = DOM.getElementPropertyInt(root, "offsetHeight"); 
    404             } 
    405  
    406             size -= margins.hasTop() ? marginTop : 0; 
    407             size -= margins.hasBottom() ? marginBottom : 0; 
     413                childHeightTotal = DOM.getElementPropertyInt(root, 
     414                        "offsetHeight"); 
     415            } 
     416 
     417            childHeightTotal -= margins.hasTop() ? marginTop : 0; 
     418            childHeightTotal -= margins.hasBottom() ? marginBottom : 0; 
    408419 
    409420            // Reduce spacing from the size 
    410             int numChild = childWidgets.size(); 
    411421            if (hasComponentSpacing) { 
    412                 size -= ((orientationMode == ORIENTATION_HORIZONTAL) ? hSpacing 
     422                childHeightTotal -= ((orientationMode == ORIENTATION_HORIZONTAL) ? hSpacing 
    413423                        : vSpacing) 
    414424                        * (numChild - 1); 
    415425            } 
    416426 
    417             // Set the sizes for each child 
     427            // Total space is divided among the children 
     428            if (orientationMode == ORIENTATION_VERTICAL) { 
     429                childHeightDivisor = numChild; 
     430            } 
     431        } 
     432 
     433        // layout is calculated by us 
     434        if (width != null) { 
     435 
     436            // Calculate the space for fixed contents minus marginals 
     437            // If we know explicitly set pixel-size, use that 
     438            if (width != null && width.endsWith("px")) { 
     439                try { 
     440                    childWidthTotal = Integer.parseInt(width.substring(0, width 
     441                            .length() - 2)); 
     442 
     443                    // For negative sizes, use measurements 
     444                    if (childWidthTotal < 0) { 
     445                        childWidthTotal = rootOffsetMeasure("offsetWidth"); 
     446                    } 
     447 
     448                } catch (NumberFormatException e) { 
     449 
     450                    // In case of invalid number, try to measure the size; 
     451                    childWidthTotal = rootOffsetMeasure("offsetWidth"); 
     452                } 
     453            } 
     454            // If not, try to measure the size 
     455            else { 
     456                childWidthTotal = rootOffsetMeasure("offsetWidth"); 
     457            } 
     458 
     459            childWidthTotal -= margins.hasLeft() ? marginLeft : 0; 
     460            childWidthTotal -= margins.hasRight() ? marginRight : 0; 
     461 
     462            // Reduce spacing from the size 
     463            if (hasComponentSpacing 
     464                    && orientationMode == ORIENTATION_HORIZONTAL) { 
     465                childWidthTotal -= hSpacing * (numChild - 1); 
     466            } 
     467 
     468            // Total space is divided among the children 
    418469            if (orientationMode == ORIENTATION_HORIZONTAL) { 
    419                 for (Iterator i = childWidgetWrappers.iterator(); i.hasNext();) { 
    420                     ((WidgetWrapper) i.next()).forceHeight(size); 
    421                 } 
     470                childWidthDivisor = numChild; 
     471            } 
     472        } 
     473 
     474        // Set the sizes for each child 
     475        for (Iterator i = childWidgetWrappers.iterator(); i.hasNext();) { 
     476            int w, h; 
     477            if (childHeightDivisor > 1) { 
     478                h = Math.round(((float) childHeightTotal) 
     479                        / (childHeightDivisor--)); 
     480                childHeightTotal -= h; 
    422481            } else { 
    423                 for (Iterator i = childWidgetWrappers.iterator(); i.hasNext();) { 
    424                     final int ws = Math.round(((float) size) / (numChild--)); 
    425                     size -= ws; 
    426                     ((WidgetWrapper) i.next()).forceHeight(ws); 
    427                 } 
    428             } 
    429         } 
    430  
    431         // Vertically layout is calculated by the browsers 
    432         else { 
    433             for (Iterator i = childWidgetWrappers.iterator(); i.hasNext();) { 
    434                 ((WidgetWrapper) i.next()).forceHeight(-1); 
    435             } 
     482                h = childHeightTotal; 
     483            } 
     484            if (childWidthDivisor > 1) { 
     485                w = Math.round(((float) childWidthTotal) 
     486                        / (childWidthDivisor--)); 
     487                childWidthTotal -= h; 
     488            } else { 
     489                w = childWidthTotal; 
     490            } 
     491            WidgetWrapper ww = (WidgetWrapper) i.next(); 
     492            // TODO COMBINE THESE 
     493            ww.forceSize(w, h); 
    436494        } 
    437495    } 
     
    460518    } 
    461519 
    462     /** Recalculate and apply child widths */ 
    463     private void updateChildWidths() { 
    464         // layout is calculated by us 
    465         if (width != null) { 
    466  
    467             // Calculate the space for fixed contents minus marginals 
    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             } 
    490  
    491             size -= margins.hasLeft() ? marginLeft : 0; 
    492             size -= margins.hasRight() ? marginRight : 0; 
    493  
    494             // Reduce spacing from the size 
    495             int numChild = childWidgets.size(); 
    496             if (hasComponentSpacing 
    497                     && orientationMode == ORIENTATION_HORIZONTAL) { 
    498                 size -= hSpacing * (numChild - 1); 
    499             } 
    500  
    501             // Set the sizes for each child 
    502             if (orientationMode == ORIENTATION_HORIZONTAL) { 
    503                 for (Iterator i = childWidgetWrappers.iterator(); i.hasNext();) { 
    504                     final int ws = Math.round(((float) size) / (numChild--)); 
    505                     size -= ws; 
    506                     ((WidgetWrapper) i.next()).forceWidth(ws); 
    507                 } 
    508             } else { 
    509                 for (Iterator i = childWidgetWrappers.iterator(); i.hasNext();) { 
    510                     ((WidgetWrapper) i.next()).forceWidth(size); 
    511                 } 
    512             } 
    513         } 
    514  
    515         // Layout is calculated by the browsers 
    516         else { 
    517             for (Iterator i = childWidgetWrappers.iterator(); i.hasNext();) { 
    518                 ((WidgetWrapper) i.next()).forceWidth(-1); 
    519             } 
    520         } 
    521  
    522     } 
    523  
    524520    /** Parse alignments from UIDL and pass whem to correct widgetwrappers */ 
    525521    private void handleAlignmentsSpacingAndMargins(UIDL uidl) { 
     
    600596 
    601597        /** 
    602          * Set the height given for the wrapped widget in pixels. 
     598         * Set the width and height given for the wrapped widget in pixels. 
    603599         *  
    604600         * -1 if unconstrained. 
    605601         */ 
    606         public void forceHeight(int pixelHeight) { 
     602        public void forceSize(int pixelWidth, int pixelHeight) { 
    607603 
    608604            // If we are already at the correct size, do nothing 
    609             if (lastForcedPixelHeight == pixelHeight) { 
     605            if (lastForcedPixelHeight == pixelHeight 
     606                    && lastForcedPixelWidth == pixelWidth) { 
    610607                return; 
    611608            } 
    612609 
    613610            // Clipper DIV is needed? 
    614             if (tableMode) { 
    615                 if (pixelHeight >= 0) { 
    616                     if (clipperDiv == null) { 
    617                         createClipperDiv(); 
    618                     } 
     611            if (tableMode && (pixelHeight >= 0 || pixelWidth >= 0)) { 
     612                if (clipperDiv == null) { 
     613                    createClipperDiv(); 
    619614                } 
    620                 // Needed to remove unnecessary clipper DIV 
    621                 else if (clipperDiv != null && lastForcedPixelWidth < 0) { 
    622                     removeClipperDiv(); 
    623                 } 
    624             } 
     615            } 
     616 
     617            // ClipperDiv is not needed, remove if necessary 
     618            else if (clipperDiv != null) { 
     619                removeClipperDiv(); 
     620            } 
     621 
    625622            Element e = clipperDiv != null ? clipperDiv 
    626623                    : getElementWrappingAlignmentStructures(); 
    627624 
    628625            // Overflow 
     626            DOM.setStyleAttribute(e, "overflowX", pixelWidth < 0 ? "" 
     627                    : "hidden"); 
    629628            DOM.setStyleAttribute(e, "overflowY", pixelHeight < 0 ? "" 
    630629                    : "hidden"); 
    631630 
    632             // Set height 
     631            // Set size 
     632            DOM.setStyleAttribute(e, "width", pixelWidth < 0 ? "" : pixelWidth 
     633                    + "px"); 
    633634            DOM.setStyleAttribute(e, "height", 
    634635                    pixelHeight < 0 ? (e == clipperDiv || !tableMode ? "100%" 
    635636                            : "") : pixelHeight + "px"); 
    636637 
     638            // Set cached values 
     639            lastForcedPixelWidth = pixelWidth; 
    637640            lastForcedPixelHeight = pixelHeight; 
    638         } 
    639  
    640         /** 
    641          * Set the width given for the wrapped widget in pixels. 
    642          *  
    643          * -1 if unconstrained. 
    644          */ 
    645         public void forceWidth(int pixelWidth) { 
    646  
    647             // If we are already at the correct size, do nothing 
    648             if (lastForcedPixelWidth == pixelWidth) { 
    649                 return; 
    650             } 
    651  
    652             // Clipper DIV needed 
    653             if (tableMode) { 
    654                 if (pixelWidth >= 0) { 
    655                     if (clipperDiv == null) { 
    656                         createClipperDiv(); 
    657                     } 
    658                 } 
    659                 // Needed to remove unnecessary clipper DIV 
    660                 else if (clipperDiv != null && lastForcedPixelHeight < 0) { 
    661                     removeClipperDiv(); 
    662                 } 
    663             } 
    664             Element e = clipperDiv != null ? clipperDiv 
    665                     : getElementWrappingAlignmentStructures(); 
    666  
    667             // Overflow 
    668             DOM.setStyleAttribute(e, "overflowX", pixelWidth < 0 ? "" 
    669                     : "hidden"); 
    670  
    671             // Set width 
    672             DOM.setStyleAttribute(e, "width", pixelWidth < 0 ? "" : pixelWidth 
    673                     + "px"); 
    674  
    675             lastForcedPixelWidth = pixelWidth; 
    676641        } 
    677642 
     
    680645            clipperDiv = DOM.createDiv(); 
    681646            final Element e = getElementWrappingClipperDiv(); 
     647            String classe = DOM.getElementAttribute(e, "class"); 
    682648            while (DOM.getChildCount(e) > 0) { 
    683649                final Element c = DOM.getFirstChild(e); 
     
    685651                DOM.appendChild(clipperDiv, c); 
    686652            } 
     653            if (classe != null && classe.length() > 0) { 
     654                DOM.removeElementAttribute(e, "class"); 
     655                DOM.setElementAttribute(clipperDiv, "class", classe); 
     656            } 
    687657            DOM.appendChild(e, clipperDiv); 
    688658        } 
     
    691661        private void removeClipperDiv() { 
    692662            final Element e = getElementWrappingClipperDiv(); 
     663            String classe = DOM.getElementAttribute(clipperDiv, "class"); 
    693664            while (DOM.getChildCount(clipperDiv) > 0) { 
    694665                final Element c = DOM.getFirstChild(clipperDiv); 
     
    698669            DOM.removeChild(e, clipperDiv); 
    699670            clipperDiv = null; 
     671            if (classe != null && classe.length() > 0) { 
     672                DOM.setElementAttribute(e, "class", classe); 
     673            } 
    700674        } 
    701675 
     
    11711145    /* documented at super */ 
    11721146    public void iLayout() { 
    1173         updateChildHeights(); 
    1174         updateChildWidths(); 
     1147        updateChildSizes(); 
    11751148        Util.runDescendentsLayout(this); 
    11761149        childLayoutsHaveChanged = false;