Infrastructure for Virtual Widgets

Virtual rendering in the qooxdoo Table widget has proved to be very effective. Over time many features have been added to the table, which has led to a rather complex API. Yet the feature set is still too limited for some use cases.

This project aims to decompose the current table into reusable components with the goal to provide a framework for a variety of virtual widgets, including an replacement for the existing table widget.

Use Cases

A collection of possible virtual widgets.

  • Table: Row-based table like qx.ui.table.Table which exists in qooxdoo now
  • ListView: Ultra fast slim table with a limited set of features like the listview in 0.7
  • Tree: Virtual version of qx.ui.tree.Tree (cf. qx.ui.treevirtual.TreeVirtual)
  • MultiColumnTree: Virtual tree with multiple columns. A combination of table and tree (cf. demo)
  • Grid: An Excel like data grid
  • Property Editor: Like the Table cell editor demo.
  • Gallery: Like icon view in the windows explorer
  • List: Single column list like qx.ui.form.List
  • SelectBox: SelectBox with a virtual list
  • ComboBox: ComboBox with a virtual list
  • OLAP-Table

Features

This is a brainstorming area for features, which a new table and the underlying virtual infrastructure in general could provide.

Virtual Pane

  • vertical virtual rendering
  • horizontal virtual rendering
  • variable row height
  • variable column widths
  • multiple layers (grid lines, selection, cells)
  • row and column span (for effect similar to HTML table's COLSPAN, ROWSPAN)
  • "keepFirstRowVisible" option

Selection

  • Row selection
    • single line
    • multi line
  • Column selection
    • single line
    • multi line
  • Cell selection (a single cell, multiple ranges of cells)
  • Rectangular selection
  • Drag selection

Focus

  • Cell Focus
  • Line Focus
  • Column Focus?

Grid Rendering

  • Row background colors
  • Grid lines

Cell Renderer

  • Custom cell renderer
  • Active cell renderer
    • Open close button in tree folders
    • Links
    • CheckBox cell renderer
  • Use qooxdoo appearances

Editing

  • Cell editing
  • Custom cell editors
  • Line editing

Headers

  • Row header
  • Column header
  • Custom header

Columns

  • Sorting
  • Moving
  • Resizing
  • Auto sizing (cf. ResizeColumnModel)
  • Meta Columns (Freeze Pane)
  • Meta Rows

Model

  • Use new data binding
  • Sorting
  • Filtering
  • Remote

Events

  • Cell events
  • Drag and drop
    • Insert marker

Reports

In conjunction with the "pre-rendering" capability being added to the virtual widgets, where additional rows net yet required to be seen are rendered out of sight, it would be nice to have the ability to pre-render the entire table such that the inner HTML could then be added to a report being generated for printing. Ideally, the page size or area of the page in which the widget is to be rendered could be provided, so that whole rows could be kept on a page (or moved to the next page) if desired.

Other

  • Column visibility menus

Coding Guidelines

Development Process:

  • Unit test for each function
  • test the edge cases

Variable names:

  • x, y for pixel coordinates
  • width, height for cell sizes in pixel
  • row, column for grid coordinate
  • left, top, right, bottom to outer pixel position of a grid cell

Variable order:

  • x before y
  • BUT row before column for grid/table coordinates
  • width before height
  • left before top

Update Strategies

It is important to have a consistent mechanism to update the layers of a virtual pane to avoid superfluous render passes. Further it is important for the user to know how/when to update.

Basically there are four kinds of events, which require an update of all or some aspects of a virtual pane widget:

  1. The initial rendering
  2. The pane's axis configuration changes
    1. the number of rows/columns
    2. default row/column size
    3. size of a specific row/column
  3. The visible view port changes by:
    1. scrolling
    2. pane resize
    3. pane preloading
  4. The data of a specific layer changes. e.g.:
    1. The row color in a Row layer
    2. The line width in a GridLines layer
    3. The cell data in a HtmlCell or WidgetCell layer

Each of these changes may require different kind of updates. Further some of these events may occur at the same time.

Initial Rendering

This is handled by the Pane. During the Pane's first appear event a fullUpdate on all layers is performed. No layer updates will happen before this event.

The pane's axis configuration changes

The Axis objects for the row and column configurations fire change events, if they are changed. The pane listens for these events and performs a fullUpdate on all layers.

The visible view port changes

The pane tracks all changes to the part of the grid and calls updateLayerWindow on each layer.

The data of a specific layer changes

All layers must implement a reload method, which adds the layer to the widget queue and schedules an update of the displayed data.

Where possible the layers handle changes to the data they have to display automatically. In cases where this is not possible this has to be stated in the class documentation.

Layer methods

Each layer provides the following methods:

  1. updateLayerWindow
  2. updateData
  3. fullUpdate

All these methods only schedule the updates by adding the layer to the display queue (qx.ui.core.queue.Display.add(layer)). The concrete implementations of the updates are provided by protected methods with the same name.

This table visualizes, which method is called for each possible event combination:

InitialAxisWindowData
X fullUpdate
X X fullUpdate
X X fullUpdate
X X X fullUpdate
X X fullUpdate
X X X fullUpdate
X X X fullUpdate
X X X X fullUpdate
X fullUpdate
X X fullUpdate
X X fullUpdate
X X X fullUpdate
X updateLayerWindow
X X fullUpdate
X updateData
updateLayerWindow

Only the visible window of the virtual grid has changed. No other changes need to be applied.

updateData

Only the data the layer displays has changed. Row configuration and layer window remain unchanged.

fullUpdate

Perform a full update of the layer. All caches have to be cleared. This methods is a superset of updateData and updateLayerWindow. It can be used instead of those methods but with a potential performance hit.