kivy/kivy — pull request #1414 by geojeff (2013-08-06 16:22:11+00:00)
Title: Data changed and selection

Improved the organization of adapter classes, selection, and ListView.

Explored options for, then added variants of ObservableList and ObservableDict to be used in ListProperty and DictProperty, that dispatch for individual changes. After experimenting with names, these variants became OpObservableList and Dict, to signify that these do per-op dispatching.

Replaced the top-down scheme for setting up bindings, where ListView called down to its adapter to request that bindings be set up to methods that update the UI, with the creation of bindings to data_changed() methods in the adapters and in ListView.

data_changed() in the adapters reacts directly from the new per-op change events. These events are what you would expect. For lists, they include set, setitem, delitem, delslice, remove, sort, etc. And, for dicts, they include set, setitem, setdefault, update, etc. For a given op, the adapter.data_changed() code will change cached_views and/or selection. Then, in turn, will dispatch its own data changed event, so that ListView can respond, also in its data_changed() method. ListView makes needed UI changes, in how it manages children, and how it recalculates height and scrolling, etc.

There were many smaller, associated changes, in many cases addressing known issues. For file system changes, kivy.adapters.models.py is now kivy.models.py, because models (now with only a simple SelectableDataItem class) are not adapter specific. This system can also be used for non-view, normal Python classes, or for special applications. Likewise, after Selection was pulled out of the adapters, and became a mixin for them, by similar logic, kivy.adapters.selection.py is now kivy.selection.py. Selection can be used in non-view applications.

This work does not substantially change the ListView API -- there has yet been no removal of templates, addition of dynamic classes in examples, or other bigger changes. However, it does lay better ground work for adapters to be used with collection style widgets other than just ListView, and it aids development of other "controller layer" type improvements.

One thing that has not yet been addressed are scrolling and height calculations, but the framework is there now, in ListView.data_changed() for specific reactions to data change events. We will need to work through the cases, and decide whether for certain changes there should be scroll-to-selection, scroll-to-end, and other similar reactions.