Source code for simvx.core.selection
"""Multi-select selection system for editor use."""
from __future__ import annotations
import logging
log = logging.getLogger(__name__)
class _Signal:
def __init__(self):
self._callbacks: list = []
def connect(self, fn):
self._callbacks.append(fn)
def emit(self):
for cb in self._callbacks:
cb()
[docs]
class Selection:
"""Tracks an ordered set of selected items with change notification."""
def __init__(self):
self._items: list = []
self.selection_changed = _Signal()
# -- properties ----------------------------------------------------------
@property
def items(self) -> list:
return list(self._items)
@property
def count(self) -> int:
return len(self._items)
@property
def primary(self) -> object | None:
return self._items[0] if self._items else None
@property
def empty(self) -> bool:
return not self._items
# -- mutators -------------------------------------------------------------
[docs]
def select(self, item, *, additive: bool = False):
"""Select *item*. If *additive*, toggle it; otherwise replace."""
if additive:
self.toggle(item)
return
changed = self._items != [item]
self._items = [item]
if changed:
self.selection_changed.emit()
[docs]
def deselect(self, item):
if item in self._items:
self._items.remove(item)
self.selection_changed.emit()
[docs]
def toggle(self, item):
if item in self._items:
self._items.remove(item)
else:
self._items.append(item)
self.selection_changed.emit()
[docs]
def clear(self):
if self._items:
self._items.clear()
self.selection_changed.emit()
[docs]
def select_all(self, items):
self._items = list(items)
self.selection_changed.emit()
# -- queries --------------------------------------------------------------
[docs]
def is_selected(self, item) -> bool:
return item in self._items
[docs]
def __contains__(self, item):
return item in self._items
[docs]
def __iter__(self):
return iter(self._items)
[docs]
def __len__(self) -> int:
return len(self._items)