PDA

View Full Version : VerticalLayoutContainer does not calculates own height properly.



8 May 2014, 11:16 PM
VerticalLayoutContainer does not calculates own height properly if any margin specified. It seems that margins are not getting included into overall height.



public void onModuleLoad() {
VerticalLayoutContainer parentContainer = new VerticalLayoutContainer();
RootPanel.get().add(parentContainer);

VerticalLayoutContainer childContainer = new VerticalLayoutContainer();
parentContainer.add(childContainer);
// To make the containers boundries visible
childContainer.getElement().getStyle().setBackgroundColor("red");

TextField firstName = new TextField();
childContainer.add(new FieldLabel(firstName, "First Name"), new VerticalLayoutData(-1, -1, new Margins(6)));

TextField lastName = new TextField();
childContainer.add(new FieldLabel(lastName, "Last Name"), new VerticalLayoutData(-1, -1, new Margins(6)));
}


As you see contents are getting out of the container boundaries. This will make very hard to place something next/after to the container.

Output:
48959

victormartinezjurado
8 May 2014, 11:50 PM
Hi,

This issue seems to appear when using margins in the VerticalLayoutData, which is indeed a big problem. I am currently trying to migrate a 3.0.5 app to 3.1.0 and more than half the application is now unusable due to that problem.

Can we expect a quickfix for this one ?

11 May 2014, 11:26 PM
I can confirm that the problem still exists in 3.1.0 release.

stigrv
15 May 2014, 6:50 AM
I got the same problem after migrating from 3.1-beta to 3.1

stigrv
15 May 2014, 9:35 PM
My problem was solved by moving from VerticalLayoutContainer to CssFloatLayoutContainer with a CssFloatData size parameter of 1

16 May 2014, 12:23 AM
stigrv,
Thank you for the solution,
But use of CssFloatLayoutContainer not an easy option for us. Too many layouts needs to be altered

Our product almost complete. We are using a nightly build of gxt 3.1.0 and we have switched from gxt 3.0.

I need to be sure that there is no other options before making this decision.

Thanks

branflake2267
16 May 2014, 11:05 AM
We are looking into this and will get back with more shortly.

Brandon

stigrv
26 May 2014, 7:15 AM
Using CssFloatLayoutContainer only works if all elements should fill the full width. If any of the elements use margins horizontally, the width of their margins are deducted from the total width to calculate what width all elements should be given. I'm not sure about its intended use, but I don't think that's the way to do it.

28 May 2014, 3:18 AM
Using CssFloatLayoutContainer only works if all elements should fill the full width. If any of the elements use margins horizontally, the width of their margins are deducted from the total width to calculate what width all elements should be given. I'm not sure about its intended use, but I don't think that's the way to do it.

I agree with you stigrv. In my opinion Margins are not supposed to be deducted from the widgets width.

Actually we have paused transition to 3.1.0 because of this issue. We are waiting Brandon's reply. As he stated he will get back with more information.

branflake2267
28 May 2014, 9:04 AM
Just a note, I've found a bug with the CssFloatLayoutContainer margins calculation seems to be doubling on the right, and this throws off how it may be calculating (EXTGWT-3707). I have escalated the issue. Although this only occurs when using margins for a css float layout container addition.




CssFloatLayoutContainer con = new CssFloatLayoutContainer();
con.add(getRowWidget(1), new CssFloatData(1, new Margins(10))); // right margin broken
con.add(getRowWidget(2), new CssFloatData(1, new Margins(0))); // works good


While the margin is broken, another container can be used to wrap and add margins around that.

I will share Vertical Layout options in the next posts.


~ New GXT Guides ~
http://docs.sencha.com/gxt/3.1/


~ Tips and Announcements Community ~
https://plus.google.com/communities/110447085143928405373

branflake2267
28 May 2014, 9:35 AM
The VerticalLayoutContainer is meant for top down sizing, which means it either has to be given a size or the parent sizes it. When using -1 for any layoutdata, will turn off sizing for that dimension, which means the child is responsible for that sizing and in theory, it won't run sizing for that dimension which includes margins. So if you add margins to vertical layout container with margins and there is a -1 for height or width, the margins will likely not work.

