muhuk's blog

Nature, to Be Commanded, Must Be Obeyed

February 04, 2009

Using Layouts In Qooxdoo - Part 2: VBox Layout

This is the second part of a tutorial series about layout managers, container objects and object hierarchies in Qooxdoo. Read the first part here.

qx.ui.layout.VBox is a basic layout manager that places child widgets on top of each other.

VBox Layout

VBox Layout

Let’s see how VBox lays out components on a simple application1. All the necessary code is below:

/*
#asset(vbox/*)
*/
qx.Class.define("vbox.Application",
{
    extend: qx.application.Standalone,
    members: {
        main: function(){
            this.base(arguments);
            var main_container = new qx.ui.container.Composite();
            var layout_manager = new qx.ui.layout.VBox();
            main_container.setLayout(layout_manager);

            main_container.add(new qx.ui.form.Button("Child Widget 1"));
            main_container.add(new qx.ui.form.Button("Child Widget 2"));
            main_container.add(new qx.ui.form.Button("Child Widget 3"));

            var application_root = this.getRoot();
            application_root.add(main_container);
        }
    }
});
VBox Example 1

VBox Example 1

I told you VBox is basic; child widgets are stacked vertically in order they have added. We haven’t set any preferences (constraints), so it’s all defaults. Button``s get an optimal width depending on the length of their label. The container ``main_container applies this width to itself, it conforms its children’s dimensions.

Try giving one of the buttons a longer label. Now the modified button is wider, that was expected. But the others are widened as well. That is because they have conformed (flexed) their container’s width. We will see how this works in detail.

Let’s set the container’s size same as the viewport’s:

/*
#asset(vbox/*)
*/
qx.Class.define("vbox.Application",
{
    extend: qx.application.Standalone,
    members: {
        main: function(){
            this.base(arguments);

            var main_container = new qx.ui.container.Composite();
            main_container.setWidth(qx.bom.Viewport.getWidth());
            main_container.setHeight(qx.bom.Viewport.getHeight());

            var layout_manager = new qx.ui.layout.VBox();
            main_container.setLayout(layout_manager);

            main_container.add(new qx.ui.form.Button("Child Widget 1"));
            main_container.add(new qx.ui.form.Button("Child Widget 2"));
            main_container.add(new qx.ui.form.Button("Child Widget 3"));

            var application_root = this.getRoot();
            application_root.add(main_container);
        }
    }
});
VBox Example 2

VBox Example 2

Notice that only width seems to be adjusted, even though we have set both dimensions. Actually, it worked as we intended to; main_container now fills the entire viewport. But by default VBox won’t flex child widgets vertically. We will start overriding this behaviour in a minute.

Try setting alignY property to "center" or "bottom" on the layout manager:

layout_manager.setAlignY("bottom");

So far we have set properties (constraints) on containers (main_container.width & main_container.height) and on layout managers (layout_manager.alignY). In the next example we will set properties on child widgets:

/*
#asset(vbox/*)
*/
qx.Class.define("vbox.Application",
{
    extend: qx.application.Standalone,
    members: {
        main: function(){
            this.base(arguments);

            var main_container = new qx.ui.container.Composite();
            main_container.setWidth(qx.bom.Viewport.getWidth());
            main_container.setHeight(qx.bom.Viewport.getHeight());

            var layout_manager = new qx.ui.layout.VBox();
            main_container.setLayout(layout_manager);

            main_container.add(new qx.ui.form.Button("Child Widget 1"), {flex: 1});
            main_container.add(new qx.ui.form.Button("Child Widget 2"), {flex: 1});
            main_container.add(new qx.ui.form.Button("Child Widget 3"), {flex: 1});

            var application_root = this.getRoot();
            application_root.add(main_container);
        }
    }
});
VBox Example 3

VBox Example 3

We have added a second parameter to the add method of layout manager. This JavaScript object literal is used to set widget specific properties on the layout manager.

Flex property determines how the extra space2 is distributed between children. By default it is set to 0, which means that the widget will not grow vertically. Any other (integer) value for flex will cause growing to occupy the extra space. Growing is proportional to flex value. Try different flex values for different widgets and see the changes.

NEXT PART: HBox Layout


1: If you haven’t created a qx application before, it is explained in detail in the tutorial.

2: Remaining space after initial dimensions of children are computed.

If you have any questions, suggestions or corrections feel free to drop me a line.