1
0
mirror of https://github.com/arsenetar/dupeguru.git synced 2026-01-22 14:41:39 +00:00

Improved hscommon.gui docs

This commit is contained in:
Virgil Dupras
2013-11-24 13:53:52 -05:00
parent 0b00171655
commit da06ef8cad
7 changed files with 211 additions and 30 deletions

View File

@@ -11,6 +11,22 @@ from collections import Sequence, MutableSequence
from .base import GUIObject
class Selectable(Sequence):
"""Mix-in for a ``Sequence`` that manages its selection status.
When mixed in with a ``Sequence``, we enable it to manage its selection status. The selection
is held as a list of ``int`` indexes. Multiple selection is supported.
.. attribute:: selected_index
*int*. *get/set*. Thin wrapper around :attr:`selected_indexes`. Points to the first selected
index or ``None`` if it's empty. Using this property only makes sense if your selectable
sequence supports single selection only.
.. attribute:: selected_indexes
*list*. *get/set*. List of selected indexes. When setting the value, automatically removes
out-of-bounds indexes. The list is kept sorted.
"""
def __init__(self):
self._selected_indexes = []
@@ -26,16 +42,30 @@ class Selectable(Sequence):
#--- Virtual
def _update_selection(self):
# Takes the table's selection and does appropriates updates on the view and/or model, when
# appropriate. Common sense would dictate that when the selection doesn't change, we don't
# update anything (and thus don't call _update_selection() at all), but there are cases
# where it's false. For example, if our list updates its items but doesn't change its
# selection, we probably want to update the model's selection. A redesign of how this whole
# thing works is probably in order, but not now, there's too much breakage at once involved.
pass
"""(Virtual) Updates the model's selection appropriately.
Called after selection has been updated. Takes the table's selection and does appropriates
updates on the view and/or model. Common sense would dictate that when the selection doesn't
change, we don't update anything (and thus don't call ``_update_selection()`` at all), but
there are cases where it's false. For example, if our list updates its items but doesn't
change its selection, we probably want to update the model's selection.
By default, does nothing.
Important note: This is only called on :meth:`select`, not on changes to
:attr:`selected_indexes`.
"""
# A redesign of how this whole thing works is probably in order, but not now, there's too
# much breakage at once involved.
#--- Public
def select(self, indexes):
"""Update selection to ``indexes``.
:meth:`_update_selection` is called afterwards.
:param list indexes: List of ``int`` that is to become the new selection.
"""
if isinstance(indexes, int):
indexes = [indexes]
self.selected_indexes = indexes
@@ -62,6 +92,10 @@ class Selectable(Sequence):
class SelectableList(MutableSequence, Selectable):
"""A list that can manage selection of its items.
Subclasses :class:`Selectable`. Behaves like a ``list``.
"""
def __init__(self, items=None):
Selectable.__init__(self)
if items:
@@ -100,10 +134,14 @@ class SelectableList(MutableSequence, Selectable):
#--- Virtual
def _on_change(self):
pass
"""(Virtual) Called whenever the contents of the list changes.
By default, does nothing.
"""
#--- Public
def search_by_prefix(self, prefix):
# XXX Why the heck is this method here?
prefix = prefix.lower()
for index, s in enumerate(self):
if s.lower().startswith(prefix):
@@ -111,21 +149,57 @@ class SelectableList(MutableSequence, Selectable):
return -1
class GUISelectableList(SelectableList, GUIObject):
#--- View interface
# refresh()
# update_selection()
#
class GUISelectableListView:
"""Expected interface for :class:`GUISelectableList`'s view.
*Not actually used in the code. For documentation purposes only.*
Our view, some kind of list view or combobox, is expected to sync with the list's contents by
appropriately behave to all callbacks in this interface.
"""
def refresh(self):
"""Refreshes the contents of the list widget.
Ensures that the contents of the list widget is synced with the model.
"""
def update_selection(self):
"""Update selection status.
Ensures that the list widget's selection is in sync with the model.
"""
class GUISelectableList(SelectableList, GUIObject):
"""Cross-toolkit list view.
Represents a UI element presenting the user with a selectable list of items.
Subclasses :class:`SelectableList` and :class:`~hscommon.gui.base.GUIObject`. Expected view:
:class:`GUISelectableListView`.
:param iterable items: If specified, items to fill the list with initially.
"""
def __init__(self, items=None):
SelectableList.__init__(self, items)
GUIObject.__init__(self)
def _view_updated(self):
"""Refreshes the view contents with :meth:`GUISelectableListView.refresh`.
Overrides :meth:`~hscommon.gui.base.GUIObject._view_updated`.
"""
self.view.refresh()
def _update_selection(self):
"""Refreshes the view selection with :meth:`GUISelectableListView.update_selection`.
Overrides :meth:`Selectable._update_selection`.
"""
self.view.update_selection()
def _on_change(self):
"""Refreshes the view contents with :meth:`GUISelectableListView.refresh`.
Overrides :meth:`SelectableList._on_change`.
"""
self.view.refresh()