Add core Widget, Container. Add widgets Label.
authorRadek Brich <radek.brich@devl.cz>
Mon, 17 Mar 2014 23:44:18 +0100
changeset 87 ee5ea9671f28
parent 86 0978fb755d31
child 88 90d00354dc70
Add core Widget, Container. Add widgets Label.
demos/03_application.py
tuikit/core/buffer.py
tuikit/core/container.py
tuikit/core/coords.py
tuikit/core/size.py
tuikit/core/widget.py
tuikit/core/window.py
tuikit/widgets/__init__.py
tuikit/widgets/label.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()
--- 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)