Title: [chandler2] (grant)[180] Add a better API for single (or multiple) selection in chandler.core.Table
- Revision
- 180
- Author
- grant
- Date
- 2009-03-02 12:48:42 -0800 (Mon, 02 Mar 2009)
Log Message
Add a better API for single (or multiple) selection in chandler.core.Table
Modified Paths
Diff
Modified: trunk/Chandler-Platform/Table.txt (179 => 180)
--- trunk/Chandler-Platform/Table.txt 2009-03-02 20:44:21 UTC (rev 179)
+++ trunk/Chandler-Platform/Table.txt 2009-03-02 20:48:42 UTC (rev 180)
@@ -302,6 +302,60 @@
line corresponding to the empty part of the scroll area of our
hypothetical table.
+Row selections
+--------------
+By default, a :class:`Table` allows a single selected item, accessible via
+the :attr:`~Table.selected_item` API:
+
+>>> table.selected_item.lastName
+u'Topalov'
+>>> table.selected_item is table.items[0]
+True
+
+Note that :attr:`~Table.selected_item` is an optional attribute, so
+it's only set up when you access it. It's initialized by default to be
+the first element in :attr:`~Table.items`.
+
+We can change the selected item by assigning :attr:`~Table.selected_item`:
+
+>>> table.selected_item = players[0]
+>>> table.selected_item.lastName
+u'Morozevich'
+
+It's common enough that you want a :class:`Table` to allow more than
+one selected item, of course. There's an attribute to change that,
+:attr:`~Table.single_item_selection`, which defaults to ``True``
+
+>>> table.single_item_selection
+True
+
+but can be changed:
+
+>>> table.single_item_selection = False
+
+In this case, :attr:`~Table.selection` becomes a
+:class:`~peak.events.collections.SubSet` of items, and
+is empty by default:
+
+>>> table.selection
+SubSet([])
+
+>>> table.selection.update((players[1], players[2]))
+>>> sorted(p.lastName for p in table.selection)
+[u'Anand', u'Topalov']
+
+>>> table.selection.remove(players[1])
+>>> list(table.selection) == [players[2]]
+True
+
+Note that it's OK to use :attr:`~Table.selection` in the
+case of :attr:`~Table.single_item_selection` being ``True``:
+
+>>> table.single_item_selection = True
+>>> list(table.selection) == [table.selected_item]
+True
+
+
TODO
----
Modified: trunk/Chandler-Platform/chandler/core.py (179 => 180)
--- trunk/Chandler-Platform/chandler/core.py 2009-03-02 20:44:21 UTC (rev 179)
+++ trunk/Chandler-Platform/chandler/core.py 2009-03-02 20:48:42 UTC (rev 180)
@@ -505,7 +505,9 @@
subcomponents = Many(inverse=InteractionComponent.scope)
def make_model_cell(self, attr):
- return _RuleCell(lambda: trellis.Cells(self.model)[attr])
+ def get_cell():
+ return trellis.Cells(self.model)[attr]
+ return _RuleCell(get_cell)
@staticmethod
def feature_cells(**kw):
@@ -622,10 +624,39 @@
self.items.sort_key = self.sort_column.sort_key
self.items.reverse = not self.sort_column.sort_ascending
+ new_selection = trellis.attr(resetting_to=None)
+ single_item_selection = trellis.attr(True)
+
@trellis.maintain(initially=None, optional=True)
+ def selection(self):
+ if self.single_item_selection:
+ return trellis.Set([self.selected_item])
+ selection = self.selection
+ new_selected_items = self.new_selection
+
+ if selection is None:
+ if new_selected_items is None:
+ new_selected_items = ()
+ selection = collections.SubSet(new_selected_items, base=self.model)
+ elif new_selected_items is not None:
+ # We are going to do some set arithmetic here to try
+ # to try to make sure we do an update with one
+ # atomic operation
+ diff = set(new_selected_items) # i.e. allow any iterable
+ diff = diff.difference(selection).union(selection.difference(diff))
+ selection.symmetric_difference_update(diff)
+
+ return selection
+
+ @trellis.maintain(initially=None, optional=True)
def selected_item(self):
- if self.selected_item is None or not self.selected_item in self.items:
- return self.items[0] if self.items else None
+ if self.new_selection is not None:
+ return self.new_selection
+ elif self.selected_item is None:
+ try:
+ return iter(self.items).next()
+ except StopIteration, TypeError:
+ pass # i.e. return None
return self.selected_item
def get_cell_value(self, (row, col)):
_______________________________________________
commits mailing list
commits@osafoundation.org
http://lists.osafoundation.org/mailman/listinfo/commits