Project

General

Profile

Actions

Bug #1072

closed

Buttons become unclickable in layouts with images and nonzero stretch factors

Added by Peter K over 12 years ago. Updated about 12 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Target version:
Start date:
11/27/2011
Due date:
% Done:

0%

Estimated time:

Description

Hi,

It looks to me like WHBoxLayout and WVBoxLayout may have a bug when dealing with images. I narrowed the problem down to a test case (code below). In short, in layouts that contain an image and an element with a non-zero stretch factor, two problems appear:

1) Images are rendered across div (WContainerWidget) boundaries

2) Buttons that are placed in elements after the stretch are unclickable

The "unclickable" buttons are always unclickable on a freshly loaded browser (Firefox, Chrome, Safari). Sometimes, they can become clickable after other buttons on the page have been used.

In the test case I have a nested layout that uses a WHBoxLayout and a WVBoxLayout. Without the image, everything works fine. When the image is added, the image size seems to be ignored and it is rendered across the div boundary. Buttons in elements before the stretch element work as expected, but the button placed after it is apparently invisible to the browser. Any other widgets placed after the stretch also don't respond to events.

MyApplication::MyApplication(const WEnvironment& env):
WApplication(env)
{
    useStyleSheet("CssStyleSheet.css"); //Just background-color to highlight where the divs are

    //A vertical box layout fills out the root widget and contains two WContainerWidgets
    WVBoxLayout* vLayout=new WVBoxLayout(root());
    WContainerWidget *topContainer, *bottomContainer;
    topContainer=new WContainerWidget; bottomContainer=new WContainerWidget;
    vLayout->addWidget(topContainer);
    vLayout->addWidget(bottomContainer);
    topContainer->setStyleClass("grey");
    vLayout->setStretchFactor(bottomContainer,1);   //bottom container takes up all unused space

    //A horizontal box layout fills out the topContainer and has four WContainerWidgets in it
    WHBoxLayout* topLayout=new WHBoxLayout(topContainer);
    WContainerWidget *topDiv1, *topDiv2, *topDiv3, *topDiv4;
    topDiv1=new WContainerWidget; topDiv2=new WContainerWidget;
    topDiv3=new WContainerWidget; topDiv4=new WContainerWidget;
    topLayout->addWidget(topDiv1);
    topLayout->addWidget(topDiv2);
    topLayout->addWidget(topDiv3);
    topLayout->addWidget(topDiv4);
    topLayout->setStretchFactor(topDiv3,1);     //Third WContainerWidget takes up all unused space

    //An image is placed into the first top WContainerWidget
    //Without the image, the bug does not show up
    WImage* image=new WImage("Blue rectangle.jpg",topDiv1);     //?? Image is rendered across the div boundary!

    //Three buttons are added to containers 2,3, and 4. The one after the stretched element (topDiv3)
    //Is unclickable
    WPushButton *button2, *button3, *button4;
    button2=new WPushButton(WString("Button 2"),topDiv2);       //Clickable
    button3=new WPushButton(WString("Button 3"),topDiv3);       //Clickable
    button4=new WPushButton(WString("Button 4"),topDiv4);       //Unclickable!!
}

Files

Blue_rectangle.jpg (8.4 KB) Blue_rectangle.jpg Peter K, 11/27/2011 01:14 AM
CssStyleSheet.css (110 Bytes) CssStyleSheet.css Peter K, 11/27/2011 01:14 AM
Firefox_result.png (17.8 KB) Firefox_result.png Firefox, Chrome and Safari - image misrendered, unclickable button Peter K, 11/28/2011 07:11 PM
IE9_result.png (18.5 KB) IE9_result.png IE9 - no bug Peter K, 11/28/2011 07:11 PM
Actions #1

Updated by Koen Deforche over 12 years ago

  • Status changed from New to InProgress
  • Assignee set to Koen Deforche
  • Target version set to 3.2.0

Hey,

I couldn't reproduce this problem with the latest git version though (I tried Chrome, firefox and IE), so I would have to assume that this was solved.

Regards,

koen

Updated by Peter K over 12 years ago

Hi Koen,

Even with the latest git version, I can reproduce the bug by pasting the above code into the "Hello World" example... Attached are the images of the incorrectly rendered page in Firefox (bug present, unclickable button 4) and IE9 (no bug). The bug shows on Firefox, Chrome and Safari, but IE9 does not have it for some reason.

Loading the page in IE9 before loading it in Firefox fixes the issue in Firefox until the browser is closed (I don't know how that is possible!).

Also, to see the bug, the image file (here, "Blue_rectangle.jpg") must be in the executable's current directory. If the image is not found and not rendered, the bug will not show up.

I can always see the bug on the page by closing all browsers and then loading Firefox, Chrome or Safari.

Could it be a problem in the Windows build? My WT build is Win64 (with ZLIB and OpenSSL).

Thanks,

Peter

Actions #3

Updated by Koen Deforche over 12 years ago

  • Target version changed from 3.2.0 to 3.2.1
Actions #4

Updated by Koen Deforche over 12 years ago

  • Status changed from InProgress to Feedback

Hey,

I've managed to reproduce the problem. The reason is that the layout requires active size management, and this is computed before the image has been loaded. Resizing the window, for example, fixes this.

I'm not sure how to fix this without adverse side effects --- catching the onload signal of all images contained in a layout manager seems like overkill and could be a disaster when you have mnay images.

A workaround is to explicitly set a size to the image. In that way you also avoid possible flicker caused by reflowing the page when the image gets loaded.

Regards,

koen

Actions #5

Updated by Peter K over 12 years ago

I see... Setting the image size is fine as a solution, but the problem is that the application may not always know the size, right?

Just random ideas from the top of my head:

1) Is it possible to delay computing the layout until all the images have loaded?

2) Can I trigger recomputing the layout after everything on the page has loaded? (just like resizing the page does?)

Thank you,

Peter

Actions #6

Updated by Koen Deforche over 12 years ago

Hey,

Unfortunately, it is not that simple --- there is no catch all event handler for image loading and thus one needs to add handlers to every image --- something which is even more difficult because some images may also be part of XHTML that is not generated by Wt.

For 2) we could indeed document a method. The way you can do this is:

app->doJavaScript("window.onresize();");

Regards,

koen

Actions #7

Updated by Peter K over 12 years ago

Thanks, that solves it. It might be a good idea to add something to the documentation about this potential pitfall (Maybe to WImage and WBoxLayout sections?).

Regards,

Peter

Actions #8

Updated by Koen Deforche over 12 years ago

  • Status changed from Feedback to Resolved

Hey,

Good idea. I added a note in the WBoxLayout documentation.

Regards,

koen

Actions #9

Updated by Koen Deforche about 12 years ago

  • Status changed from Resolved to Closed

Fixed in 3.2.1

Actions

Also available in: Atom PDF