Greg,

I think this thread got forked somehow.  If you have a simple test case I can 
try to look at it this weekend.

I don't doubt that the changes you propose work for you, but they make me 
nervous although I'm not the best at reading code and understanding what it 
does.  Here's a brain dump on layout in case it helps.

In Flex, parents always size their children.  The children probably shouldn't 
override that size or if they do they have to be careful that it doesn't 
trigger the another layout in the parent in a way that you run layout forever 
(a "layout loop").  In Flex, because of the LayoutManager running on frame 
events, that generally doesn't freeze the UI and I have seen situations where 
the LayoutManager never goes idle even though the app appears to be running 
fine.  There is also the case where the first layout pass results in scrollbars 
which causes children to adjust and results in the removal of scrollbars and 
that loops forever with the scrollbars blinking on and off.  In Royale, there 
is a greater chance of hanging.  

Also in Flex, with the LayoutManager, EVERY widget added itself to the 
LayoutManager ensuring validation in a particular order, enforcing the "parents 
size children" rule.

In Royale, I tried to go without a LayoutManager because we started out 
targeting IE8 and I wasn’t sure if there were some things that were exceptions 
to requestAnimationFrame (like setting text or sizing images).  To this day, 
I'm concerned that it will create an poor debugging experience because I think 
when you hit breakpoints the screen updates.  All of those things need testing 
before we try a LayoutManager based on requestAnimationFrame.  And then, as I 
think you mentioned, we have to be concerned about how much code is going to 
run if we start running all of the validation methods.

On the other hand, I think Royale runs layout too often still because two 
property changes can trigger two layout passes.  I looked at BoxLayout which 
extends LayoutBase which does already watch for 
widthChanged/heightChanged/sizeChanged so whatever is the root cause of your 
problem may not be triggering the layout pass you want, although the code paths 
in LayoutBase.childResizeHandler are there to prevent layout loops.

Usually, in Flex, a component didn't change its size in response to user 
interaction or data loading, it changed its measured size and called 
invalidateSize on itself and its parent.  The LayoutManager measured children 
before parents, then layed out parents before children.

In Royale, there is little to no measurement subsystem.  That's because we rely 
on the browser to "immediately" measure by setting offsetWidth/offsetHeight 
saving us the impossible task of writing code to guess at how the browser 
measures.  For PAYG reasons in Basic, there is no code looking for changes that 
should trigger a layout other than possibly child size changes.  Everything 
else is supposed to use LayoutChangeNotifier to wire the one event that signals 
a change to the container/layout that cares.

In MXRoyale, there are complex components that can't rely on offsetWidth/Height 
since MXRoyale cannot rely on browser layout because of things like overriding 
the meaning of width=100%.   MXRoyale has measure() methods from Flex, but they 
don't always get run because there is no LayoutManager measuring the children 
before the parents and existing measure() methods expect the children to have 
been measured.  It might be that is the root cause here.  That some or all 
invalidateSize() calls need to call measure() and then instead of calling 
layoutNeeded on the parent, call the parent's invalidateSize until somehow we 
know we've gone far enough up the chain to start laying out again.

HTH,
-Alex


On 6/4/20, 1:51 PM, "Greg Dove" <greg.d...@gmail.com> wrote:

    'I don’t think we’ve dealt with a lot of children changing sizes (other
    than Images loading late and a few other things) so it may be time to
    listen to widthChanged/heightChanged/sizeChanged as children get added if
    there isn’t already code doing that.'
    
    That would be another way of doing it. There is already this code [1] that
    is swf-only but seems to only be relevant before sawInitComplete.
    
    But if the children run their layouts when their own size changes, then
    they can notify their parent as well if the size changed either before or
    during layout. That's sort of what I was trying to do with the
    ContainerView change I mentioned earlier. It checks size for change in
    beforeLayout and again in afterLayout and then requests parent layout if it
    thinks the parent needs to do something that could affect parent layout or
    even re-apply its own rules to the current target. In this way there is not
    a need to add listeners to every child. But I expect there are some
    downsides or things I cannot see with what I did so far because I have not
    spent a lot of time in this code, as you have. I'll post more details in
    the github issue at my EOD.
    
    1.
    
