Project

General

Profile

Problems using WGridLayout

Added by David Gaarenstroom over 13 years ago

I'm encountering some problems using WGridLayout (Wt 3.1.11) and maybe someone can help. I would like to create a grid filled with fixed-size squares of 20 pixels high and 8 wide. In this grid I want to place widgets inside one or more cells, e.g. a WLabel on (1, 0) with span(1, 3) and a WLineEdit on (1,4) with span(1, 6).

For example:

+-+-+-+-+-+-+-+-+-+-+
| | | [somelabel] | |
+-+-+-+-+-+-+-+-+-+-+
[label] [My lineedit]
+-+-+-+-+-+-+-+-+-+-+
[label] | | | | | | |
+-+-+-+-+-+-+-+-+-+-+

I've tried different approaches, but every time I end up with a WLineEdit that is 10 pixel high instead of 20. Also there seems to be too much spacing between each row. I am setting both the horizontal and vertical spacing to 0. Explicitly resizing child widgets to the right size does not help either. Am I doing something wrong or is this a bug?

Here's an example (using colors around each widget to debug sizes):

#include <Wt/WApplication>
#include <Wt/WContainerWidget>
#include <Wt/WColor>
#include <Wt/WCssDecorationStyle>
#include <Wt/WGridLayout>
#include <Wt/WLabel>
#include <Wt/WLength>
#include <Wt/WLineEdit>

using namespace Wt;

#define         COL_SIZE        8
#define         ROW_SIZE        20

class MyApplication: public WApplication {
public:
    MyApplication(const Wt::WEnvironment& env);
};

MyApplication::MyApplication(const Wt::WEnvironment& env)
    : Wt::WApplication(env)
{
    setTitle("Test grid");

    WContainerWidget* container = new WContainerWidget(root());
    container->resize(22*COL_SIZE, 8*ROW_SIZE);

    // Add a background color for "container" to debug its allocated size
    WCssDecorationStyle decoration;
    decoration.setBackgroundColor(WColor("silver"));
    container->setDecorationStyle(decoration);

    // Divide the container into 22x8 equally-sized cells
    WGridLayout* grid = new WGridLayout(container);
    for (int c = 0; c< 22; ++c)
        grid->setColumnStretch(c, 0);
    for (int r = 0; r < 8; ++r)
        grid->setRowStretch(r, 0);

    // Disable spacing
    grid->setHorizontalSpacing(0);
    grid->setColumnResizable(0);

    // Set gridlayout for container
    container->setLayout(grid);

    WLabel* field1 = new WLabel("somelabel");
    grid->addWidget(field1, 0, 3, 1, 5);

    WLabel* field2 = new WLabel("label");
    grid->addWidget(field2, 1, 0, 1, 3);

    WLineEdit* field3 = new WLineEdit();
    grid->addWidget(field3, 1, 4, 1, 6);

    WLabel* field4 = new WLabel("label");
    grid->addWidget(field4, 2, 0, 1, 3);


    WCssDecorationStyle dfield1;
    dfield1.setBackgroundColor(WColor("yellow"));
    field1->setDecorationStyle(dfield1);

    WCssDecorationStyle dfield2;
    dfield2.setBackgroundColor(WColor("red"));
    field2->setDecorationStyle(dfield2);

    WCssDecorationStyle dfield3;
    dfield3.setBackgroundColor(WColor("blue"));
    field3->setDecorationStyle(dfield3);

    WCssDecorationStyle dfield4;
    dfield4.setBackgroundColor(WColor("green"));
    field4->setDecorationStyle(dfield4);

    /* This doesn't help either:
    field1->resize(5*COL_SIZE, 1*ROW_SIZE);
    field2->resize(3*COL_SIZE, 1*ROW_SIZE);
    field3->resize(6*COL_SIZE, 1*ROW_SIZE);
    field4->resize(3*COL_SIZE, 1*ROW_SIZE);
    */
}

WApplication*   createApplication(const Wt::WEnvironment& env) 
{
    WApplication* app = new MyApplication(env);
    return app;
}

int main(int argc, char *argv[])
{
    return Wt::WRun(argc, argv, &createApplication);
}

Replies (5)

RE: Problems using WGridLayout - Added by David Gaarenstroom over 13 years ago

This:

grid->setColumnResizable(0);

was supposed to be

grid->setVerticalSpacing(0);

But fixing it doesn't help much. Column 4, 5, 6 and 7 are wider than the other columns (about 1.5 times). The row-height seems to be consistent. I'm becoming more convinced that this really is a bug in Wt. (My version is 3.1.11, but the 3.2.0 Changelog doesn't seem to mention anything related...)

The following code can be added at the end of the MyApplication constructor to show the inconsistent column-width:

    WCssDecorationStyle even;
    even.setBackgroundColor(WColor("white"));

    WCssDecorationStyle odd;
    odd.setBackgroundColor(WColor("black"));

    for (int r = 0; r < 8; ++r) {
        if (r == 7) {
            for (int c = 0; c< 22; ++c) {
                WContainerWidget* square = new WContainerWidget();

                if (((c +r) % 2) == 0) {
                    square->setDecorationStyle(odd);
                } else {
                    square->setDecorationStyle(even);
                }
                grid->addWidget(square, r, c);
            }
        }
        else {
            WContainerWidget* square = new WContainerWidget();

            if ((r % 2) == 0) {
                square->setDecorationStyle(even);
            } else {
                square->setDecorationStyle(odd);
            }
            grid->addWidget(square, r, 21);
        }
    }

RE: Problems using WGridLayout - Added by David Gaarenstroom over 13 years ago

I've managed to locate two problems here.

First of all, browsers seem to give a higher precedence to the size attribute (default: 10) of the WLineEdit than the width. Both Firefox and Chrome handle this the same way. (I don't think Wt can do anything about that.)

Second, the width for the columns in the WGridLayout are set in whole percentages by Wt. IMHO, this is a bug and I will file this as such.

In the case of my example, each of the 22 columns will be set to style="width:4\" (100 / 22 columns, rounded down), resulting in a total of 88%.

It seems browsers are assigning the remaining 12% to what they think is best. Therefore some columns will simply be wider that others. If I save the "innerHTML\" using Firebug and change all columns to be 4.55% wide, the layout seems fine!

RE: Problems using WGridLayout - Added by Koen Deforche over 13 years ago

Hey,

I wonder why we settled on use integer percentages --- and if it is not because we found that some browsers (IE?) could not handle floating point percentages... Did you see an issue with IE?

Regards,

koen

RE: Problems using WGridLayout - Added by David Gaarenstroom over 13 years ago

I'm seeing issues in Firefox and to solve them I had to use the 4.55% I'm not yet aware of such debugging features in IE. And I could not really locate the code that needed to be changed in Wt to generate the desired code.

Being able to set the width for column definitions inside the colgroup for the WGridLayout (e.g. a "SetColumnWidth(int colNo, const WLength& width)") that will generate the required code might be very helpful here and for other purposes. By the way, if I use a width of 5% (rounded up) columns seem to be distributed correctly. If I'm using >100 columns the layout is completely messed up because the width is set to 0%.

RE: Problems using WGridLayout - Added by Koen Deforche over 13 years ago

Hey,

Git head contains a patch to use fractional numbers.

I couldn't spot any problem with it even in IE.

Regards,

Koen

    (1-5/5)