Most of the issues seem to be around, "why isn't my child get sized or margins showing up?". Thats usually because a top down container has been used and the -1 shuts off sizing for the children or the margins. In this case the child has to do the sizing work, not the container that the child sits in.

Another issue is how the widgets are constructed, IsWidget vs Composite widget construction. If you are using composite with a layout widget, then that Composite will have to implement RequiresResize. This is critical and more information can be found here.
http://docs.sencha.com/gxt/3.1/ui/WidgetConfigurations.html

More information on the VLC container
http://docs.sencha.com/gxt/3.1/ui/layout/containers/VerticalLayoutContainer.html

If you don't want to provide a size by parent or setting it by setPixelSize, then maybe one of the other containers may be suited for the job, like FlowLayoutContainer, CssFloatLayoutContainer, or VBoxLayoutContainer. There suited to do different jobs and configurations depending on the goals.

The FlowLayoutContainer is the best option for bottom up sizing, which means the children are responsible for there own sizes, and the FLC doesn't care and it can provide margin data when adding the children. Like if adding a Grid as a child to the FLC, the Grid will need to be given a specific size because it needs a specific size so it can calculate its header, row widgets and such.



import com.google.gwt.user.client.ui.RootPanel;
import com.sencha.gxt.widget.core.client.container.FlowLayoutContainer;
import com.sencha.gxt.widget.core.client.container.MarginData;
import com.sencha.gxt.widget.core.client.form.TextField;


public class FlowLayoutContainerExample {


public FlowLayoutContainerExample() {
TextField tb1 = new TextField();
TextField tb2 = new TextField();

FlowLayoutContainer flc = new FlowLayoutContainer();
flc.setBorders(true);
flc.add(tb1, new MarginData(10));
flc.add(tb2, new MarginData(10));

RootPanel.get().add(flc);
}

}


The next option is the CSSFloatLayoutContainer option is best used when the width has been set by its parent or given directly to the CFLC. It works good if you want to stack things vertically, or when all the rows are like the VerticalLayoutData(1, -1). It also works great for Floating to the right or left and getting a gallery like view. Another benefit to this container it isn't as heavy calculation sizer as the VerticalLayoutContainer is, but thats indistinguishable to the human eye most of the time, but something to be aware of.

More on the CssFloatLayoutContainer
http://docs.sencha.com/gxt/3.1/ui/layout/containers/CssFloatLayoutContainer.html



CssFloatLayoutContainer con = new CssFloatLayoutContainer();
con.add(getRowWidget(1), new CssFloatData(1)); // 1 == 100%
con.add(getRowWidget(2), new CssFloatData(1));
con.add(getRowWidget(3), new CssFloatData(1));


If you get stumped on what you should use, provide a wire frame with colored borders for the boundaries and the expected goals and I'll mock up options to layout the widgets. (This could be a screenshot of what your trying to do with colored borders, or some mocked up wireframe using a tool...)

I know at first that layout container seem daunting and seem to have issues, but once I picked up on the behaviors and options, they exceedingly help drive quicker layout development for me. I also know the challenges and working hard to help provide more guides, tips and information to help digest the options quickly.

Like always there are more options than the above mentioned and I'm standing by to help, send me a wire frame and I can provide even more options.


~ New GXT Guides ~
http://docs.sencha.com/gxt/3.1/


~ Tips and Announcements Community ~
https://plus.google.com/communities/110447085143928405373

branflake2267
28 May 2014, 9:50 AM
Just one more note, what I said above doesn't appear to be working for you, please let us know. Let us know by using a wire frame, screenshot and code configuration to help us provide something back to you quickly.

When providing a code configuration and small test case that we can run locally will help us quickly run and provide options in return.

The goal, if you try to put something together and it has an issue, we can help modify that and send it back. (I have several test cases sitting in the wings if you need something to help get going with.)

Thanks,
Brandon

Andreas Samjeske
2 Jun 2014, 1:56 AM
branflake, thanks for this helpful info! =D>

According to your info given above, I would consider the javadoc of VLC misleading, if not buggy:

