Add core Widget, Container. Add widgets Label.
--- 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()
--- 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
--- /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)
--- /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)
--- 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)
--- /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
--- 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)
--- /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)