NewModelViewArchitecture
Homepage for the WIP Model-View architecture for CEGUI widgets!
Introduction
The new architecture aims to unify the underlying implementation of several widgets so that they will use a common base model provider. This will involve a lot of ABI and API breakage.
Proposed architecture
TODO - decide on another concepts than row/column
ModelIndex
Identifies uniquely items in the model.
Properties:
- row : size_t
- column : size_t
- parent : ModelIndex *
- indexModelData : void *
Methods:
- isValid
ItemModel
The model for the view, that provides data like items count to the view. This is implemented by the developers that want to use this new architecture.
Structure-related methods:
- rowCount(modelIndex)
- columnCount(modelIndex)
- makeIndex(row, column, parentModelIndex)
- getParentIndex(modelIndex)
Data-provider methods:
- getString(modelIndex)
- getImage(modelIndex)
Events:
- Rows/ColumnsAdded - startIndex, count
- Rows/ColumnsRemoved - startIndex, count
- Rows/ColumnsDataChanged - startIndex, count
TODO: Should we instead allow for a rectangular notification area? Like: startIndex / endIndex ?
ModelIndex Invalidation
Views might (read: will) store indices for a faster rendering or operations on the view. But these indices might become invalid if:
- the underlying model instance changes (i.e.: model is set to another instance)
- Solution: Just invalidate the memorized indices
- an index from the "middle" is removed
- Solution1: Create persistent model indices, like Qt does.
- Con: too much management required, prone to errors.
- Solution2: Query the model for validity
- isValid will be moved to the ViewModel
- Solution3: Other?
- Solution1: Create persistent model indices, like Qt does.
Affected widgets
Changed (to the new architecture) widgets
- ComboBox + ComboDropList -> ComboView
- Tree -> TreeView
- ListBox -> ListView
New widgets
- GridView
- ListBoxWidget (combines model & view together for simple usage cases)
Removed/deprecated widgets
- MultiColumnList (replaced by GridView)
- ItemListbox (duplicated by ListBox)
To decide
- ItemListBase
- It's used in other places like: MenuBase and ScrolledItemListBase
- Remove the other usages as well?
Workflow examples
List rendering
- Create root model index (parent=0)
- Query the number of rows for root
- For each row (value=[0, rowCount))
- Create row model index (row=current row value, parent=rootModelIndex)
- Query the image to be displayed for row index
- Draw image
- Query the text to be displayed for row index
- Draw text
- Render non-row elements
Tree rendering
Full/first-time rendering
Triggered first time, or when whole model changes.
Recursive rendering procedure starting with a model index
- > Given a parent model index
- Query the number of rows for index
- For each row (value=[0, rowCount))
- Create row model index (row=current row value, parent=parent<odelIndex)
- Query the image to be displayed for row index
- Draw image
- Query the text to be displayed for row index
- Draw text
- Call procedure with row model index.
Actual rendering:
- Call procedure defined above with root model index (parent = 0)
- Render non-row elements
Item(s) modified/isolated rendering
Triggered when some parts of the model changed, but not all.