Wow,

Chris, this is really cool.

I have now 0.7 code, but very early I will be porting it and I really
need flow layout. So very thank for your work!

Cheers
- Petr

2008/8/24 Chris Banford <[EMAIL PROTECTED]>:
>
> Flow now respects each Child's alignY setting. :-)
>
> Not sure if __rebuildCache() would apply or not to Flow.
>
> I'm going to take a break from trying to put any more functionality into
> this, as I'd rather get feedback from the devs on this, as how it could be
> improved and/or cleaned up, before I go making it more convoluted. Might
> also be cool to get this into the SVN contrib as a next step?
>
> Here's a simple use case again for anyone who's curious:
> -----------------------------------------------------------------
>       /*
>
> -------------------------------------------------------------------------
>         Below is your actual application code...
>
> -------------------------------------------------------------------------
>       */
>       var container = new qx.ui.container.Composite( new
> qx.ui.layout.Flow(0, "center") );
>
>       var button1 = new qx.ui.form.Button("First Button is long! Overflow
> should ¬
>                     stay centered (and a wee bit of margin too...)",
> "custom/test.png");
>       button1.setMargin(3);
>       button1.setAlignY("middle");
>       container.add(button1);
> ... Add more buttons here to see Flow in action!..
>       this.getRoot().add(container, {edge: 0});
> -----------------------------------------------------------------
>
> The first parameter to Flow is for eventual Child spacing, but I haven't
> implemented that yet. I've also placed the Flow.js file in with the other
> qooxdoo ui.layout files...
>
> Hope this Flow class can be of use someday. Our current YUI-based tools
> implement an Image Library, so we'd need to be able to build a 'flowing'
> thumbnail container. This Flow would work for that already -- kinda cool
> that qooxdoo is so usable that I could get a crude version of such a layout
> object working in just a couple of days from scratch.
>
>
>
> Its a glorious day here, at the foot of the Matterhorn, and I'm off for a
> fantastic, long bike ride through the Swiss alps! (
> http://bergbahnen.zermatt.ch/e/web-cam/ )
>
>
> Have a great day!
> -Chris
>
>
>
> Like so until monday we're going to have a FlowLayout 1.0 full :)
>
> 2008/8/23 Chris Banford <[EMAIL PROTECTED]>
>>
>> Me again,
>>
>> I've managed to get a working implementation of a flow layout that now
>> handles
>> alignX : ["left". "center", "right"] and to boot it respects margins.
>> Turned out to be a tricky little bugger.
>>
>> It also keeps it in grip if the elements are wider than the available
>> space.
>>
>> Need to start to figure out what is up with Gaps and Spacers.
>>
>> AlignY shouldn't too bad to get working as well.
>>
>> -Chris
>>
>>
>>
>
>
> /* ************************************************************************
>
>   qooxdoo - the new era of web development
>   http://qooxdoo.org
>
>   http://www.dihedrals.com
>
>   Copyright:
>     2008 Dihedrals.com
>
>   License:
>     LGPL: http://www.gnu.org/licenses/lgpl.html
>     EPL: http://www.eclipse.org/org/documents/epl-v10.php
>     See the LICENSE file in the project's top-level directory for details.
>
>   Authors:
>     * Chris Banford [chris at dihedrals dot com]
>     * Borrowed liberally from Basic.js and HBox.js
>
> ************************************************************************ */
>
> /**
>  * A basic layout, which supports positioning of child widgets in a
> 'flowing'
>  * manner, starting at the container's top/left position, placing children
> left to right
>  * (like a HBox) until the there's no remaining room for the next child.
> When
>  * out of room on the current line of elements, a new line is started,
> cleared
>  * below the tallest child of the preceeding line -- a bit like using
> 'float'
>  * in CSS, except that a new line wraps all the way back to the left.
>  *
>  * *Example*
>  *
>  * Here is a little example of how to use the grid layout.
>  *
>  * <pre class="javascript">
>  * var flow = new qx.ui.layout.Flow("center")                   // defaults
> to "left"
>  *
>  * var container = new qx.ui.container.Composite( new qx.ui.layout.Flow(
> flow ) );
>  *
>  * var button1 = new qx.ui.form.Button("First Button is long! Overflow
> should stay centered (and a wee bit of margin too...)", "custom/test.png");
>  * button1.setMargin(3);
>  * container.add(button1);
>  *
>  * var button2 = new qx.ui.form.Button("2. Button", "custom/test.png");
>  * container.add(button2);
>  *
>  * var button3 = new qx.ui.form.Button("3rd TALL & really, really, really
> long Button", "custom/test.png");
>  * button3.setHeight(100);      // tall button
>  * container.add(button3);
>  *
>  * var button4 = new qx.ui.form.Button("Number 4", "custom/test.png");
>  * container.add(button4);
>  *
>  * this.getRoot().add(container, {edge: 0});
>  *
>  * </pre>
>  *
>  * *External Documentation*
>  *
>  */
>
> qx.Class.define("qx.ui.layout.Flow",
> {
>  extend : qx.ui.layout.Abstract,
>
>
>  /*
>  *****************************************************************************
>     CONSTRUCTOR
>  *****************************************************************************
>  */
>
>  /**
>   * @param spacing {Integer?0} The spacing between child widgets [EMAIL 
> PROTECTED]
> #spacing}.
>   * @param alignX {String?"left"} Horizontal alignment of the whole children
>   *     block [EMAIL PROTECTED] #alignX}.
>   */
>  construct : function(spacing, alignX)
>  {
>    this.base(arguments);
>
>    if (spacing) {
>      this.setSpacing(spacing);
>    }
>
>    if (alignX) {
>      this.setAlignX(alignX);
>    }
>  },
>
>
>
>  /*
>  *****************************************************************************
>     PROPERTIES
>  *****************************************************************************
>  */
>
>  properties :
>  {
>    /**
>     * Horizontal alignment of the whole children block. The horizontal
>     * alignment of the child is completely ignored in HBoxes (
>     * [EMAIL PROTECTED] qx.ui.core.LayoutItem#alignX}).
>     */
>    alignX :
>    {
>                check : [ "left", "center", "right" ],
>                init : "left",
>                apply : "_applyLayoutChange"
>    },
>
>
>    /**
>     * Vertical alignment of each child. Can be overridden through
>     * [EMAIL PROTECTED] qx.ui.core.LayoutItem#alignY}.
>     */
>    alignY :
>    {
>                check : [ "top", "middle", "bottom", "baseline" ],
>                init : "top",
>                apply : "_applyLayoutChange"
>    },
>
>
>    /** Horizontal spacing between two children */
>    spacing :
>    {
>                check : "Integer",
>                init : 0,
>                apply : "_applyLayoutChange"
>    }
>
>
>  },
>
>
>
>  /*
>  *****************************************************************************
>     MEMBERS
>  *****************************************************************************
>  */
>
>  members :
>  {
>        __currLinesTotalChildWidth : 0,
>        __currLinesTallestChild : 0,
>
>        /*
>
>  ---------------------------------------------------------------------------
>        LAYOUT INTERFACE
>
>  ---------------------------------------------------------------------------
>        */
>
>        // overridden
>        verifyLayoutProperty : qx.core.Variant.select("qx.debug",
>        {
>                "on" : function(item, name, value)
>                {
>                this.assert( false, "The property '"+name+"' is not supported
> by the flow layout!" );
>                },
>
>                "off" : null
>        }),
>
>        //-------------------------------------------------------------------
>        // overridden
>        renderLayout : function( availWidth, availHeight )
>        {
>                var util = qx.ui.layout.Util;
>                var children = this._getLayoutChildren();
>                var child, size, left, top, childW;
>                var marginL, marginR, marginT, marginB;
>
>                var linesChildrenIndexes =[];
>                var newLineFlag = false;
>
>                var lineLeft = 0, lineTop = 0;
>                var tallestChildInLine = 0;
>
>                // Compute gaps
>                var spacing = this.getSpacing();
>                //var separator = this.getSeparator();
>                //if (separator) {
>                //      var gaps =
> util.computeHorizontalSeparatorGaps(children, spacing, separator);
>                //} else {
>                //var gaps = util.computeHorizontalGaps(children, spacing,
> true);
>                //}
>                this.info( "   >> Layout spacing: " + spacing );
>
>                // Flow Render children
>                //if ( qx.core.Variant.get("qx.debug") == "on" ){ this.info(
> "*** Render Start ***" ); }
>                var lineCounter = 0;
>                var currChildIndex = 0
>                while ( currChildIndex < children.length )
>                {
>                        lineCounter++;
>                        tallestChildInLine = 0;
>
>                        linesChildrenIndexes =
> this._getIndexesOfChildrenOnALine(children, currChildIndex, availWidth);
>
>                        /*
>                        // Debug msgs
>                        if ( qx.core.Variant.get("qx.debug") == "on" ){
>                                if ( linesChildrenIndexes.length > 0 ) {
>                                        this.info( "Line #"+ (lineCounter) +"
> is "+this.getAlignX()+" aligned and has " + linesChildrenIndexes.length + "x
> children" );
>                                } else {
>                                        this.info( "Line #"+ (lineCounter) +"
> is "+this.getAlignX()+" aligned and has 1 child" );
>                                }
>                        }
>                        */
>
>
>                        // Alignment X support
>                        var thisLineCurrLeft = 0;
>   // AlignX -> "left"
>                        if (this.getAlignX() != "left") {
>                                thisLineCurrLeft = availWidth -
> this.__currLinesTotalChildWidth;        // AlignX -> "right"
>                                if (this.getAlignX() == "center") {
>                                        thisLineCurrLeft =
> Math.round(thisLineCurrLeft / 2);    // AlignX -> "center"
>                                }
>                                // reverse this Line's children, so the Flow
> starts from the
>                                // right edge of the container, with the
> proper child order (I think)
>                                if (this.getAlignX() == "right") {
>                                        linesChildrenIndexes =
> linesChildrenIndexes.concat().reverse();
>                                }
>                        }
>
>
>
>                        // If there are multiple children that have place on
> this Line,
>                        // then loop through them and render each one after
> calculating
>                        // the correct left starting position due to alignX.
>                        var thisLineNr;
>                        var len = linesChildrenIndexes.length;
>                        for ( var x=0; x<len; x++ ) {
>                                thisLineNr = linesChildrenIndexes[x];
>                                child = children[thisLineNr];
>                                //this.info( "   >> Render child: " +
> child.getLabel() );
>                                size = child.getSizeHint();
>                                // Keep track of the tallest child on this
> Line.
>                                marginT = child.getMarginTop();
>                                marginB = child.getMarginBottom();
>                                if ( (marginT + size.height + marginB) >
> tallestChildInLine ) {
>                                        tallestChildInLine = (marginT +
> size.height + marginB);
>                                }
>                                marginL = child.getMarginLeft();
>                                marginR = child.getMarginRight();
>
>
>                        // Respect vertical alignment - alignY
>                        top =
> util.computeVerticalAlignOffset(child.getAlignY()||this.getAlignY(),
> (marginT + size.height + marginB), this.__currLinesTallestChild, marginT,
> marginB);
>
>
>                                child.renderLayout( (thisLineCurrLeft +
> marginL), (lineTop + top), size.width, size.height);
>
>                                thisLineCurrLeft += (marginL + size.width +
> marginR);
>                                currChildIndex++;
>                        }
>
>
>
>                        // Single child on Line
>                        // If this line contain's a single element that is
> wider than then
>                        // available space, then it still needs to be
> rendered to this Line,
>                        // and the line counter increased to the next line
> (otherwise any
>                        // element wider than availWidth wouldn't be
> shown...)
>                        // AlignX will have special meaning here! Will prob
> mean negative left pos...
>                        if ( len < 1 ) {
>                                child = children[currChildIndex];
>                                //this.info( "   >> Render child wider than
> window on its own line: " + child.getLabel() );
>                                size = child.getSizeHint();
>                                // Only a single child on this line, so its
> automatically the tallest.
>                                marginT = child.getMarginTop();
>                                marginB = child.getMarginBottom();
>                                tallestChildInLine = (marginT + size.height +
> marginB);
>                                marginL = child.getMarginLeft();
>                                marginR = child.getMarginRight();
>
>
>                                // Adjust this single, possibly overflowing
> child for alignX.
>                                if ( (marginL + size.width + marginR) >
> availWidth ) {
>                                        // Child is overflowing.
>                                        if (this.getAlignX() == "center") {
>                                                var centeredLeft =
> Math.round((availWidth - (marginL + size.width + marginR)) / 2)
>                                                //this.info( ">> Single
> centered overflow: " + centeredLeft );
>                                                thisLineCurrLeft =
> centeredLeft;                        // AlignX -> "center"
>                                        }
>                                        if (this.getAlignX() == "right") {
>                                                var rightLeft =
> Math.round(availWidth - (marginL + size.width + marginR))
>                                                //this.info( ">> Single
> centered overflow: " + centeredLeft );
>                                                thisLineCurrLeft = rightLeft;
>                   // AlignX -> "right"
>                                        }
>                                }
>
>                                // alignY -> When a single child is displayed
> alone on a line,
>                                // there is no alignY applied, as this
> child's hieght is the Line's height.
>                                child.renderLayout( (thisLineCurrLeft +
> marginL), (lineTop + marginT), size.width, size.height);
>                                currChildIndex++;
>                        }
>
>                        // update the next line's top starting point.
>                        lineTop += tallestChildInLine;
>
>                }
>
>        },
>
>
>        //-------------------------------------------------------------------
>        // Take a list of children and a starting index and see how
>        // many of the buggers will fit on a line of availWidth space.
>        _getIndexesOfChildrenOnALine : function(children, startIndex,
> availWidth)
>        {
>                var childIndexList = [];
>                var child, size, childW;
>                var marginL, marginR, marginT, marginB;
>                var currLeft = 0;
>                var tallestChildInLine = 0;
>
>                for ( var i=startIndex, l=children.length; i<l; i++ )
>                {
>                        // Add children indexes, until their accumulated
> widths
>                        // won't fit on a single line anymore.
>                        child = children[i];
>                        size = child.getSizeHint();
>                        marginL = child.getMarginLeft();
>                        marginR = child.getMarginRight();
>                        marginT = child.getMarginTop();
>                        marginB = child.getMarginBottom();
>                        childW = marginL + size.width + marginR;
>                        if ( currLeft + childW > availWidth ) {
>                                // Don't save this child and return this
> lines list of Child index numbers.
>                                break;
>                        }
>                        // Calc Tallest child on line.
>                        if ( (marginT + size.height + marginB) >
> tallestChildInLine ) {
>                                tallestChildInLine = (marginT + size.height +
> marginB);
>                        }
>                        childIndexList.push(i);
>                        currLeft += childW;
>
>                }
>
>                // keep track of the total width of all this line's children,
> so
>                // renderLayout() can calculate the starting left position of
> the first child,
>                // so that alignX works.
>                this.__currLinesTotalChildWidth = currLeft;
>                // Same for alignY
>                this.__currLinesTallestChild = tallestChildInLine;
>
>                return childIndexList;
>        },
>
>
>        // overridden
>        // Don't need hints for a Flow box (I think)
>        // Sebastian's tip is to return null, but that's yakking, so
> returning 0 instead.
>        _computeSizeHint : function()
>        {
>                return {
>                        width : 0,
>                        height : 0
>                };
>        }
>
>
>
>
>  }
> });
>
> -------------------------------------------------------------------------
> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
> Build the coolest Linux based applications with Moblin SDK & win great
> prizes
> Grand prize is a trip for two to an Open Source event anywhere in the world
> http://moblin-contest.org/redirect.php?banner_id=100&url=/
> _______________________________________________
> qooxdoo-devel mailing list
> qooxdoo-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel
>
>

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
qooxdoo-devel mailing list
qooxdoo-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel

Reply via email to