Source code for napari.utils.events.containers._selectable_list

from typing import TypeVar

from ...translations import trans
from ._evented_list import EventedList
from ._nested_list import NestableEventedList
from ._selection import Selectable

_T = TypeVar("_T")


[docs]class SelectableEventedList(Selectable[_T], EventedList[_T]): """List model that also supports selection. Events ------ inserting (index: int) emitted before an item is inserted at ``index`` inserted (index: int, value: T) emitted after ``value`` is inserted at ``index`` removing (index: int) emitted before an item is removed at ``index`` removed (index: int, value: T) emitted after ``value`` is removed at ``index`` moving (index: int, new_index: int) emitted before an item is moved from ``index`` to ``new_index`` moved (index: int, new_index: int, value: T) emitted after ``value`` is moved from ``index`` to ``new_index`` changed (index: int, old_value: T, value: T) emitted when ``index`` is set from ``old_value`` to ``value`` changed <OVERLOAD> (index: slice, old_value: List[_T], value: List[_T]) emitted when ``index`` is set from ``old_value`` to ``value`` reordered (value: self) emitted when the list is reordered (eg. moved/reversed). selection.changed (added: Set[_T], removed: Set[_T]) Emitted when the set changes, includes item(s) that have been added and/or removed from the set. selection.active (value: _T) emitted when the current item has changed. selection._current (value: _T) emitted when the current item has changed. (Private event) """ def __init__(self, *args, **kwargs) -> None: self._activate_on_insert = True super().__init__(*args, **kwargs) self.events.removed.connect( lambda e: self.selection.discard(e.value) ) # FIXME remove lambda self.selection._pre_add_hook = self._preselect_hook def _preselect_hook(self, value): """Called before adding an item to the selection.""" if value not in self: raise ValueError( trans._( "Cannot select item that is not in list: {value!r}", deferred=True, value=value, ) ) return value
[docs] def insert(self, index: int, value: _T): super().insert(index, value) if self._activate_on_insert: # Make layer selected and unselect all others self.selection.active = value
[docs] def select_all(self): """Select all items in the list.""" self.selection.update(self)
[docs] def remove_selected(self): """Remove selected items from list.""" idx = 0 for i in list(self.selection): idx = self.index(i) self.remove(i) new = max(0, (idx - 1)) if len(self) > new: self.selection.add(self[new])
[docs] def select_next(self, step=1, shift=False): """Selects next item from list.""" if self.selection: idx = self.index(self.selection._current) + step if len(self) > idx >= 0: next_layer = self[idx] if shift: self.selection.add(next_layer) self.selection._current = next_layer else: self.selection.active = next_layer elif len(self) > 0: self.selection.active = self[-1 if step > 0 else 0]
[docs] def select_previous(self, shift=False): """Selects previous item from list.""" self.select_next(-1, shift=shift)
class SelectableNestableEventedList( SelectableEventedList[_T], NestableEventedList[_T] ): pass