Moved SelectableView out of adapters/mixins and into uix, and adjusted examples and tests. Added base Adapter tests, and a test to check views returned from adapters.

This commit is contained in:
geojeff 2012-10-19 09:43:54 -05:00
parent 9fdd3b809c
commit e66d48dbdb
7 changed files with 77 additions and 38 deletions

View File

@ -142,3 +142,17 @@ Notes from Adapter.py:
- Might there be other useful converters to put in
kivy/adapters/args_converters.py, in addition to the default simple
string converter?
- SelectableView was moved out of adapters.mixins and into uix/listview. Was
this the correct thing to do? Are there other cases of view definitions
outside of uix?
- Clean up Factory registrations in examples -- when needed? which classes
have been added to kivy/factory_registers.py.
- CustomListItem, the name for the class created in the examples, list_kv.py,
and list_cascade.py, and also in the test_adapters.py file, is defined only
in the Builder.load_string() call. Better document the special nature of
this in API explanations. (You can't refer to it as a normal class).

View File

@ -1,5 +1,5 @@
from kivy.adapters.dictadapter import DictAdapter
from kivy.adapters.mixins.selection import SelectableView
from kivy.uix.selectableview import SelectableDataItem
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.listview import ListView, ListItemButton

View File

@ -1,5 +1,5 @@
from kivy.adapters.dictadapter import DictAdapter
from kivy.adapters.mixins.selection import SelectableView
from kivy.uix.selectableview import SelectableDataItem
from kivy.uix.listview import ListView, ListItemButton
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
@ -8,6 +8,8 @@ from kivy.factory import Factory
from fixtures import integers_dict
# [TODO] Will SelectableView be in the kivy/factory_registers.py,
# as a result of setup.py? ListItemButton? others?
Factory.register('SelectableView', cls=SelectableView)
Factory.register('ListItemButton', cls=ListItemButton)

View File

@ -18,7 +18,9 @@ From :class:`Adapter`, :class:`SimpleListAdapter` gets these properties:
- args_converter, an optional function to transform data item argument
sets, in preparation for either a cls instantiation,
or a kv template invocation
or a kv template invocation. If no args_converter is
provided, a default one is set, that assumes that the
data items are strings.
From the :class:`SelectionSupport` mixin, :class:`DictAdapter` has
these properties:

View File

@ -24,39 +24,6 @@ class SelectableDataItem(object):
self.is_selected = False
class SelectableView(object):
'''The :class:`SelectableView` mixin is used in list item classes that are
to be instantiated in a list view, which uses a list adapter. select()
and deselect() are to be overridden with display code to mark items as
selected or not, if desired.
'''
index = NumericProperty(-1)
'''The index into the underlying data list or the data item this view
represents.
'''
is_selected = BooleanProperty(False)
'''A SelectableView instance carries this property, and is kept in
sync with the equivalent property in the data item it represents.
'''
def __init__(self, **kwargs):
super(SelectableView, self).__init__(**kwargs)
def select(self, *args):
'''The list item is responsible for updating the display for
being selected, if desired.
'''
pass
def deselect(self, *args):
'''The list item is responsible for updating the display for
being unselected, if desired.
'''
pass
class SelectionSupport(EventDispatcher):
'''The :class:`SelectionSupport` mixin is used for selection. Any
"collection" view, such as :class:`ListView`.

View File

@ -5,12 +5,16 @@ Adapter tests
import unittest
from kivy.adapters.mixins.selection import SelectableDataItem
from kivy.uix.selectableview import SelectableView
from kivy.uix.listview import ListItemButton
from kivy.uix.label import Label
from kivy.adapters.adapter import Adapter
from kivy.adapters.listadapter import SimpleListAdapter
from kivy.adapters.listadapter import ListAdapter
from kivy.adapters.mixins.selection import SelectableDataItem
from kivy.factory import Factory
from kivy.lang import Builder
from nose.tools import raises
@ -235,6 +239,10 @@ class FruitsListAdapter(ListAdapter):
[f for f in fruit_data_items if f.name in category['fruits']]
# [TODO] Needed if setup.py run normally, after merge to master?
Factory.register('SelectableView', cls=SelectableView)
Factory.register('ListItemButton', cls=ListItemButton)
Builder.load_string('''
[CustomListItem@SelectableView+BoxLayout]:
index: ctx.index
@ -278,6 +286,24 @@ class AdaptersTestCase(unittest.TestCase):
msg = 'adapter: a cls or template must be defined'
self.assertEqual(str(cm.exception), msg)
with self.assertRaises(Exception) as cm:
fruit_categories_list_adapter = \
Adapter(data='cat',
args_converter=dummy_converter,
cls=None)
msg = 'adapter: a cls or template must be defined'
self.assertEqual(str(cm.exception), msg)
with self.assertRaises(Exception) as cm:
fruit_categories_list_adapter = \
Adapter(data='cat',
args_converter=dummy_converter,
template=None)
msg = 'adapter: a cls or template must be defined'
self.assertEqual(str(cm.exception), msg)
with self.assertRaises(Exception) as cm:
fruit_categories_list_adapter = \
Adapter(data='cat',
@ -337,6 +363,14 @@ class AdaptersTestCase(unittest.TestCase):
adapter_2 = Adapter(**kwargs_2)
self.assertEqual(adapter_2.args_converter, list_item_args_converter)
adapter = Adapter(data='cat', cls=Label)
self.assertEqual(adapter.get_count(), 1)
self.assertEqual(adapter.get_item(0), 'cat')
adapter = Adapter(data=None, cls=Label)
self.assertEqual(adapter.get_count(), 0)
self.assertEqual(adapter.get_item(0), None)
def test_instantiating_simple_list_adapter(self):
# with no data
with self.assertRaises(Exception) as cm:
@ -470,6 +504,8 @@ class AdaptersTestCase(unittest.TestCase):
self.assertEqual(str(cm.exception), msg)
def test_view_from_list_adapter(self):
# First with a class.
list_item_args_converter = \
lambda selectable: {'text': selectable.name,
'size_hint_y': None,
@ -484,3 +520,21 @@ class AdaptersTestCase(unittest.TestCase):
view = fruit_categories_list_adapter.get_view(0)
self.assertTrue(isinstance(view, ListItemButton))
# Now with a template.
list_item_args_converter = \
lambda selectable: {'text': selectable.name,
'is_selected': selectable.is_selected,
'size_hint_y': None,
'height': 25}
fruit_categories_list_adapter = \
ListAdapter(data=category_data_items,
args_converter=list_item_args_converter,
selection_mode='single',
allow_empty_selection=False,
template='CustomListItem')
view = fruit_categories_list_adapter.get_view(0)
self.assertEqual(view.__class__.__name__, 'CustomListItem')

View File

@ -288,8 +288,8 @@ from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.adapters.listadapter import SimpleListAdapter
from kivy.adapters.mixins.selection import SelectableView
from kivy.uix.abstractview import AbstractView
from kivy.uix.selectableview import SelectableView
from kivy.properties import ObjectProperty, DictProperty, \
NumericProperty, ListProperty, BooleanProperty
from kivy.lang import Builder