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

from tuikit.core.window import WindowManager, Window
from tuikit.core.theme import default_theme
from tuikit.core.timer import Timer
from tuikit.core.buffer import ProxyBuffer
from tuikit.core.events import ResizeEvent

import logging


class Application:

    """Tuikit application helper.

    Joins all required pieces to build complete application
    using TUI widgets and event loop.

    """

    def __init__(self, driver='cursesw'):
        self.log = logging.getLogger(__name__)
        self.driver = None
        self.timer = Timer()
        self.window_manager = WindowManager(timer=self.timer)
        self.root_window = Window()
        # flags
        self._started = False
        self._quit = False
        # find and initialize driver
        self.set_driver(driver)
        self.set_theme(default_theme)
        self.window_manager.add(self.root_window)
        # Convenience method
        self.add = self.root_window.add

    def set_driver(self, driver_name):
        """Select driver to be used for rendering and input.

        `driver_name` should be one of: 'base', 'curses', 'sdl'

        """
        if self._started:
            raise Exception('Cannot change driver after starting the application.')
        module = __import__('tuikit.driver.' + driver_name, fromlist=['driver_class'])
        self.driver = module.driver_class()

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

    def start(self):
        """Start application. Runs main loop."""
        self.log.info('=== Start ===')
        with self.driver:
            self.main_loop()

    def stop(self):
        """Terminate application."""
        self._quit = True

    def main_loop(self):
        """The main loop."""
        self._started = True
        self.window_manager.handle_event(ResizeEvent(*self.driver.size))

        screen = ProxyBuffer(self.driver)
        while not self._quit:
            self.window_manager.draw_if_needed(screen)
            self.driver.cursor = self.window_manager.get_cursor_if_visible()
            self.driver.flush()

            timeout = self.timer.nearest_timeout()
            events = self.driver.getevents(timeout)

            self.timer.process_timeouts()
            for event in events:
                self.window_manager.handle_event(event)

        self._started = False
        self.log.info('=== End ===')