--- a/tuikit/common.py Thu Jan 10 00:03:34 2013 +0100
+++ b/tuikit/common.py Fri Jan 18 22:36:50 2013 +0100
@@ -3,6 +3,37 @@
from tuikit.events import Event, Emitter
+class Select:
+ def __init__(self, selected=None):
+ if not hasattr(self, '_options'):
+ raise TypeError('Cannot instantiate Select class.')
+ self._selected = selected or self._options[0]
+
+ def update(self, selected):
+ if selected not in self._options:
+ raise ValueError('Select: %r not in options %r' % (selected, self._options))
+ self._selected = selected
+
+ def select_next(self):
+ i = self._options.index(self._selected)
+ try:
+ self._selected = self._options[i+1]
+ except IndexError:
+ self._selected = self._options[0]
+
+ @property
+ def selected(self):
+ return self._selected
+
+ def __repr__(self):
+ return self.__class__.__name__ + '(%r)' % self._selected
+
+
+def make_select(*args):
+ name = ''.join([x.capitalize() for x in args]) + 'Select'
+ return type(name, (Select,), {'_options': args})
+
+
class Coords:
'''2D coordinates.'''
@@ -28,6 +59,19 @@
def __repr__(self):
return 'Coords(x={0.x},y={0.y})'.format(self)
+ def update(self, x=None, y=None):
+ if isinstance(x, Coords) and y is None:
+ self.x, self.y = x
+ else:
+ if isinstance(x, int):
+ self.x = x
+ elif x is not None:
+ raise ValueError('Coords.update(): first parameter must be int or Coords')
+ if isinstance(y, int):
+ self.y = y
+ elif y is not None:
+ raise ValueError('Coords.update(): second parameter must be int')
+
class Size(Emitter):
@@ -78,6 +122,22 @@
def __repr__(self):
return 'Size(w={0._w},h={0._h})'.format(self)
+ def update(self, w=None, h=None):
+ old_w, old_h = self._w, self._h
+ if isinstance(w, Size) and h is None:
+ self._w, self._h = w
+ else:
+ if isinstance(w, int):
+ self._w = w
+ elif w is not None:
+ raise ValueError('Size.update(): first parameter must be int or Size')
+ if isinstance(h, int):
+ self._h = h
+ elif h is not None:
+ raise ValueError('Size.update(): second parameter must be int')
+ if self._w != old_w or self._h != old_h:
+ self.emit('change')
+
class Rect:
@@ -103,11 +163,13 @@
'''
- def __init__(self, l=0, t=0, r=0, b=0):
+ def __init__(self, l=0, t=0, r=0, b=0, full=None):
self.l = l # left
self.t = t # top
self.r = r # right
self.b = b # bottom
+ if full is not None:
+ self.l = self.t = self.r = self.b = full
def __getitem__(self, key):
try:
@@ -120,6 +182,16 @@
def __repr__(self):
return 'Borders(l={0.l},t={0.t},r={0.r},b={0.b})'.format(self)
+ def update(self, *args, **kwargs):
+ if len(args) == 4:
+ self.l, self.t, self.r, self.b = args
+ elif len(args) == 1 and isinstance(args[0], Borders):
+ self.l, self.t, self.r, self.b = args[0]
+ elif len(args):
+ raise ValueError('Borders.update() takes exactly 4 positional arguments.')
+ for arg in kwargs:
+ setattr(self, arg, kwargs[arg])
+
class ClipStack:
@@ -176,6 +248,11 @@
# http://en.wikipedia.org/wiki/List_of_Unicode_characters#Geometric_shapes
UP_ARROW = '▲' #curses.ACS_UARROW
DOWN_ARROW = '▼' #curses.ACS_DARROW
+ LEFT_ARROW = '◀'
+ RIGHT_ARROW = '▶'
+ CIRCLE = '●'
+ DIAMOND = '◆'
+ MIDDLE_DOT = '·'
# http://en.wikipedia.org/wiki/Box-drawing_characters
LIGHT_SHADE = '░' #curses.ACS_BOARD