tuikit/core/widget.py
author Radek Brich <radek.brich@devl.cz>
Fri, 28 Mar 2014 10:44:29 +0100
changeset 94 e50dae408fe9
parent 93 c1e79acb9fcb
child 97 0c2e0c09ba5c
permissions -rw-r--r--
Add origin to Buffer. Use it to simplify hierarchical drawing.

from tuikit.core.coords import Point, Size
from tuikit.core.theme import default_theme

import logging


class Widget:

    """Base class for all widgets."""

    _num_instances = 0

    def __init__(self):
        self._num_instances += 1
        self._log = logging.getLogger(__name__)

        #: Widget name is used for logging etc. Not visible anywhere.
        self.name = '{}{}'.format(
            self.__class__.__name__,
            self._num_instances)

        #: Parent Widget
        self.parent = None
        #: Window owning this Widget
        self.window = None
        #: Theme
        self.theme = default_theme

        #: 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)

    ## position 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

    @property
    def size(self):
        return self._size.readonly()

    def resize(self, w, h):
        self._size.update(w, h)

    ## drawing, looks ##

    def draw(self, buffer):
        """Draw self into buffer."""
        self._log.debug('%s draw into %r at %s (exposed %s)',
                        self.name, buffer, buffer.origin, self.exposed(buffer))

    def set_theme(self, theme):
        self.theme = theme

    @staticmethod
    def exposed(buffer):
        """Exposed part of widget.

        Only this area needs to be drawn.

        Returns exposed Rect in widget's local coordinates,
        where 0,0 is left top corner of widget to be drawn.

        """
        return buffer.clip_rect.moved(-buffer.origin.x, -buffer.origin.y)

    ## timeouts ##

    def add_timeout(self, delay, callback, *args):
        """Register `callback` to be called after `delay` seconds."""
        self.parent.add_timeout(self, delay, callback, *args)

    def remove_timeout(self, callback, *args):
        """Unregister callback previously registered with add_timeout.

        Removes all timeouts with the `callback` and `args`.

        """
        self.parent.remove_timeout(self, callback, *args)