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

Reply via email to