From ab8fef3cdb2bf5c6393ed841f74baf2bfc5a1a23 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 20 Feb 2014 19:50:17 +0100 Subject: [PATCH] Add new NeighborList datatype --- qutebrowser/utils/types.py | 113 +++++++++++++++++++++++++++++++++ qutebrowser/widgets/browser.py | 1 + 2 files changed, 114 insertions(+) create mode 100644 qutebrowser/utils/types.py diff --git a/qutebrowser/utils/types.py b/qutebrowser/utils/types.py new file mode 100644 index 000000000..328515d8b --- /dev/null +++ b/qutebrowser/utils/types.py @@ -0,0 +1,113 @@ +# Copyright 2014 Florian Bruhin (The Compiler) +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +"""Custom useful datatypes.""" + +# Used as default argument in the constructor so default can be None. +_UNSET = object() + + +class NeighborList: + + """A list of items which saves it current position. + + Attributes: + BLOCK/WRAP/RAISE: Modes, see constructor documentation. + _items: A list of all items, accessed through item property. + idx: The current position in the list. + _mode: The current mode. + + """ + + BLOCK = 0 + WRAP = 1 + RAISE = 2 + + def __init__(self, items, default=_UNSET, mode=BLOCK): + """Constructor. + + Args: + items: The list of items to iterate in. + _default: The initially selected value. + _mode: Behaviour when the first/last item is reached. + BLOCK: Stay on the selected item + WRAP: Wrap around to the other end + RAISE: Raise an IndexError. + + """ + self._items = items + self._default = default + if default is not _UNSET: + self.idx = self._items.index(default) + self._mode = mode + + @property + def items(self): + """Getter for items, which should not be set.""" + return self._items + + def getitem(self, offset): + """Get the item with a relative position. + + Args: + offset: The offset of the current item, relative to the last one. + + Return: + The new item. + + Raise: + IndexError if the border of the list is reached and mode is RAISE. + + """ + # FIXME - zooming somehow wraps... + try: + if self.idx + offset > 0: + new = self._items[self.idx + offset] + else: + raise IndexError + except IndexError: + if self._mode == self.BLOCK: + new = self.curitem() + elif self._mode == self.WRAP: + self.idx += offset + self.idx %= len(self.items) + new = self.curitem() + elif self._mode == self.RAISE: + raise + else: + self.idx += offset + return new + + def curitem(self): + """Get the current item in the list.""" + return self._items[self.idx] + + def nextitem(self): + """Get the next item in the list.""" + return self.getitem(1) + + def previtem(self): + """Get the previous item in the list.""" + return self.getitem(-1) + + def reset(self): + """Reset the position to the default.""" + if self._default is _UNSET: + raise ValueError("No default set!") + else: + self.idx = self._items.index(self._default) + return self.curitem() diff --git a/qutebrowser/widgets/browser.py b/qutebrowser/widgets/browser.py index a1c842a3f..66e9a6ea6 100644 --- a/qutebrowser/widgets/browser.py +++ b/qutebrowser/widgets/browser.py @@ -40,6 +40,7 @@ import qutebrowser.utils.config as config from qutebrowser.widgets.tabbar import TabWidget from qutebrowser.utils.signals import SignalCache, dbg_signal from qutebrowser.utils.misc import read_file +from qutebrowser.utils.types import NeighborList class TabbedBrowser(TabWidget):