https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Froyale-asjs%2Fblob%2F9c70b052a6fef3ebe7c6a07ca887af4f7381d46f%2Fframeworks%2Fprojects%2FCore%2Fsrc%2Fmain%2Froyale%2Forg%2Fapache%2Froyale%2Fcore%2FLayoutBase.as%23L131&amp;data=02%7C01%7Caharui%40adobe.com%7C6386a0b1feaa464dab7c08d808c9126c%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637269006974198657&amp;sdata=Mrz28G2QGTZDNSRqZuLyrHe52Q2yje7Y2qUZA%2BroK0k%3D&amp;reserved=0
    
    On Fri, Jun 5, 2020 at 3:32 AM Alex Harui <aha...@adobe.com.invalid> wrote:
    
    > Serkan, is there a bug tracking your layout issue?
    >
    > There should be a difference between first layout if all children have
    > known sizes and what Greg is describing which is responding to children
    > changing sizes.  I don’t think we’ve dealt with a lot of children changing
    > sizes (other than Images loading late and a few other things) so it may be
    > time to listen to widthChanged/heightChanged/sizeChanged as children get
    > added if there isn’t already code doing that.
    >
    > There might be other issues with containers having an inner contentArea
    > that might be getting in the way too.
    >
    > HTH,
    > -Alex
    >
    > From: Yishay Weiss <yishayj...@hotmail.com>
    > Reply-To: "dev@royale.apache.org" <dev@royale.apache.org>
    > Date: Thursday, June 4, 2020 at 4:30 AM
    > To: "dev@royale.apache.org" <dev@royale.apache.org>
    > Subject: RE: MXRoyale layout issues - questions/discussion
    >
    > Call me lazy but this is a bit difficult to parse. If you can spare some
    > time, maybe come up with a GitHub issue that describes a concrete case so
    > we can discuss this.
    >
    > > I think the layouts work downward for this, but changes in the children
    > don't seem to trigger the parent layout.
    >
    > Yes, I’ve seen that as well. Alex’s advice when I pointed it out to him
    > was to just add a parent.dispatchEvent(new Event(‘layoutNeeded’)) if it
    > solves a concrete bug. It’s true that this could result in a performance
    > hit. If that’s your issue then I guess we can discuss emulation of the
    > layout manager or some other optimization.
    >
    >
    > From: Greg Dove <greg.d...@gmail.com>
    > Sent: Thursday, June 4, 2020 11:12:08 AM
    > To: Apache Royale Development <dev@royale.apache.org>
    > Subject: MXRoyale layout issues - questions/discussion
    >
    > Hi,
    >
    > Just wondered if anyone else is dealing with layout issues in Flex
    > emulation. I have some layout issues that are slowing my progress on a
    > project, and I'd like to resolve them as quickly as I can.
    >
    > In particular, I see issues with BoxLayout-based containers which have
    > percentWidth or percentHeight set. These don't get determined as having
    > width or height 'SizedToContent' when performing layout, but in many
    > situations they behave in a similar way (they can change their size based
    > on their content in terms of layout rules applied by the parent 
container).
    > This is because in Flex, percentages are not simply a percentage of their
    > parent, but they follow something perhaps a little closer to flexbox 
