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