tuikit/core/window.py
author Radek Brich <radek.brich@devl.cz>
Sun, 22 Feb 2015 09:53:13 +0100
changeset 119 dd91747504dd
parent 114 26c02bd94bd9
permissions -rw-r--r--
Redraw widgets on request. Add scrollbar demo.

from tuikit.core.buffer import Buffer
from tuikit.core.signal import Signal
from tuikit.core.container import Container


class Window(Container):

    """Window is rectangular part of screen containing widgets.

    Widgets are drawn into window, events are routed to widgets through window.

    Parent of Window is always WindowManager.

    """

    def __init__(self, buffer=None):
        """New buffer for the window will be created unless given existing
        `buffer` as parameter."""
        Container.__init__(self)
        self.allow_focus = True
        self.trap_focus = True
        self._buffer = None
        self.buffer = buffer or Buffer()

    @property
    def buffer(self):
        return self._buffer

    @buffer.setter
    def buffer(self, buffer):
        # replace the buffer
        self._buffer = buffer

    @property
    def size(self):
        return self.buffer.size

    def resize(self, w, h):
        """Resize buffer when window gets resized."""
        Container.resize(self, w, h)
        self.buffer.resize(w, h)
        self.redraw()

    def draw_content_if_needed(self):
        """Draw window contents into its own buffer."""
        buffer = self.buffer
        buffer.reset_origin()
        for child in self._widgets:
            with buffer.moved_origin(child.x, child.y):
                with buffer.clip(buffer.origin.x, buffer.origin.y,
                                 child.width, child.height):
                    child.draw_if_needed(buffer)

    def draw_if_needed(self, buffer):
        """Refresh window content and draw it into `buffer` if required."""
        self.draw_content_if_needed()
        # Draw window unconditionally (for now)
        self.draw(buffer)

    def draw(self, buffer):
        """Draw window buffer into given`buffer`."""
        buffer.draw(self.buffer)


class WindowManager(Container):

    def __init__(self, timer):
        Container.__init__(self)
        self.timer = timer

    def draw(self, buffer):
        Container.draw(self, buffer)
        self.log.debug('%s has focus.', self.get_focused_widget().name)

    def resize(self, w, h):
        Container.resize(self, w, h)
        self._widgets[0].resize(w, h)

    def keypress_event(self, ev):
        self.log.debug('%s', ev)
        return Container.keypress_event(self, ev)

    def handle_event(self, event):
        """Handle input event to managed windows."""
        self.log.debug('Handle event: %r', event)
        handler = getattr(self, event.name + '_event', None)
        if handler:
            handler(event)
        else:
            raise Exception('Unknown event: %r' % event)

    def get_focused_widget(self):
        """Traverse the widget hierarchy to bottom
        and return actually focused Widget."""
        node = self
        while isinstance(node, Container) and node.focus_widget:
            node = node.focus_widget
        return node

    def get_cursor_if_visible(self):
        if self.cursor_visible:
            return self.cursor