layout
    > rules for all the percentWidth or percentHeight siblings (managed by their
    > parent's layout). In other words, they are also related to the measured
    > size of their content if the parent needs to manage them (I'm not sure how
    > best to describe this, but I think that sort of captures it). They can
    > expand beyond their percent allocation or contract below it depending on
    > their measured sizes.
    > I think the layouts work downward for this, but changes in the children
    > don't seem to trigger the parent layout.
    >
    > An example might be
    > <mx:HBox id='addThingsToMe' width='50%' />
    >
    > If you have the above at the application level (where the application has
    > vertical layout) and keep adding buttons (for example) to the HBox via a 
UI
    > test button that adds a new Button to that on each click, then it should
    > expand horizontally greater than 50% width when the volume of buttons
    > exceeds its nominal 50% width. It is definitely easier to see this if you
    > add a border to the container.
    >
    > I have been working on this, and made progress, but the approach I am 
using
    > feels a bit patchwork, and just wondered whether others are seeing 
anything
    > like this, and/or how it has been addressed elsewhere....
    >
    > Here's a summary of some of the things I have been trying, which do yield
    > improvements, but don't really solve the problem completely:
    >
    > 1. added extra listener for 'childrenRemoved' in BoxLayout strand setter.
    >
    > 2. Created a new mx 'ContainerView' class
    > (mx.containers.beads.ContainerView extends
    > org.apache.royale.html.beads.ContainerView)
    > This has the following in it:
    >
    > private var widthBefore:Number = -1
    > private var heightBefore:Number = -1;
    > private var sizeChangedBeforeLayout:Boolean;
    >
    > COMPILE::JS
    > override public function beforeLayout():Boolean
    > {
    > var container:Container = host as Container;
    >
    > sizeChangedBeforeLayout = (widthBefore != container.width || heightBefore
    > != container.height);
    > widthBefore = container.width;
    > heightBefore = container.height;
    > return super.beforeLayout();
    > }
    >
    >     COMPILE::JS
    >     override public function afterLayout():void
    >     {
    >         var container:Container = host as Container;
    > //size might change during layout
    > var sizeChangedDuringLayout:Boolean = !sizeChangedBeforeLayout &&
    > (widthBefore != container.width || heightBefore != container.height);
    > if (sizeChangedDuringLayout) {
    > //prepare for next time
    > widthBefore = container.width;
    > heightBefore = container.height;
    > }
    > var requestParentLayout:Boolean = sizeChangedBeforeLayout
    > || sizeChangedDuringLayout
    >           || (!isNaN(container.percentWidth) && container.width <
    > container.measuredWidth) || (!isNaN(container.percentHeight) &&
    > container.height < container.measuredHeight);
    >         if (requestParentLayout && container.parent is Container) {
    > trace('requesting parent layout of ',(container as
    > Object).ROYALE_CLASS_INFO.names[0].qName );
    >             (container.parent as Container).layoutNeeded();
    >         }
    >     }
    >
    > That is pretty much it, and it is being used as a replacement in my local
    > MXRoyale css for Container:
    >
    >  /*IBeadView:
    > ClassReference("org.apache.royale.html.beads.ContainerView");*/
    > IBeadView: ClassReference("mx.containers.beads.ContainerView");
    >
    > I'm not saying this is right, but it does help quite a bit with what I am
    > facing.
    >
    > In addition to BoxLayout in general, I have been working on the
    > Grid/GridRow/GridItem layouts which are more specific in terms of layout
    > changes needed, but also can have similar problems.
    >
    >
    > Although I am seeing improvements with what I have done so far, I'm not
    > really satisfied with it, and I am keen for input/discussion (or
    > collaboration). I have been pursuing what I would mostly describe as a
    > 'workaround' approach, so would welcome any thoughts on how best to tackle
    > this.
    > I think there is something missing because of the way Flex does layouts 
vs.
    > the way Royale does it, but I can't describe it fully yet. Perhaps things
    > are only currently envisaged to work with mxml declarative content onto
    > display and not so much with dynamic updates. But I think state-based
    > changes could have similar effects for some of these things if they happen
    > inside containers that have their own percent dimensions.
    >
    >
    > Thanks,
    > Greg
    > From: Greg Dove<mailto:greg.d...@gmail.com>
    > Sent: Thursday, June 4, 2020 11:12 AM
    > To: Apache Royale Development<mailto:dev@royale.apache.org>
    > Subject: MXRoyale layout issues - questions/discussion
    >
    > Hi,
    >
    > Just wondered if anyone else is dealing with layout issues in Flex
    > emulation. I have some layout issues that are slowing my progress on a
    > project, and I'd like to resolve them as quickly as I can.
    >
    > In particular, I see issues with BoxLayout-based containers which have
    > percentWidth or percentHeight set. These don't get determined as having
    > width or height 'SizedToContent' when performing layout, but in many
    > situations they behave in a similar way (they can change their size based
    > on their content in terms of layout rules applied by the parent 
container).
    > This is because in Flex, percentages are not simply a percentage of their
    > parent, but they follow something perhaps a little closer to flexbox 
layout
    > rules for all the percentWidth or percentHeight siblings (managed by their
    > parent's layout). In other words, they are also related to the measured
    > size of their content if the parent needs to manage them (I'm not sure how
    > best to describe this, but I think that sort of captures it). They can
    > expand beyond their percent allocation or contract below it depending on
    > their measured sizes.
    > I think the layouts work downward for this, but changes in the children
    > don't seem to trigger the parent layout.
    >
    > An example might be
    > <mx:HBox id='addThingsToMe' width='50%' />
    >
    > If you have the above at the application level (where the application has
    > vertical layout) and keep adding buttons (for example) to the HBox via a 
UI
    > test button that adds a new Button to that on each click, then it should
    > expand horizontally greater than 50% width when the volume of buttons
    > exceeds its nominal 50% width. It is definitely easier to see this if you
    > add a border to the container.
    >
    > I have been working on this, and made progress, but the approach I am 
using
    > feels a bit patchwork, and just wondered whether others are seeing 
anything
    > like this, and/or how it has been addressed elsewhere....
    >
    > Here's a summary of some of the things I have been trying, which do yield
    > improvements, but don't really solve the problem completely:
    >
    > 1. added extra listener for 'childrenRemoved' in BoxLayout strand setter.
    >
    > 2. Created a new mx 'ContainerView' class
    > (mx.containers.beads.ContainerView extends
    > org.apache.royale.html.beads.ContainerView)
    > This has the following in it:
    >
    > private var widthBefore:Number = -1
    > private var heightBefore:Number = -1;
    > private var sizeChangedBeforeLayout:Boolean;
    >
    > COMPILE::JS
    > override public function beforeLayout():Boolean
    > {
    > var container:Container = host as Container;
    >
    > sizeChangedBeforeLayout = (widthBefore != container.width || heightBefore
    > != container.height);
    > widthBefore = container.width;
    > heightBefore = container.height;
    > return super.beforeLayout();
    > }
    >
    >     COMPILE::JS
    >     override public function afterLayout():void
    >     {
    >         var container:Container = host as Container;
    > //size might change during layout
    > var sizeChangedDuringLayout:Boolean = !sizeChangedBeforeLayout &&
    > (widthBefore != container.width || heightBefore != container.height);
    > if (sizeChangedDuringLayout) {
    > //prepare for next time
    > widthBefore = container.width;
    > heightBefore = container.height;
    > }
    > var requestParentLayout:Boolean = sizeChangedBeforeLayout
    > || sizeChangedDuringLayout
    >           || (!isNaN(container.percentWidth) && container.width <
    > container.measuredWidth) || (!isNaN(container.percentHeight) &&
    > container.height < container.measuredHeight);
    >         if (requestParentLayout && container.parent is Container) {
    > trace('requesting parent layout of ',(container as
    > Object).ROYALE_CLASS_INFO.names[0].qName );
    >             (container.parent as Container).layoutNeeded();
    >         }
    >     }
    >
    > That is pretty much it, and it is being used as a replacement in my local
    > MXRoyale css for Container:
    >
    >  /*IBeadView:
    > ClassReference("org.apache.royale.html.beads.ContainerView");*/
    > IBeadView: ClassReference("mx.containers.beads.ContainerView");
    >
    > I'm not saying this is right, but it does help quite a bit with what I am
    > facing.
    >
    > In addition to BoxLayout in general, I have been working on the
    > Grid/GridRow/GridItem layouts which are more specific in terms of layout
    > changes needed, but also can have similar problems.
    >
    >
    > Although I am seeing improvements with what I have done so far, I'm not
    > really satisfied with it, and I am keen for input/discussion (or
    > collaboration). I have been pursuing what I would mostly describe as a
    > 'workaround' approach, so would welcome any thoughts on how best to tackle
    > this.
    > I think there is something missing because of the way Flex does layouts 
vs.
    > the way Royale does it, but I can't describe it fully yet. Perhaps things
    > are only currently envisaged to work with mxml declarative content onto
    > display and not so much with dynamic updates. But I think state-based
    > changes could have similar effects for some of these things if they happen
    > inside containers that have their own percent dimensions.
    >
    >
    > Thanks,
    > Greg
    >
    >
    

Reply via email to