flex-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Peter Ent <p...@adobe.com>
Subject [FlexJS] Layout Issue/Change
Date Mon, 01 May 2017 14:06:21 GMT
Hi,

My main goal of the recent set of changes to containers and layouts was to make the HTML/CSS/JS
side as minimal as possible, letting the browser and friends take care of things as much as
possible. For the most part, I think it works.  But there is an issue that has been bothering
me.

Right now, the LayoutBase class sets up event listeners on the layout host to automatically
re-run the layout under certain conditions. The more I think about this the less PAYG it is
and it is also inconsistent how things are handled.

The layout code is set up to recognize changes in the layout host's size. When that happens
the layout is re-run. That, to me, is a good thing.

The layout code also waits for the initial "childrenAdded" event and if it sees it, the layout
code will set event listeners for size changes on the children. If you later add children,
those new children may not have listeners attached (this is an inconsistency). It is the responsibility
of the app developer to dispatch a "layoutNeeded" event on the layout host to trigger the
layout. Again, this is inconsistent as a component could dispatch "childrenAdded" while another
component may not.

I see three possibilities here:


  1.  Do nothing with children (PAYG). The layout code would listen for size changes to the
layout host, but it would not set up listeners on the children. An application that changes
an items size or adds or removes an item will have to dispatch "layoutNeeded" on the item's
(or items') parent. This way you can change a component frequently and only trigger its layout
when the changes are complete.
  2.  Do everything (Pay Heavily). The layout code would really try to listen for all sorts
of events on the layout host and respond to them.  The cost would be high however, if a large
number of items were being changed inside of a loop: the layout code would be run for each
pass of the loop.
  3.  Do everything, but wait (Partial Payment). The layout code would do the same as #2,
but allow for updating loops. A number of systems have this: host.beginUpdate(); /* do a bunch
of things */ host.endUpdate(). While the loop is running the layout would ask the host if
it is OK to update and if not, the layout would not run. Once the endUpdate() was executed,
the host would dispatch a final "layoutNeeded" and the layout would run once.

I am in favor of #1. It is in the spirit of PAYG and if you decided you needed either #2 or
#3, you could extend a layout and build that yourself. Or we could add it to the Express package
or something like that.

In choice 1, changing an item's size trigger's its own layout. If you have a Group with 100
elements, all of which are Groups themselves, and you were to resize each sub-Group in a loop,
the resize of a sub-Group would trigger its layout. This is desired behavior. Once that loop
has completed, the outer Group would also need its layout run to account of the newly resized
children and that's where you do: outer.dispatchEvent(new Event("layoutNeeded")); In choice
2 or choice 3, each time a sub-Group was resized, the outer Group's layout would run for a
total of 100 times, which may even cause some of the sub-Group's layouts to run again, depending
on the layout algorithm.

If I were to remove the child event listeners in the layout code, any place your app or example
that counted on the layout running, you would need to add a dispatch event for "layoutNeeded"
if you did not resize the component.

I hope that made sense.
Peter


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message