/**
* A layout container that lays out its children in a single column. The lay out
* properties for each child are specified using {@link VerticalLayoutData}.
*
* <p/>
* Code Snippet:
*
* <pre>
VerticalLayoutContainer c = new VerticalLayoutContainer();
c.add(new FieldLabel(new TextField(), "Home"), new VerticalLayoutData(1, -1));
c.add(new FieldLabel(new TextField(), "Office"), new VerticalLayoutData(1, -1));
RootPanel.get().add(c);
* </pre>
*/
public class VerticalLayoutContainer extends InsertResizeContainer implements HasScrollHandlers, HasScrollSupport {
...

4 Jun 2014, 1:01 AM
Brandon thanks for your explanations. i appreciate your time and effort.

Currently we have solved this issue by giving a fixed height for all of our vlcs.

branflake2267
4 Jun 2014, 9:03 AM
@Andreas Samjeske (http://www.sencha.com/forum/member.php?289093-Andreas-Samjeske) Good point about the VLC Javadocs. I think we will change the example a little and provide the alternative links as well. The VLC can use -1 in its layoutdata, it just has different impacts depending on the children. Thanks for sharing.

@[email protected] (http://www.sencha.com/forum/member.php?241524-selcuk-atay.org) Thanks for the information.

stigrv
5 Jun 2014, 2:55 AM
Thanks for the info, branflake.
Are there a plan for a release with the CssFloatLayoutContainer margins bug ironed out?

branflake2267
5 Jun 2014, 7:53 AM
Yeah, we escalated the CssFloatLayoutContainer margins issue and an engineer has been assigned that task. So if all the testing goes well it should make it in the next release.

stigrv
15 Jun 2014, 11:39 PM
You should probably also add "position: relative;" to the child element CSS, in order to position its inner content correctly.

stigrv
13 Aug 2014, 11:47 PM
These changes did not make it into the 3.1.1 release. Any plans on when this will be added to an official release?

branflake2267
18 Aug 2014, 9:36 AM
Just an update, the fix is in review and is going in shortly for children with margins. I'll update you when the nightlies are available.

stigrv
25 Sep 2014, 4:42 AM
Any updates on this issue?

stigrv
26 Sep 2014, 12:11 AM
I made some changes to the doLayout method:



@Override
protected final void doLayout() {
final Size size = this.getContainerTarget().getStyleSize();


if (GXTLogConfiguration.loggingIsEnabled()) {
logger.finest(this.getId() + " doLayout size: " + size);
}


int w = size.getWidth() - (this.adjustForScroll ? XDOM.getScrollBarWidth() : 0);
w -= this.getContainerTarget().getFrameWidth(Side.LEFT, Side.RIGHT);
int pw = w;


final int count = this.getWidgetCount();


// Some columns can be percentages while others are fixed so we need to make 2 passes
for (int i = 0; i < count; i++) {
final Widget widget = this.getWidget(i);


CssFloatData layoutData = null;
final Object d = widget.getLayoutData();
if (d != null && d instanceof CssFloatData) {
layoutData = (CssFloatData) d;
} else {
layoutData = new CssFloatData();
}


if (layoutData.getSize() > 1) {
pw -= layoutData.getSize();
}
}


pw = pw < 0 ? 0 : pw;


for (int i = 0; i < count; i++) {
final Widget widget = this.getWidget(i);


CssFloatData layoutData = null;
final Object d = widget.getLayoutData();
if (d != null && d instanceof CssFloatData) {
layoutData = (CssFloatData) d;
} else {
layoutData = new CssFloatData();
}


int width = -1;
final double s = layoutData.getSize();
if (s > 0 && s <= 1) {
width = (int) (s * pw);
} else {
width = (int) s;
}


width -= this.getSideMargins(widget);
this.applyLayout(widget, width, -1);
}
}


I removed the line subtracting side margins during the first pass, and removed side margins during the second pass. This made the layout work a lot better than the original implementation. At least for debug mode. There are still some problems with Chrome and Firefox not ending up at the same width. There are also sometimes large differences between live and debug mode.