Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-8121] Android: Implement support for Ti.UI.INHERIT

GitHub Issuen/a
TypeNew Feature
PriorityHigh
StatusClosed
ResolutionInvalid
Resolution Date2012-06-15T13:29:25.000+0000
Affected Version/sRelease 2.0.0
Fix Version/sn/a
ComponentsAndroid
Labelscore, parity
ReporterBryan Hughes
AssigneeOpie Cyrus
Created2012-03-20T14:45:48.000+0000
Updated2017-03-22T21:01:48.000+0000

Description

Ti.UI.INHERIT tells a control that it's width/height should be based on the parent's width/height, respectively. If the parent's width (for example) is SIZE, then the inherited width is SIZE, otherwise it is FILL. As a result, if a control inherits, the result will be either SIZE or FILL but nothing else. Another way to think about this is that inherit is a different type of "auto"...instead of looking to the controls default of FILL/SIZE, it looks to the parent to infer FILL/SIZE.

Comments

  1. Ivan Skugor 2012-03-21

    I don't understand, how is this different from using "100%"?
  2. Ivan Skugor 2012-03-21

    I found more precise explanation in Git commit comment: "The INHERIT behavior means the view will use the width or height of the parent, as specified by the user. For example, if the parent width is set to 50%, then a child with a width of INHERIT will inherit the width of 50%, making it 25% of the parent's parent's width." But I'm still struggling to understand when this behavior would be useful.
  3. Bryan Hughes 2012-03-21

    It's useful when you want to make reusable components and you don't know what the parent width/height is going to be. It could be SIZE, or it could be FILL, but we have no way of knowing when the component is written but we have to support both situations. Note that if you set the width to FILL, and the parent is SIZE, the behavior is undefined. Conversely, if the control's size is SIZE and the parent is FILL, it will probably look bad and waste space. This means there is no good default that exists currently.
  4. Bryan Hughes 2012-05-15

    I ended up tweaking the behavior for inherit some to better match how I needed it to act, and how I think people will want to use it. The behavior I implemented is that if the parent's width (for example) is SIZE, then the inherited width is SIZE, otherwise it is FILL. As a result, if a control inherits, the result will be either SIZE or FILL but nothing else. Another way to think about this is that inherit is a different type of "auto"...instead of looking to the controls default of FILL/SIZE, it looks to the parent to infer FILL/SIZE. I feel that this will be more useful for developers (plus it just feels less...hacky), but I'm certainly open for discussion.
  5. Ivan Skugor 2012-05-16

    "Note that if you set the width to FILL, and the parent is SIZE, the behavior is undefined." - this is good point, but IMO the behavior should not be undefined. I think that parent should have priority and should size itself according to child's content (if child has no content, they should be invisible ~ dimension value should be zero). That way, parent will semantically have size of its content, while child will fill parent. :)
  6. Bryan Hughes 2012-05-16

    I don't particularly like it being undefined either, and in practice the behavior is defined on a platform by platform basis, but technically the UI composite spec says the behavior is undefined. If we want to change it officially, we need to change the spec. On mobile web, if the parent is size and the child is fill, the child recurses up the tree until it finds a non-size parent and uses that size. Example: root: 50px child1: UI.SIZE child2: UI.FILL Child 2 will be 50px wide. The other platforms tend to work similarly, although this behavior cannot be relied upon since it isn't defined.
  7. Ivan Skugor 2012-05-17

    If other platforms implemented similar behavior, than that's something that really should be specified (so that all platforms implement same behavior). Solution implemented on Mobile web is fine, although, as I mentioned, my preference is that parent component has priority (it seems more intuitive to me).
  8. Bryan Hughes 2012-05-17

    I don't really have a preference either way, so if you feel that parent's taking priority makes more sense, then I am totally fine with that. This ticket is not the place to make that change, however, and a separate ticket should be filed.
  9. Ivan Skugor 2012-05-18

  10. Opie Cyrus 2012-05-30

    This change should not be required. Inheriting the user defined value is already possible via something like:
        var win = Ti.UI.createWindow({backgroundColor: 'red'});
        
        var view1 = Ti.UI.createView({top: 10, backgroundColor: 'green', width: '30%', height: '30%'});
        var view2 = Ti.UI.createView({backgroundColor: 'yellow', width: view1.width, height: view1.height});
        view1.add(view2);
        win.add(view1);
        
        
        var view3 = Ti.UI.createView({bottom: 10, backgroundColor: 'green', width: '30%', height: '30%'});
        var view4 = Ti.UI.createView({backgroundColor: 'yellow', width: '30%', height: '30%'});
        view3.add(view4);
        win.add(view3);
        
        win.addEventListener("postlayout", function() {
        	Ti.API.info("View1 width: " + view1.width + " View1 rect.width: " + view1.rect.width);
        });
        win.open();
        
    Beyond that, changing the layout mechanism by adding a new layout property should require a parity discussion before any implementation is done.
  11. Bryan Hughes 2012-05-30

    Opie: can you tell me how your code sample solves the FILL/SIZE mismatch problem? None of the views in your example are FILL/SIZE, so I'm not seeing the connection. FYI inherit has already been implemented in Mobile Web, although it can certainly be changed or made internal only (most of our controls require it internally).
  12. Bryan Hughes 2012-05-30

    Oh yeah, I should also mention that a key part of inherit is that the child doesn't know about the existence of the parent. This is critical for Mobile Web because we never know what controls the built-in controls will be added to. Devs can add, for example, a label to a parent with SIZE or FILL and we won't know, so we have to handle both scenarios with a single codebase. This is also useful for controls wrapped up in modules and reused.
  13. Opie Cyrus 2012-05-31

    From the description on this ticket: "This operation is considered a raw copy of the user assigned value". The above code snippet allows you to set the current view params to the user assigned value of the parent. If the scope extends beyond the ticket description then I guess I am struggling to understand the use case for this (why does a view need to know about the parent layout params). Part of the 2.0 layout spec was defining default view behavior for various view types and I don't see why a child view should need to know about the default layout behavior of a parent. The whole idea was for each view to have its own layout params that are respected regardless of where that view happens to be. You said: "It's useful when you want to make reusable components and you don't know what the parent width/height is going to be. It could be SIZE, or it could be FILL, but we have no way of knowing when the component is written but we have to support both situations. Note that if you set the width to FILL, and the parent is SIZE, the behavior is undefined." but I don't see how the lack of Ti.UI.INHERIT prevents the creation of reusable UI widgets assuming MW implemented the 2.0 layout spec. Can you provide a more concrete use case of when this would be needed under the 2.0 layout spec?
  14. Bryan Hughes 2012-05-31

    Simple: Ti.UI.Button in mobile Web. It is a horizontal layout view that contains two children: the image and the label. The image is SIZExSIZE, so no problem, but the label needs to be FILLxSIZE so that the text can be centered, left aligned, or right aligned. The problem though is when the dev sets the width of the button to SIZE (or doesn't specify since it's the default). This leads to the case of having a parent of width SIZE and a child of width FILL, which is undefined behavior. Regarding "This operation is considered a raw copy of the user assigned value", that was updated in the comments to be a little different. I'll update the ticket description to match.
  15. Opie Cyrus 2012-05-31

    You are talking about the internal implementation of a Titanium type. Beyond that, you should be able to set the position of a label within a parent view (IE: the image view representing the button) with the "center" property. From a pure HTML standpoint, I know there are other ways to accomplish the centering of the label also. Perhaps we should have a skype over this to discuss in detail.
  16. Bryan Hughes 2012-05-31

    I'm at a conference today, but we can skype tomorrow. I considered all of the options you mentioned, but we couldn't use them for one reason or another (Button has been the source of much pain the past).
  17. Max Stepanov 2012-05-31

    Bryan, in most (if not all) layout implementations such issues are covered by simple _hint_ layout property which acts like a preferred size for a control with FILL when its parent is SIZE. In your particular example: the label with FILL needs a _hint_ to be set to preferred (minimal) width of the text it contains. *Edit*: in any way, if Mobile Web(iOS,Android) needs something like INHERIT/etc for its internal implementations, that's absolutely fine. It should not be just exposed to developers.
  18. Bryan Hughes 2012-05-31

    Max, I just checked the docs and I didn't see a hint property in Ti.UI.View. Is it somewhere else? If you guys don't think that this is useful for other developers, then we can make it a hidden layout param in mobile web. I have no problem with that and it wouldn't be the first time either (mobile web supports 5 layout modes, not just the 3 supported by the other platfosm). I just felt that since I ran into this limitation in the layout system, that other developers might have run into it as well and would like to use the solution that I developed to it.
  19. Max Stepanov 2012-05-31

    Bryan, when I mentioned _hint_ I meant other publicly available layout engines (java, tcl/tk, etc). Sorry for confusion. Basically my proposal is to add _hint_ instead of _INHERIT_ for developers use.
  20. Bryan Hughes 2012-05-31

    Ah, gotcha. That could work. I prefer inherit simply because it's already implemented and working and it means less work for me :), but if you guys think that hint is cleaner from an API perspective then I am all for it.
  21. Opie Cyrus 2012-05-31

    Well, I don't wanna add a new public cross platform API point unless there is a clear use case for it. There may be but the description provided so far doesn't lay out IMO a clear reason to add this. Implementation challenges for a specific platform are not justifiable reasons IMO to add a cross platform API point. If there is a cross platform titanium use case that highlights how this is a problem then I am more than open to investigating this further.
  22. Bryan Hughes 2012-05-31

    The cross-platform use case is if someone wants to create a custom control and bundle it as a module in the marketplace...in that case it is identical to how we create controls in mobile web, just cross-platform.
  23. Max Stepanov 2012-05-31

    Opie, current layout implementation(s) has a few gaps in expected behavior definition. Briefly, there are two kinds of problems: 1. Size determination 2. Excess space distribution Given Bryan's Ti.UI.Button as an example for #1, the size is undefined for a container with SIZE when one of the children is FILL. Having multiple FILL children inside fixed sized container is #2. #1 is usually solved by _hint_. #2 by either _grabExcessSpace_ on one of the children or _weight_ across multiple ones (depending is single/multi child stretching is supported). For the _weights_ case, we have percentages, so it's covered. I'm not saying we need to add it right away, but all this is a part of Allen's and mine layout review process.
  24. Opie Cyrus 2012-05-31

    Well, this is just a matter of codifying the expected behavior IMO rather than exposing a new API point (least in the case of the button example. IMO, when a parent view has SIZE rules and the only child is FILL, nothing would be displayed as SIZE on the parent would take precedence (the child has no knowledge of the grand parent). If the Parent view has a concrete child(set dimensions or SIZE) with another FILL child then the parent would be the size of the concrete child and the FILL child would only expand to the size of the parent. I don't see why a new API point would be needed to support this kind of behavior (beyond a new API point making the layout changes even that more complicated). My whole point in this thread is not that the layout system is perfect - only questioning whether a new API point is needed or not for this issue.
  25. Bryan Hughes 2012-05-31

    The problem with that is this sentence: "the FILL child would only expand to the size of the parent." The size of the parent is SIZE, meaning it doesn't have a size itself. In most cases (including button), we want the FILL child to SIZE to it's contents in this specific case, but FILL in all other cases.
  26. Bryan Hughes 2012-05-31

    OK, I've had a thought. This mechanism is not necessary *if* we do two things: 1) Specify that the size/fill conflict is settled by having FILL items sized to 0 (not the current behavior on mobile web, but can be done pretty easily). This behavior is currently undefined, so it is simply a matter of defining the behavior and making sure the platforms comply (mobile web doesn't). There is already a ticket for this mentioned above by Ivan. 2) Implement support for min width/height (mobile web already has this as a hidden property, although it is currently broken). We can set the width to FILL and the min width to SIZE. This way, the FILL will be smaller than SIZE and will thus give the behavior we want. This will be fixed for mobile web in TIMOB-8696
  27. Opie Cyrus 2012-06-01

    @Bryan When I say "the FILL child would only expand to the size of the parent." I mean that the SIZE parent would be 0 if it's only child was a FILL view or a real value if one of it's children (IE: the concrete child). This covers the use case where a valid child exists with hard dimensions (say a button or label) or the case where a child has no concrete dimensions. For example, if I have a Parent view of SIZE and two children: -1st child is SIZE and its content cause it to be 100x100 -2nd child is FILL and just a view with a background color When the parent view is rendered, you would likely only see the 2nd child filling up 100x100 (would cover up the first child) since the minimum size of the parent is set to the dimensions of the child with the highest concrete dimensions.
  28. Bryan Hughes 2012-06-01

    @Opie Yeah I understand that, but it's not useful to me because that only applies to composite layouts, and I'm really talking about horizontal/vertical layouts.
  29. Lee Morris 2017-03-22

    Closing ticket as invalid with reference to the above comments.

JSON Source