diff --git a/kivy/adapters/adapter.py b/kivy/adapters/adapter.py index e104a29b4..6757334fc 100644 --- a/kivy/adapters/adapter.py +++ b/kivy/adapters/adapter.py @@ -4,8 +4,15 @@ Adapter .. versionadded:: 1.5 +.. warning:: + + This widget is still experimental, and his API is subject to change in a + future version. + ''' +__all__ = ('Adapter', ) + from kivy.event import EventDispatcher from kivy.properties import ObjectProperty from kivy.lang import Builder @@ -28,16 +35,25 @@ class Adapter(EventDispatcher): Subclasses may override to another data type, such as ListProperty or DictProperty, as appropriate. For example, in ListAdapter, data is a ListProperty. + + :data:`data` is an :class:`~kivy.properties.ObjectProperty`, default + to None. ''' cls = ObjectProperty(None) ''' A class for instantiating a given view item. (Use this or template). + + :data:`cls` is an :class:`~kivy.properties.ObjectProperty`, default + to None. ''' template = ObjectProperty(None) ''' A kv template for instantiating a given view item. (Use this or cls). + + :data:`template` is an :class:`~kivy.properties.ObjectProperty`, default + to None. ''' args_converter = ObjectProperty(None) @@ -47,6 +63,9 @@ class Adapter(EventDispatcher): If an args_converter is not provided, a default one is set that assumes simple content in the form of a list of strings. + + :data:`args_converter` is an :class:`~kivy.properties.ObjectProperty`, + default to None. ''' def __init__(self, **kwargs): diff --git a/kivy/adapters/args_converters.py b/kivy/adapters/args_converters.py index cd2a4db8b..b42a6dadc 100644 --- a/kivy/adapters/args_converters.py +++ b/kivy/adapters/args_converters.py @@ -8,6 +8,7 @@ List Item View Argument Converters The default list item args converter for list adapters is this function that takes a string and returns the string as the text argument in a dict, along with two properties suited for simple text items with height of 25. + ''' list_item_args_converter = lambda x: {'text': x, 'size_hint_y': None, diff --git a/kivy/adapters/dictadapter.py b/kivy/adapters/dictadapter.py index f3bb36f27..d9d72e7b7 100644 --- a/kivy/adapters/dictadapter.py +++ b/kivy/adapters/dictadapter.py @@ -4,6 +4,11 @@ DictAdapter .. versionadded:: 1.5 +.. warning:: + + This widget is still experimental, and his API is subject to change in a + future version. + :class:`DictAdapter` is an adapter around a python dictionary of records. From :class:`ListAdapter`, :class:`DictAdapter` gets these properties: @@ -33,6 +38,8 @@ If you wish to have a bare-bones list adapter, without selection, use ''' +__all__ = ('DictAdapter', ) + from kivy.properties import ListProperty, DictProperty from kivy.lang import Builder from kivy.adapters.listadapter import ListAdapter @@ -47,6 +54,9 @@ class DictAdapter(ListAdapter): provided. If there is an args_converter, the record received from a lookup in the data, using key from sorted_keys, will be passed to it, for instantiation of list item view class instances. + + :data:`sorted_keys` is a :class:`~kivy.properties.ListProperty`, default + to []. ''' data = DictProperty(None) @@ -54,6 +64,9 @@ class DictAdapter(ListAdapter): sorted_keys, or they are a superset of the keys in sorted_keys. The values can be strings, class instances, dicts, etc. + + :data:`data` is a :class:`~kivy.properties.DictProperty`, default + to None. ''' def __init__(self, **kwargs): diff --git a/kivy/adapters/listadapter.py b/kivy/adapters/listadapter.py index 207c5e9e9..f18bc73c0 100644 --- a/kivy/adapters/listadapter.py +++ b/kivy/adapters/listadapter.py @@ -4,10 +4,10 @@ ListAdapter .. versionadded:: 1.5 -ListAdapter -=========== +.. warning:: -.. versionadded:: 1.5 + This widget is still experimental, and his API is subject to change in a + future version. :class:`ListAdapter` is an adapter around a python list. @@ -44,10 +44,17 @@ and several methods used in selection operations. If you wish to have a bare-bones list adapter, without selection, use :class:`SimpleListAdapter`. -:class:`DictAdapter` is a subclass of :class:`ListAdapter`. +:class:`DictAdapter` is a subclass of :class:`ListAdapter`. They both dispatch +the on_selection_change event. + + :Events: + `on_selection_change`: (view, view list ) + Fired when selection changes ''' +__all__ = ('ListAdapter', ) + import inspect from kivy.event import EventDispatcher from kivy.adapters.adapter import Adapter @@ -70,6 +77,9 @@ class ListAdapter(Adapter, EventDispatcher): selection = ListProperty([]) '''The selection list property is the container for selected items. + + :data:`selection` is a :class:`~kivy.properties.ListProperty`, default + to []. ''' selection_mode = OptionProperty('single', @@ -86,6 +96,9 @@ class ListAdapter(Adapter, EventDispatcher): multiple -- multi-touch / incremental addition to selection allowed; may be limited to a count by selection_limit + + :data:`selection_mode` is an :class:`~kivy.properties.OptionProperty`, + default to 'single'. ''' propagate_selection_to_data = BooleanProperty(False) @@ -117,6 +130,10 @@ class ListAdapter(Adapter, EventDispatcher): data. You could accomplish the same functionality by writing code to operate on list selection, but having selection stored on the data might prove convenient in some cases. + + :data:`propagate_selection_to_data` is a + :class:`~kivy.properties.BooleanProperty`, + default to False. ''' allow_empty_selection = BooleanProperty(True) @@ -126,6 +143,10 @@ class ListAdapter(Adapter, EventDispatcher): list displays. Set allow_empty_selection False, so that selection is auto-initialized, and always maintained, and so that any observing views may likewise be updated to stay in sync. + + :data:`allow_empty_selection` is a + :class:`~kivy.properties.BooleanProperty`, + default to True. ''' selection_limit = NumericProperty(-1) @@ -137,6 +158,9 @@ class ListAdapter(Adapter, EventDispatcher): If selection_limit is not set, the default is -1, meaning that no limit will be enforced. + + :data:`selection_limit` is a :class:`~kivy.properties.NumericProperty`, + default to -1 (no limit). ''' cached_views = DictProperty({}) @@ -146,6 +170,9 @@ class ListAdapter(Adapter, EventDispatcher): This dictionary works as a cache. get_view() only asks for a view from the adapter if one is not already stored for the requested index. + + :data:`cached_views` is a :class:`~kivy.properties.DictProperty`, + default to {}. ''' def __init__(self, **kwargs): diff --git a/kivy/adapters/models.py b/kivy/adapters/models.py index 7de58de5f..5e01a34f1 100644 --- a/kivy/adapters/models.py +++ b/kivy/adapters/models.py @@ -1,12 +1,22 @@ ''' +SelectableDataItem +================== + +.. versionadded:: 1.5 + +.. warning:: + + This widget is still experimental, and his API is subject to change in a + future version. + Data Models -=========== +----------- Kivy is open about the type of data used in applications built with the system. However, base classes are optionally needed to conform data to requirements of some parts of the system. -:class:`SelectableDataItem` is a basic `Python data model`_ class that can be +:class:`SelectableDataItem` is a basic Python data model class that can be used as a mixin to build data objects that are compatible with Kivy's adapter and selection system, which works with views such as ListView. The boolean property is_selected is the requirement. @@ -17,21 +27,21 @@ view-only operation. However, in some cases, it is useful to propogate selection to the actual data items. You may, of course, build your own Python data model system as the backend for -a Kivy application. For instance, to use the `Google App Engine datamodeling`_ -system with Kivy, this class could be redefined as: +a Kivy application. For instance, to use the Google App Engine datamodeling +system with Kivy, this class could be redefined as:: from google.appengine.ext import db - class SelectableDataItem(db.Model): + class MySelectableDataItem(db.Model): ... other properties is_selected = db.BooleanProperty() -.. _Python data model: http://docs.python.org/reference/datamodel.html +It is easy to build such a class with plain Python, also. -.. _Google App Engine datamodeling: -https://developers.google.com/appengine/docs/python/datastore/datamodeling ''' +__all__ = ('SelectableDataItem', ) + class SelectableDataItem(object): ''' A mixin class containing requirements for selection operations. diff --git a/kivy/adapters/simplelistadapter.py b/kivy/adapters/simplelistadapter.py index 1d54b92bd..239940412 100644 --- a/kivy/adapters/simplelistadapter.py +++ b/kivy/adapters/simplelistadapter.py @@ -4,11 +4,19 @@ SimpleListAdapter .. versionadded:: 1.5 +.. warning:: + + This widget is still experimental, and his API is subject to change in a + future version. + :class:`SimpleListAdapter` is for simple lists, such as for showing a text-only display of strings, or a list of views of some type that have no user interaction. + ''' +__all__ = ('SimpleListAdapter', ) + from kivy.adapters.adapter import Adapter from kivy.properties import ListProperty from kivy.lang import Builder @@ -38,6 +46,9 @@ class SimpleListAdapter(Adapter): will be used directly if no args_converter function is provided. If there is an args_converter, the data objects will be passed to it, for instantiation of item view class (cls) instances from the data. + + :data:`data` is a :class:`~kivy.properties.ListProperty`, + default to []. ''' def __init__(self, **kwargs): diff --git a/kivy/factory_registers.py b/kivy/factory_registers.py index 0ff43a79d..243af0fbb 100644 --- a/kivy/factory_registers.py +++ b/kivy/factory_registers.py @@ -3,6 +3,11 @@ from kivy.factory import Factory r = Factory.register +r('Adapter', module='kivy.adapters.adapter') +r('ListAdapter', module='kivy.adapters.listadapter') +r('SimpleListAdapter', module='kivy.adapters.simplelistadapter') +r('DictAdapter', module='kivy.adapters.dictadapter') +r('SelectableDataItem', module='kivy.adapters.models') r('Animation', module='kivy.animation') r('AnimationTransition', module='kivy.animation') r('ExceptionHandler', module='kivy.base') @@ -92,6 +97,12 @@ r('Image', module='kivy.uix.image') r('AsyncImage', module='kivy.uix.image') r('Label', module='kivy.uix.label') r('Layout', module='kivy.uix.layout') +r('AbstractView', module='kivy.uix.abstractview') +r('CompositeListItem', module='kivy.uix.listview') +r('ListItemButton', module='kivy.uix.listview') +r('ListItemLabel', module='kivy.uix.listview') +r('ListView', module='kivy.uix.listview') +r('SelectableView', module='kivy.uix.listview') r('ModalView', module='kivy.uix.modalview') r('ProgressBar', module='kivy.uix.progressbar') r('Popup', module='kivy.uix.popup') diff --git a/kivy/uix/__init__.py b/kivy/uix/__init__.py index d4e3b709e..2d438de7c 100644 --- a/kivy/uix/__init__.py +++ b/kivy/uix/__init__.py @@ -31,6 +31,7 @@ Read first: :doc:`api-kivy.uix.widget` :doc:`api-kivy.uix.bubble`, :doc:`api-kivy.uix.dropdown`, :doc:`api-kivy.uix.filechooser`, :doc:`api-kivy.uix.popup`, :doc:`api-kivy.uix.spinner`, + :doc:`api-kivy.uix.listview`, :doc:`api-kivy.uix.listview`, :doc:`api-kivy.uix.tabbedpanel`, :doc:`api-kivy.uix.videoplayer`, :doc:`api-kivy.uix.vkeyboard`, diff --git a/kivy/uix/listview.py b/kivy/uix/listview.py index 7667468b8..4b60d4079 100644 --- a/kivy/uix/listview.py +++ b/kivy/uix/listview.py @@ -4,19 +4,29 @@ List View .. versionadded:: 1.5 +.. warning:: + + This widget is still experimental, and his API is subject to change in a + future version. + The :class:`ListView` widget provides a scrollable/pannable viewport that is clipped at the scrollview's bounding box, which contains a list of list item view instances. -:class:`ListView` implements AbstractView as a vertical scrollable list. -From AbstractView we have these properties and methods: +:class:`ListView` implements :class:`AbstractView` as a vertical scrollable +list. :class:`AbstractView` has one property, adapter. :class:`ListView` sets +adapter to one of: :class:`SimpleListAdapter`, :class:`ListAdapter`, or +:class`DictAdapter`. - - adapter, an instance of SimpleListAdapter, ListAdapter, or DictAdapter + + :Events: + `on_scroll_complete`: (boolean, ) + Fired when scrolling completes. Basic Example ------------- -Here we make a listview with 100 items. +In its simplest form, we make a listview with 100 items:: from kivy.uix.listview import ListView from kivy.uix.gridlayout import GridLayout @@ -47,15 +57,16 @@ When the constructor for :class:`ListView` sees that only a list of strings is provided as an argument, called item_strings, it creates an instance of :class:`SimpleListAdapter` with the list of strings. -Simple in :class:`SimpleListAdapter` means: WITHOUT SELECTION SUPPORT -- it is -just a scrollable list of items, which do not respond to touch events. +Simple in :class:`SimpleListAdapter` means: *without selection support*. It is +a scrollable list of items that do not respond to touch events. To use :class:`SimpleListAdaper` explicitly in creating a ListView instance, -do: +do:: + + simple_list_adapter = SimpleListAdapter( + data=["Item #{0}".format(i) for i in xrange(100)], + cls=Label) - simple_list_adapter = \ - SimpleListAdapter(data=["Item #{0}".format(i) for i in xrange(100)], - cls=Label) list_view = ListView(adapter=simple_list_adapter) The instance of :class:`SimpleListAdapter` has a required data argument, which @@ -72,34 +83,34 @@ selection functionality is often needed. :class:`ListAdapter` and See the :class:`ListAdapter` docs for details, but here are synopses of its arguments: - - data: strings, class instances, dicts, etc. that form the basis data - for instantiating view item classes. +* *data*: strings, class instances, dicts, etc. that form the basis data + for instantiating view item classes. - - cls: a Kivy view that is to be instantiated for each list item. There - are several built-in types available, including ListItemLabel and - ListItemButton, or you can easily make your own. +* *cls*: a Kivy view that is to be instantiated for each list item. There + are several built-in types available, including ListItemLabel and + ListItemButton, or you can easily make your own. - or +* *template*: the name of a Kivy language (kv) template that defines the + Kivy view for each list item. - - template: the name of a Kivy language (kv) template that defines the - Kivy view for each list item. +.. note:: - NOTE: Pick only one, cls or template, to provide as an argument. + Pick only one, cls or template, to provide as an argument. - - args_converter: a function that takes a data item object as input, and - uses it to build and return an args dict, ready - to be used in a call to instantiate the item view cls or - template. In the case of cls, the args dict acts as a - kwargs object. For a template, it is treated as a context - (ctx), but is essentially similar in form. See the - examples and docs for template use. +* *args_converter*: a function that takes a data item object as input, and + uses it to build and return an args dict, ready + to be used in a call to instantiate the item view cls or + template. In the case of cls, the args dict acts as a + kwargs object. For a template, it is treated as a context + (ctx), but is essentially similar in form. See the + examples and docs for template use. - - selection_mode: a string for: 'single', 'multiple' or others (See docs). +* *selection_mode*: a string for: 'single', 'multiple' or others (See docs). - - allow_empty_selection: a boolean, which if False, the default, forces - there to always be a selection, if there is data - available. If True, selection happens only as a - result of user action. +* *allow_empty_selection*: a boolean, which if False, the default, forces + there to always be a selection, if there is data + available. If True, selection happens only as a + result of user action. In narrative, we can summarize with: @@ -108,7 +119,7 @@ In narrative, we can summarize with: instances, using either a cls or a kv template. In a graphic, a summary of the relationship between a listview and its -list adapter, looks like this: +list adapter, looks like this:: - ------------ ListAdapter or DictAdapter ------------ - | | @@ -122,13 +133,13 @@ list adapter, looks like this: :class:`DictAdapter` has the same arguments and requirements as ListAdapter, except for two things: - 1) There is an additional argument, sorted_keys, which must meet the - requirements of normal python dictionary keys. +1) There is an additional argument, sorted_keys, which must meet the + requirements of normal python dictionary keys. - 2) The data argument is, as you would expect, a dict. Keys in the dict - must include the keys in the sorted_keys argument, but they may form a - superset of the keys in sorted_keys. Values may be strings, class - instances, dicts, etc. (The args_converter uses it, accordingly). +2) The data argument is, as you would expect, a dict. Keys in the dict + must include the keys in the sorted_keys argument, but they may form a + superset of the keys in sorted_keys. Values may be strings, class + instances, dicts, etc. (The args_converter uses it, accordingly). Using an Args Converter ----------------------- @@ -139,7 +150,7 @@ template. Whichever type of list item view is used, an args_converter function is needed to prepare, per list data item, args for either a cls or template. Here is an args_converter for use with the built-in :class:`ListItemButton`, -specified as a normal Python function: +specified as a normal Python function:: def args_converter(an_obj): return {'text': an_obj.text, @@ -156,7 +167,7 @@ In the args converter example above, the data item is assumed to be an object (class instance), hence the reference an_obj.text. Here is an example of an args converter that works with list data items that -are dicts: +are dicts:: args_converter = lambda obj: {'text': a_dict['text'], 'size_hint_y': None, @@ -168,7 +179,7 @@ according to the data at hand. An Example ListView ------------------- -Now, to some example code: +Now, to some example code:: from kivy.adapters.list_adapter import ListAdapter from kivy.uix.listview import ListItemButton, ListView @@ -204,7 +215,7 @@ strings, class instances, dictionaries, etc. It is up to the programmer to assure that the args_converter has appropriate functionality. Here we make a simple DataItem class that has the required text and -is_selected properties: +is_selected properties:: from kivy.uix.listview import ListItemButton @@ -243,7 +254,7 @@ The list_vew would then be added to a view with add_widget(). You may also use the provided :class:`SelectableDataItem` mixin to make a custom class. Instead of the "manually-constructed" DataItem class above, -we could do: +we could do:: from kivy.adapters.models import SelectableDataItem @@ -258,7 +269,7 @@ Using an Item View Template :class:`SelectableView` is another simple mixin class that has required properties for a list item: text, and is_selected. To make your own template, -mix it in as follows: +mix it in as follows:: from kivy.uix.listview import ListItemButton from kivy.uix.listview import SelectableView @@ -281,14 +292,13 @@ items -- in addition to ListItemButton, you could have a ListItemLabel, or a custom class you have defined and registered with the system. An args_converter needs to be constructed that goes along with such a kv -template. For example, to use the kv template above: +template. For example, to use the kv template above:: - list_item_args_converter = \ - lambda rec: {'text': rec['text'], - 'is_selected': rec['is_selected'], - 'size_hint_y': None, - 'height': 25} - integers_dict = \ + list_item_args_converter = lambda rec: {'text': rec['text'], + 'is_selected': rec['is_selected'], + 'size_hint_y': None, + 'height': 25} + integers_dict = { str(i): {'text': str(i), 'is_selected': False} for i in xrange(100)} # Here we create a dict adapter with 1..100 integer strings as @@ -305,13 +315,12 @@ template. For example, to use the kv template above: The list_vew would then be added to a view with add_widget(). - Using CompositeItemView ----------------------- The class :class:`CompositeItemView` is another option for building complex composite list items. The kv language approach has its advantages, but here we -build a composite list view using a straight Kivy widget method: +build a composite list view using a straight Kivy widget method:: # This is quite an involved args_converter, so we should go through the # details. A CompositeListItem instance is made with the args @@ -320,8 +329,7 @@ build a composite list view using a straight Kivy widget method: # argument sets for each of the member widgets for this composite: # ListItemButton and ListItemLabel. This is a similar approach to using a # kv template described above. - args_converter = \ - lambda rec: \ + args_converter = lambda rec: {'text': rec['text'], 'size_hint_y': None, 'height': 25, @@ -335,7 +343,7 @@ build a composite list view using a straight Kivy widget method: item_strings = ["{0}".format(index) for index in xrange(100)] - integers_dict = \ + integers_dict = { str(i): {'text': str(i), 'is_selected': False} for i in xrange(100)} # And now the dict adapter, constructed with the item_strings as @@ -363,7 +371,7 @@ in Kivy, we can build a wide range of user interface designs. We could change the data items to contain the names of dog breeds, and connect the selection of dog breed to the display of details in another view, which would update automatically. This is done via a binding to the -on_selection_change event: +on_selection_change event:: list_adapter.bind(on_selection_change=my_selection_reactor_function) @@ -388,9 +396,11 @@ There are so many ways that listviews and related functionality can be used, that we have only scratched the surface here. For on-disk examples, see: kivy/examples/widgets/lists/list_*.py + ''' -__all__ = ('ListView', ) +__all__ = ('SelectableView', 'ListItemButton', 'ListItemLabel', + 'CompositeListItem', 'ListView', ) from kivy.event import EventDispatcher from kivy.clock import Clock @@ -417,11 +427,17 @@ class SelectableView(object): index = NumericProperty(-1) '''The index into the underlying data list or the data item this view represents. + + :data:`index` is a :class:`~kivy.properties.NumericProperty`, default + to -1. ''' is_selected = BooleanProperty(False) '''A SelectableView instance carries this property, which should be kept in sync with the equivalent property in the data item it represents. + + :data:`is_selected` is a :class:`~kivy.properties.BooleanProperty`, default + to False. ''' def __init__(self, **kwargs): @@ -442,7 +458,16 @@ class SelectableView(object): class ListItemButton(SelectableView, Button): selected_color = ListProperty([1., 0., 0., 1]) - deselected_color = None + ''' + :data:`selected_color` is a :class:`~kivy.properties.ListProperty`, + default to [1., 0., 0., 1]. + ''' + + deselected_color = ListProperty([0., 1., 0., 1]) + ''' + :data:`selected_color` is a :class:`~kivy.properties.ListProperty`, + default to [0., 1., 0., 1]. + ''' def __init__(self, **kwargs): super(ListItemButton, self).__init__(**kwargs) @@ -500,14 +525,29 @@ class CompositeListItem(SelectableView, BoxLayout): background_color = ListProperty([1, 1, 1, 1]) '''ListItem sublasses Button, which has background_color, but for a composite list item, we must add this property. + + :data:`background_color` is a :class:`~kivy.properties.ListProperty`, + default to [1, 1, 1, 1]. ''' selected_color = ListProperty([1., 0., 0., 1]) + ''' + :data:`selected_color` is a :class:`~kivy.properties.ListProperty`, + default to [1., 0., 0., 1]. + ''' + deselected_color = ListProperty([.33, .33, .33, 1]) + ''' + :data:`deselected_color` is a :class:`~kivy.properties.ListProperty`, + default to [.33, .33, .33, 1]. + ''' representing_cls = ObjectProperty(None) '''Which component view class, if any, should represent for the composite list item in __repr__()? + + :data:`representing_cls` is an :class:`~kivy.properties.ObjectProperty`, + default to None. ''' def __init__(self, **kwargs): @@ -605,17 +645,26 @@ class ListView(AbstractView, EventDispatcher): container. The container is cleared with a call to clear_widgets() when the list is rebuilt by the populate() method. A padding Widget instance is also added as needed, depending on the row height calculations. + + :data:`container` is an :class:`~kivy.properties.ObjectProperty`, + default to None. ''' row_height = NumericProperty(None) '''The row_height property is calculated on the basis of the height of the container and the count of items. + + :data:`row_height` is a :class:`~kivy.properties.NumericProperty`, + default to None. ''' item_strings = ListProperty([]) '''If item_strings is provided, create an instance of :class:`SimpleListAdapter` with this list of strings, and use it to manage a no-selection list. + + :data:`item_strings` is a :class:`~kivy.properties.ListProperty`, + default to []. ''' scrolling = BooleanProperty(False) @@ -623,6 +672,9 @@ class ListView(AbstractView, EventDispatcher): happening, a call recursion error can occur. scroll_to() checks to see that scrolling is False before calling populate(). scroll_to() dispatches a scrolling_complete event, which sets scrolling back to False. + + :data:`scrolling` is a :class:`~kivy.properties.BooleanProperty`, + default to False. ''' _index = NumericProperty(0)