diff --git a/examples/widgets/list_cascade.py b/examples/widgets/list_cascade.py index 6c75bf3d6..e3056979f 100644 --- a/examples/widgets/list_cascade.py +++ b/examples/widgets/list_cascade.py @@ -49,15 +49,15 @@ class FruitsListView(SelectionObserver, ListView): super(FruitsListView, self).__init__(**kwargs) # Observed selection is fruit categories list. - def observed_selection_changed(self, observed_selection): - if len(observed_selection.selection) == 0: + def observed_selection_changed(self, list_adapter, selection): + if len(list_adapter.selection) == 0: return # Clear the previously built views. self.item_view_instances = {} # Single selection is operational for fruit categories list. - selected_object = observed_selection.selection[0] + selected_object = list_adapter.selection[0] if type(selected_object) is str: fruit_category = selected_object @@ -72,7 +72,7 @@ class FruitsListView(SelectionObserver, ListView): self.populate() - self.canvas.ask_update() + #self.canvas.ask_update() print 'just added or updated fruit category' @@ -95,12 +95,14 @@ class DetailView(SelectionObserver, GridLayout): self.add_widget( Label(text=str(fruit_data[self.fruit_name][category]))) - def observed_selection_changed(self, observed_selection): - if len(observed_selection.selection) == 0: + def observed_selection_changed(self, list_adapter, selection): + if len(list_adapter.selection) == 0: return - selected_object = observed_selection.selection[0] + selected_object = list_adapter.selection[0] + # Resetting self.fruit_name will trigger call to redraw(). + # [TODO] Why not direct call to redraw here? (And remove binding). if type(selected_object) is str: self.fruit_name = selected_object else: @@ -159,8 +161,8 @@ class CascadingView(GridLayout): # Set the fruits_list_view as an observer of the selection of # the fruit category. - self.fruit_categories_list_adapter.register_selection_observer( - self.fruits_list_view) + self.fruit_categories_list_adapter.bind( + selection=self.fruits_list_view.observed_selection_changed) # Detail view, for a given fruit, on the right: # @@ -169,9 +171,10 @@ class CascadingView(GridLayout): # Manually initialize detail view to show first object of list view, # which will be auto-selected, but the observed_selection_changed - # call would have already fired. + # call would have already fired. [TODO] Evaluate this statement. # - self.fruits_list_adapter.register_selection_observer(self.detail_view) + self.fruits_list_adapter.bind( + selection=self.detail_view.observed_selection_changed) # Data from http://www.fda.gov/Food/LabelingNutrition/\ # FoodLabelingGuidanceRegulatoryInformation/\ diff --git a/examples/widgets/list_disclosure.py b/examples/widgets/list_disclosure.py index 14cbafd2b..4fac7fb49 100644 --- a/examples/widgets/list_disclosure.py +++ b/examples/widgets/list_disclosure.py @@ -161,11 +161,11 @@ class DetailView(SelectionObserver, GridLayout): self.add_widget( Label(text=str(fruit_data[self.fruit_name][category]))) - def observed_selection_changed(self, observed_selection): - if len(observed_selection.selection) == 0: + def observed_selection_changed(self, list_adapter, selection): + if len(list_adapter.selection) == 0: return - selected_object = observed_selection.selection[0] + selected_object = list_adapter.selection[0] if type(selected_object) is str: self.fruit_name = selected_object @@ -214,7 +214,8 @@ class MasterDetailView(GridLayout): # which will be auto-selected, but the observed_selection_changed # call would have already fired. # - self.list_adapter.register_selection_observer(self.detail_view) + self.list_adapter.bind( + selection=self.detail_view.observed_selection_changed) # Data from http://www.fda.gov/Food/LabelingNutrition/\ # FoodLabelingGuidanceRegulatoryInformation/\ diff --git a/examples/widgets/list_master_detail.py b/examples/widgets/list_master_detail.py index 7854029f2..487fa9802 100644 --- a/examples/widgets/list_master_detail.py +++ b/examples/widgets/list_master_detail.py @@ -64,11 +64,11 @@ class DetailView(SelectionObserver, GridLayout): self.add_widget( Label(text=str(fruit_data[self.fruit_name][category]))) - def observed_selection_changed(self, observed_selection): - if len(observed_selection.selection) == 0: + def observed_selection_changed(self, list_adapter, selection): + if len(list_adapter.selection) == 0: return - selected_object = observed_selection.selection[0] + selected_object = list_adapter.selection[0] if type(selected_object) is str: self.fruit_name = selected_object @@ -114,13 +114,8 @@ class MasterDetailView(GridLayout): self.detail_view = DetailView(size_hint=(.7, 1.0)) self.add_widget(self.detail_view) - # Manually initialize detail view to show first object of list view, - # which will be auto-selected, but the observed_selection_changed - # call would have already fired. - # - self.list_adapter.register_selection_observer(self.detail_view) - - self.list_adapter.update_selection() + self.list_adapter.bind( + selection=self.detail_view.observed_selection_changed) # Data from http://www.fda.gov/Food/LabelingNutrition/\ # FoodLabelingGuidanceRegulatoryInformation/\ diff --git a/kivy/uix/listview.py b/kivy/uix/listview.py index a12d431fc..8f1852244 100644 --- a/kivy/uix/listview.py +++ b/kivy/uix/listview.py @@ -34,8 +34,13 @@ item_view_instances. strings representing the item_view_instances, which are instances of the provided cls input argument?). If so, formalize and document. - Address question about "pushing" out to registered selection observers, - vs. using the built-in Kivy event dispatching for an "on_select" event. + vs. using the built-in Kivy bindings system (Will event dispatching work instead of registering/pushing?). Merits? + + ANSWER: Use built-in Kivy system -- no need for observer registration + system and pushing out to registered observers. Just bind + observers to the selection ListProperty. + - Work on item_view_instances marked [TODO] in the code. Examples (in examples/widgets): @@ -143,7 +148,6 @@ class ListAdapter(SelectionSupport, Adapter): def __init__(self, data, **kwargs): if type(data) not in (tuple, list): raise Exception('ListAdapter: input must be a tuple or list') - self.register_event_type('on_select') super(ListAdapter, self).__init__(**kwargs) # Reset and update selection, in SelectionSupport, if data @@ -161,9 +165,6 @@ class ListAdapter(SelectionSupport, Adapter): return None return self.data[index] - def on_select(self, *args): - pass - def get_view(self, index): item = self.get_item(index) if item is None: diff --git a/kivy/uix/mixins/selection.py b/kivy/uix/mixins/selection.py index e3a7d1c29..09ed50f20 100644 --- a/kivy/uix/mixins/selection.py +++ b/kivy/uix/mixins/selection.py @@ -64,25 +64,12 @@ class SelectionSupport(object): # all but simple displays of list items. allow_empty_selection = BooleanProperty(True) - registered_selection_observers = ListProperty([]) - def __init__(self, **kwargs): super(SelectionSupport, self).__init__(**kwargs) self.bind(data=self.initialize_selection, selection_mode=self.initialize_selection, allow_empty_selection=self.initialize_selection) - def register_selection_observer(self, obs): - if isinstance(obs, SelectionObserver): - self.registered_selection_observers.append(obs) - obs.observed_selection_changed(self) - print 'registered_selection_observers:', \ - len(self.registered_selection_observers) - - def unregister_selection_observer(self, obs): - if obs in self.registered_selection_observers: - self.registered_selection_observers.remove(obs) - def handle_selection(self, obj): if obj not in self.selection: if self.selection_mode == 'single' and len(self.selection) > 0: @@ -92,12 +79,6 @@ class SelectionSupport(object): else: self.deselect_object(obj) - # dispatch will use the Kivy property-observing system. - # - # update_selection will push out to registered selection observers. - # - # Which is the way to go? - # self.dispatch('on_select') self.update_selection() print 'selection is now', self.selection @@ -137,9 +118,6 @@ class SelectionSupport(object): print 'selecting first data item view', v, v.is_selected self.handle_selection(self.get_view(0)) - for obs in self.registered_selection_observers: - obs.observed_selection_changed(self) - # Is this needed as special case for resetting? Or can update_selection # be modified for this case? def initialize_selection(self, *args):