# HG changeset patch # User Radek Brich # Date 1395096258 -3600 # Node ID ee5ea9671f28c9e78742a17a77a5361e36b348d3 # Parent 0978fb755d31b1c12f991af0f9250ac5d3cf97b0 Add core Widget, Container. Add widgets Label. diff -r 0978fb755d31 -r ee5ea9671f28 demos/03_application.py --- a/demos/03_application.py Mon Mar 17 20:40:04 2014 +0100 +++ b/demos/03_application.py Mon Mar 17 23:44:18 2014 +0100 @@ -4,7 +4,11 @@ sys.path.append('..') from tuikit.core.application import Application +from tuikit.widgets.label import Label +label = Label('Hello there!') +label.pos.update(20, 10) app = Application() +app.root_window.add(label) app.start() diff -r 0978fb755d31 -r ee5ea9671f28 tuikit/core/buffer.py --- a/tuikit/core/buffer.py Mon Mar 17 20:40:04 2014 +0100 +++ b/tuikit/core/buffer.py Mon Mar 17 23:44:18 2014 +0100 @@ -1,5 +1,5 @@ from tuikit.core.signal import Signal -from tuikit.core.size import Size +from tuikit.core.coords import Size from tuikit.core.unigraph import unigraph_default diff -r 0978fb755d31 -r ee5ea9671f28 tuikit/core/container.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tuikit/core/container.py Mon Mar 17 23:44:18 2014 +0100 @@ -0,0 +1,20 @@ +class Container: + + """Container for widgets.""" + + def __init__(self): + #: List of child widgets. + self.children = [] + + def add(self, widget, **kwargs): + """Add widget into container.""" + self.children.append(widget) + widget.parent = self + widget.window = self.window if hasattr(self, 'window') else self + + def draw(self, buffer, x=0, y=0): + """Draw child widgets.""" + for child in self.children: + child.draw(buffer, + x + child.x, + y + child.y) diff -r 0978fb755d31 -r ee5ea9671f28 tuikit/core/coords.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tuikit/core/coords.py Mon Mar 17 23:44:18 2014 +0100 @@ -0,0 +1,106 @@ +class Point: + + """Point in cartesian space. + + Implements attribute access (.x, .y) and list-like access([0],[1]). + + """ + + def __init__(self, x=0, y=0): + self.x = x + self.y = y + + def __getitem__(self, key): + return (self.x, self.y)[key] + + def __repr__(self): + return 'Point(x={0.x},y={0.y})'.format(self) + + def update(self, *args, **kwargs): + """Update point. + + Accepts positional or keyword arguments: + - (point: Point) + - (x: int, y: int) + + """ + if len(args) == 2: + self.x, self.y = args + elif len(args) == 1: + self.x, self.y = args[0] + elif len(args): + raise ValueError('Too many args.') + for key, val in kwargs.items(): + if key == 'point': + self.x, self.y = val + elif key in ('x', 'y'): + setattr(self, key, val) + else: + raise ValueError('Bad keyword arg: %r' % key) + + +class Size: + + """Size class. + + Implements attribute access (.w, .h) and list-like access([0],[1]). + + """ + + def __init__(self, *args, **kwargs): + self.w = 0 + self.h = 0 + self.update(*args, **kwargs) + + def __getitem__(self, key): + return (self.w, self.h)[key] + + def __repr__(self): + return 'Size(w={0.w},h={0.h})'.format(self) + + def update(self, *args, **kwargs): + """Update size. + + Accepts positional or keyword arguments: + - (size: Size) + - (w: int, h: int) + + """ + if len(args) == 2: + self.w, self.h = args + elif len(args) == 1: + self.w, self.h = args[0] + elif len(args): + raise ValueError('Too many args.') + for key, val in kwargs.items(): + if key == 'size': + self.w, self.h = val + elif key in ('w', 'h'): + setattr(self, key, val) + else: + raise ValueError('Bad keyword arg: %r' % key) + + def readonly(self): + return ReadonlySize(self) + + +class ReadonlySize: + + """Wrapper for Size which makes it read-only.""" + + def __init__(self, size): + self._size = size + + @property + def w(self): + return self._size.w + + @property + def h(self): + return self._size.h + + def __getitem__(self, key): + return self._size[key] + + def __repr__(self): + return 'ReadonlySize(w={0.w},h={0.h})'.format(self._size) diff -r 0978fb755d31 -r ee5ea9671f28 tuikit/core/size.py --- a/tuikit/core/size.py Mon Mar 17 20:40:04 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -class Size: - - """Size class. - - Implements attribute access (.w, .h) and list-like access([0],[1]). - - """ - - def __init__(self, *args, **kwargs): - self.w = 0 - self.h = 0 - self.update(*args, **kwargs) - - def __getitem__(self, key): - return (self.w, self.h)[key] - - def __repr__(self): - return 'Size(w={0.w},h={0.h})'.format(self) - - def update(self, *args, **kwargs): - if len(args) == 2: - # (w:int, h:int) - self.w, self.h = args - elif len(args) == 1: - # (size:Size) - self.w, self.h = args[0] - elif len(args): - raise ValueError('Too many args.') - for key, val in kwargs.items(): - if key in ('w', 'h'): - setattr(self, key, val) - else: - raise ValueError('Bad keyword arg: %r' % key) - - def readonly(self): - return ReadonlySize(self) - - -class ReadonlySize: - - """Wrapper for Size which makes it read-only.""" - - def __init__(self, size): - self._size = size - - @property - def w(self): - return self._size.w - - @property - def h(self): - return self._size.h - - def __getitem__(self, key): - return self._size[key] - - def __repr__(self): - return 'ReadonlySize(w={0.w},h={0.h})'.format(self._size) diff -r 0978fb755d31 -r ee5ea9671f28 tuikit/core/widget.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tuikit/core/widget.py Mon Mar 17 23:44:18 2014 +0100 @@ -0,0 +1,56 @@ +from tuikit.core.coords import Point, Size + + +class Widget: + + """Base class for all widgets.""" + + _num_instances = 0 + + def __init__(self): + #: Widget name is used for logging etc. Not visible anywhere. + self._num_instances += 1 + self.name = '{}{}'.format( + self.__class__.__name__, + self._num_instances) + + #: Parent Widget + self.parent = None + #: Window owning this Widget + self.window = None + + ### placing and size + #: Position inside parent widget. Modified by layout manager. + self.pos = Point() + #: Actual size. Modified by layout manager. + self.size = Size(10, 10) + #: Requested size. Layout manager will use this when placing the widget. + self.sizereq = Size(1, 1) + #: Minimal size of widget. Widget will never be sized smaller than this. + self.sizemin = Size(1, 1) + #: Maximum size of widget. Widget will never be sized bigger than this. + #: None means no maximum size (infinite). + self.sizemax = Size(None, None) + + ## placing and size ## + + @property + def x(self): + return self.pos.x + + @property + def y(self): + return self.pos.y + + @property + def width(self): + return self.size.w + + @property + def height(self): + return self.size.h + + ## drawing ## + + def draw(self, buffer, x, y): + pass diff -r 0978fb755d31 -r ee5ea9671f28 tuikit/core/window.py --- a/tuikit/core/window.py Mon Mar 17 20:40:04 2014 +0100 +++ b/tuikit/core/window.py Mon Mar 17 23:44:18 2014 +0100 @@ -1,8 +1,9 @@ from tuikit.core.buffer import Buffer from tuikit.core.signal import Signal +from tuikit.core.container import Container -class Window: +class Window(Container): """Window is rectangular part of screen containing widgets. @@ -13,6 +14,7 @@ def __init__(self, buffer=None): """New buffer for the window will be created unless given existing `buffer` as parameter.""" + Container.__init__(self) self._buffer = None self._size = None self.sig_resized = Signal() @@ -43,4 +45,5 @@ def draw(self, buffer, x=0, y=0): """Draw this window into buffer at x, y coords.""" + Container.draw(self, self.buffer) buffer.draw(self.buffer, x, y) diff -r 0978fb755d31 -r ee5ea9671f28 tuikit/widgets/__init__.py diff -r 0978fb755d31 -r ee5ea9671f28 tuikit/widgets/label.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tuikit/widgets/label.py Mon Mar 17 23:44:18 2014 +0100 @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +from tuikit.core.widget import Widget + + +class Label(Widget): + + def __init__(self, label=''): + Widget.__init__(self) + self.sizereq.update(len(label), 1) + self.label = label + #self.color = 'normal' + + def draw(self, buffer, x, y): + #ev.driver.pushcolor(self.color) + buffer.puts(x, y, self.label)