Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    DynamicForm Width strange behaviour

    Hi Isomorphic,

    please see this simple BuiltInDS-based sample (using v10.0p_2015-05-06):

    Code:
    package com.smartgwt.sample.client;
    
    import com.google.gwt.core.client.EntryPoint;
    import com.smartgwt.client.core.KeyIdentifier;
    import com.smartgwt.client.data.Criteria;
    import com.smartgwt.client.data.DataSource;
    import com.smartgwt.client.util.PageKeyHandler;
    import com.smartgwt.client.util.Page;
    import com.smartgwt.client.util.SC;
    import com.smartgwt.client.widgets.form.DynamicForm;
    import com.smartgwt.client.widgets.form.fields.ComboBoxItem;
    import com.smartgwt.client.widgets.form.fields.DateItem;
    import com.smartgwt.client.widgets.form.fields.DateTimeItem;
    import com.smartgwt.client.widgets.form.fields.SelectItem;
    import com.smartgwt.client.widgets.form.fields.SpinnerItem;
    import com.smartgwt.client.widgets.form.fields.TextAreaItem;
    import com.smartgwt.client.widgets.form.fields.TextItem;
    import com.smartgwt.client.widgets.layout.HStack;
    import com.smartgwt.client.widgets.layout.VStack;
    
    public class BuiltInDS implements EntryPoint {
    
    	public void onModuleLoad() {
    		KeyIdentifier debugKey = new KeyIdentifier();
    		debugKey.setCtrlKey(true);
    		debugKey.setKeyName("D");
    
    		Page.registerKey(debugKey, new PageKeyHandler() {
    			public void execute(String keyName) {
    				SC.showConsole();
    			}
    		});
    
    		VStack stack = new VStack();
    		stack.setLeft(20);
    		stack.setTop(20);
    		stack.setWidth100();
    		stack.setMembersMargin(20);
    
    		HStack stackRow1 = new HStack();
    		stackRow1.setMembersMargin(20);
    		stackRow1.setWidth100();
    		stackRow1.setHeight100();
    
    		Testform narrowForm = new Testform(false);
    		Testform narrowFormStar = new Testform(true);
    		stackRow1.addMembers(narrowForm, narrowFormStar);
    
    		stack.addMembers(stackRow1);
    		stack.draw();
    	}
    
    	private class Testform extends DynamicForm {
    		private TextItem scientificName;
    		private TextItem commonName;
    		private SelectItem status;
    		private ComboBoxItem status2;
    		private SpinnerItem lifeSpan;
    		private TextAreaItem information;
    		private DateItem dateItem;
    		private DateTimeItem dateTimeItem;
    
    		public Testform(final boolean starWidthTAI) {
    			super();
    			setWidth100();
    			setIsGroup(true);
    			setGroupTitle("setWidth100()-form");
    			setDataSource(DataSource.get("animals"));
    
    			commonName = new TextItem("commonName");
    			scientificName = new TextItem("scientificName");
    			status = new SelectItem("status", "Status(SI)");
    			status2 = new ComboBoxItem("status", "Status(CBI)");
    			lifeSpan = new SpinnerItem("lifeSpan");
    			information = new TextAreaItem("information");
    			dateItem = new DateItem("diTest");
    			dateTimeItem = new DateTimeItem("dtiTest");
    			if (starWidthTAI) {
    				// information.setWidth("*");
    			}
    			setFields(commonName, scientificName, status, status2, lifeSpan, information, dateItem, dateTimeItem);
    			fetchData(new Criteria("scientificName", "Loxodonta africana"));
    		}
    	}
    }
    I don't understand why the two DynamicForms are so wide (see horizontal scrollbar in the screenshot) and why I get a vertical scrollbar at all. I tested using FF26 DevMode.

    Best regards
    Blama
    Attached Files

    #2
    The containing Layout(s) has been told to fill the whole browser, and the form has been told to fill the width of it's container, so you should expect the form to be full screen.

    As far as why you end up with scrollbars, that looks to be a subtle effect of your redundant size settings - you don't need any width/height100 settings on either the inner HLayout or the form, and their meaning is slightly different from the default behavior of filling the available space of the Layout.

    Please confirm that removing those redundant settings fixing the scrollbar issue, if not, maybe you've found a new browser bug or similar.

    Comment


      #3
      Hi Isomorphic,

      if I remove either the HStack (not a HLayout!) calls
      Code:
      stackRow1.setWidth100();
      stackRow1.setHeight100();
      or the DynamicForm subclass call
      Code:
      setWidth100();
      the error goes away.

      So the problem is there only in combination.
      This is not important for me as it occurred while creating a testcase and not in my application. It is more of a FYI, especially as there is a workaround.

      Out of curiosity and in order to minimize LOC: What are the default width and height settings for a Widget, which call would be really redundant? setWidth("*") / setHeight("*")?

      Best regards
      Blama

      Comment


        #4
        In this instance the "default" we're really talking about is that, in the absence of specific pixel size settings or auto-sizing behavior on member components, the default behavior of a Layout is to cause members to fill the Layout's length axis, and either a Layout or Stack causes each members to fill its breadth axis.

        This is why width100/height100 settings are generally redundant for components that are members of a Layout. See Layout.hPolicy/vPolicy for more information.

        Comment


          #5
          Hello Isomorphic
          Originally posted by Isomorphic View Post
          In this instance the "default" we're really talking about is that, in the absence of specific pixel size settings or auto-sizing behavior on member components, the default behavior of a Layout is to cause members to fill the Layout's length axis, and either a Layout or Stack causes each members to fill its breadth axis.

          This is why width100/height100 settings are generally redundant for components that are members of a Layout. See Layout.hPolicy/vPolicy for more information.
          thanks, that is very valuable information (the reference to LayoutPolicy). I was not clear about the fact that the container(layout) of an widget does affect the widgets behaviour. Also thanks for the info on the redundancy of setX100() in Layouts.


          In the meantime I played around a bit more and I think I found the root cause for the behaviour.

          Please see this modified and simplified testcase:
          Code:
          package com.smartgwt.sample.client;
          
          import com.google.gwt.core.client.EntryPoint;
          import com.smartgwt.client.core.KeyIdentifier;
          import com.smartgwt.client.data.Criteria;
          import com.smartgwt.client.data.DataSource;
          import com.smartgwt.client.util.PageKeyHandler;
          import com.smartgwt.client.util.Page;
          import com.smartgwt.client.util.SC;
          import com.smartgwt.client.widgets.form.DynamicForm;
          import com.smartgwt.client.widgets.form.fields.ComboBoxItem;
          import com.smartgwt.client.widgets.form.fields.DateItem;
          import com.smartgwt.client.widgets.form.fields.DateTimeItem;
          import com.smartgwt.client.widgets.form.fields.SelectItem;
          import com.smartgwt.client.widgets.form.fields.SpinnerItem;
          import com.smartgwt.client.widgets.form.fields.TextAreaItem;
          import com.smartgwt.client.widgets.form.fields.TextItem;
          import com.smartgwt.client.widgets.layout.HLayout;
          import com.smartgwt.client.widgets.layout.HStack;
          import com.smartgwt.client.widgets.layout.VStack;
          
          public class BuiltInDS implements EntryPoint {
          
          	public void onModuleLoad() {
          		KeyIdentifier debugKey = new KeyIdentifier();
          		debugKey.setCtrlKey(true);
          		debugKey.setKeyName("D");
          
          		Page.registerKey(debugKey, new PageKeyHandler() {
          			public void execute(String keyName) {
          				SC.showConsole();
          			}
          		});
          
          		VStack stack = new VStack();
          		stack.setWidth100();
          		stack.setMembersMargin(20);
          
          		HLayout layoutRow1 = new HLayout();
          		layoutRow1.setMembersMargin(0);
          
          		Testform tf1 = new Testform();
          		Testform tf2 = new Testform();
          		layoutRow1.addMembers(tf1, tf2);
          
          		HStack stackRow2 = new HStack();
          		stackRow2.setMembersMargin(0);
          
          		Testform tf3 = new Testform();
          		Testform tf4 = new Testform();
          		stackRow2.addMembers(tf3, tf4);
          
          		stack.addMembers(layoutRow1, stackRow2);
          		stack.draw();
          	}
          
          	private class Testform extends DynamicForm {
          		private TextItem scientificName;
          		private TextItem commonName;
          		private SelectItem status;
          		private ComboBoxItem status2;
          		private SpinnerItem lifeSpan;
          		private TextAreaItem information;
          		private DateItem dateItem;
          		private DateTimeItem dateTimeItem;
          
          		public Testform() {
          			super();
          			setWidth100();
          			setIsGroup(true);
          			setAutoFetchData(false);
          			setGroupTitle("setWidth100()-form");
          			setDataSource(DataSource.get("animals"));
          
          			commonName = new TextItem("commonName");
          			scientificName = new TextItem("scientificName");
          			status = new SelectItem("status", "Status(SI)");
          			status2 = new ComboBoxItem("status", "Status(CBI)");
          			lifeSpan = new SpinnerItem("lifeSpan");
          			information = new TextAreaItem("information");
          			dateItem = new DateItem("diTest");
          			dateTimeItem = new DateTimeItem("dtiTest");
          			setFields(commonName, scientificName, status, status2, lifeSpan, information, dateItem, dateTimeItem);
          			fetchData(new Criteria("scientificName", "Loxodonta africana"));
          		}
          	}
          }
          The 1st row (HLayout) is behaving as expected, the 2nd row (HStack) is behaving as before.
          With respect to
          Originally posted by Isomorphic View Post
          ...the default behavior of a Layout is to cause members to fill the Layout's length axis, and either a Layout or Stack causes each members to fill its breadth axis.
          this might be a bug (see new screenshot)?



          Until now, the following were equivalent for me:
          • HLayout with one setWidth100() member or HLayout with one setWidth("100%") member
          • HLayout with two setWidth100() members or HLayout with two setWidth("50%") members
          • HLayout with four setWidth100() members or HLayout with four setWidth("25%") members

          Is this reasoning correct? If I change in the testcase the DynamicForm call to setWidth("50%"), both rows look as expected and there is no scrollbar.

          Best regards
          Blama
          Attached Files

          Comment


            #6
            In both the original test case and the new one, you've got an HStack with two members that have 100% width. For a HStack, it's the *length* policy that applies to the horizontal axis, and the length policy for an HStack is "none", meaning components manage their own widths.

            So with 100% width set, each member takes on the full size of its container, just as they would if they were placed with a plain Canvas. The HStack then just "stacks" them: places they side by side. This causes overflow, hence scrollbars.

            So: no bug, things are behaving exactly as doc'd.

            And, to clarify previous comments, in the first test case, the width/height100 settings on stackRow1 are redundant because it's parent is a Layout and will already cause stackRow1 to fill it. However the 100% width set on the TestForm instances is *not* redundant since it's being placed within an HStack, as explained above.

            Comment


              #7
              Hi Isomorphic,

              thanks for the detailed information. I think I understood now. The confusion came mainly from the fact that I did not use H/VStacks until now.

              I'm now pretty sure that the assumptions I made here (slightly related) are correct:
              Originally posted by Blama View Post
              Until now, the following were equivalent for me:
              • HLayout with one setWidth100() member or HLayout with one setWidth("100%") member
              • HLayout with two setWidth100() members or HLayout with two setWidth("50%") members
              • HLayout with four setWidth100() members or HLayout with four setWidth("25%") members

              Is this reasoning correct?
              Internal calculation for e.g. case three is most likely:
              • Use (100[the member's value]/(100+100+100+100[all the values]))*100[for 0.25 -> 25] + "%" for all four members
              • Use "25%" for all four members


              Best regards
              Blama

              Comment


                #8
                LayoutPolicy:"fill" has these docs:

                Layout sizes members so that they fill the specified size of the layout. The rules are:
                1. Any component given an initial pixel size, programmatically resized to a specific pixel size, or drag resized by user action is left at that exact size
                2. Any component that autofits is given exactly the space it needs, never forced to take up more.
                3. All other components split the remaining space equally, or according to their relative percentages.

                Comment


                  #9
                  Ahh, and Canvas.setWidth100() says:
                  Originally posted by docs
                  Convenience method that sets the width to 100%.
                  Thank you!
                  Blama

                  Comment


                    #10
                    Originally posted by Isomorphic View Post
                    LayoutPolicy:"fill" has these docs:
                    Layout sizes members so that they fill the specified size of the layout. The rules are:
                    1. Any component given an initial pixel size, programmatically resized to a specific pixel size, or drag resized by user action is left at that exact size
                    2. Any component that autofits is given exactly the space it needs, never forced to take up more.
                    3. All other components split the remaining space equally, or according to their relative percentages.
                    Shouldn't be LayoutPolicy:"none"
                    Originally posted by docs
                    Layout does not try to size members on the axis at all, merely stacking them (length axis) and leaving them at default breadth."
                    be more general, as it can be used in both Layout.setVPolicy() and Layout.setHPolicy()?

                    Best regards
                    Blama

                    Comment


                      #11
                      We don't follow. The docs seem to already cover both cases explicitly (length vs breadth).

                      Comment


                        #12
                        Maybe it's just my English, sorry then.

                        I understood:
                        length axis = Länge (German) = Y-axis
                        breadth = width

                        After looking up breadth I think it could be:
                        length axis = current axis
                        breadth = diagonal axis

                        If so, then the most common translation in both cases mislead me here.

                        Best regards
                        Blama

                        Comment


                          #13
                          It's not necessary to rely on translation, the Layout defines these terms in a very specific way: the length axis is the axis of stacking, the breadth axis is the other axis.

                          Comment


                            #14
                            Thanks for explaining.

                            Best regards
                            Blama

                            Comment

                            Working...
                            X