For the past few weeks, as I've had a minute here and a minute there to look
at qooxdoo, I've been considering the best way to make the Tree widgets
virtual; i.e. to render only one "page" of elements of the tree at a time.
With large lists of files/folders/whatever listed in the tree, the current
implementations can take excessively long to render -- measured in 10s of
seconds or longer in Firefox; much longer in IE, so converting it to be
virtual should have great benefit in rendering speed.

I have a few options for implementing virtualization of the Tree widgets.

1. I could do a one-time customization of TreeFullControl (and optionally,
   Tree), to make it (them) virtual.  This would be entirely custom code,
   useful only to the Tree widget(s).  This is the easiest option, but not
   otherwise generally useful.

2. Alternatively, I could attempt to render the Tree into a Table widget.  I
   like this concept, but unfortunately, the Table widget does not allow
   placing arbitrary widgets in Cells.  As currently implemented, it wants to
   render the HTML for Cells (via an appropriate CellRenderer class) rather
   than handling all of the intricacies of widgets (e.g. events).  For a Tree,
   I need to have the +/- icon, a folder/file icon, etc. rendered, and be able
   to click on various things to cause actions.  Making this work with Table
   seems like it will require much rewriting of some internal classes.

3. A much more sophisticated implementation would be instead to implement a
   virtual scrolling Canvas widget, and have the Tree widgets provide the
   whole set of what's to be display to this virtual Canvas, letting the
   Canvas actually render only those portions which are visible.

The remainder of this message refers to option 3, as it seems to have the most
general usefulness.

The details of doing this are tricky.  Without the ability to determine the
sizes of widgets prior to rendering them, only fixed-size elements could be
used.  Once the layout mechanism is modified to allow determining the size
that a widget "will be" once layed out, nearly any widget could be placed on
the virtual Canvas.

Due to the inability to calculate arbitrary sized widgets' layed-out size, I'm
currently considering a virtual "Ruled Canvas" widget.  A Ruled Canvas, like
ruled paper, has a fixed number of rows of a fixed height and width.  This
makes it similar to the Table widget, but with some significant differences:

 - In a RuledCanvas widget, widgets are placed into rows, whereas in the
   Table widget, the value placed into a cell is (typically, at least) HTML.
   By having widgets placed in the rows, all of the advantage of qooxdoo
   widgets is retained (e.g. events, automatic sizing, etc.)

 - In RuledCanvas, the rendering of widgets placed in a row of the canvas is
   left to the widgets themselves, whereas in the Table widget, the HTML to
   render a call is implemented within the Table widget (and its constituent
   helper classes).

 - In RuledCanvas, each row is entirely independent.  There are no columns
   which transcend all rows as there are in Table.  If columns are implemented
   within a RuledCanvas row and, for example, are resizable, resizing a column
   in one row would have no automatic effect on other rows.  (It would
   certainly be possible to handle an event generated when one row's column is
   resized and apply that to the other rows as well.  If this concept turns
   out to be efficient, reimplementing Table and its TablePane in terms of
   RuledCanvas may even make sense, but that's not a part of my currently
   envisioned work.)

To implement Tree widgets in terms of RuledCanvas, I'm thinking that a set of
tree rows, in some Programatically Useful Form (PUF), would be provided to the
RuledCanvas.  As RuledCanvas wishes to render a tree row, it calls a provided
callback function in the Tree class, passing the HorizontalBoxLayout of the
RuledCanvas row and the PUF for the Tree row back to the Tree class, which adds
the appropriate widgets for that row to the HorizontalBoxLayout.

This becomes a multi-step rendering process: The Tree wants to display stuff
and queues tree elements and adds itself to the Global Queue.  The Global
Queue is processed at some point, and Tree's flushQueue() is called.
flushQueue() generates the PUFs for each tree row and provides them to the
RuledCanvas.  That completes the Tree queue flush process, but leaves the
RuledCanvas in a state where it has widgets requiring rendering.  RuledCanvas
adds itself to the Global Queue.

When RuledCanvas's flush function is called, it determines which rows are to
be displayed, and for each row, calls the Tree-provided callback function as
described above.

Does this whole concept make any sense?  Does this multi-step rendering have a
hope of being sufficiently efficient as to be worthwhile?  It seems to me that
a generalized virtual Canvas could ultimately become very useful.  Even a
RuledCanvas is likely to find uses other than for Tree rendering.

Thoughts?  Ideas for improvement?

Thanks!

Derrell

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
qooxdoo-devel mailing list
qooxdoo-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel

Reply via email to