tuikit/application.py
author Radek Brich <radek.brich@devl.cz>
Mon, 17 Dec 2012 00:24:34 +0100
changeset 36 caf927c3f10b
parent 34 e3beacd5e536
child 46 2b43a7f38c34
permissions -rw-r--r--
Update docs.

# -*- coding: utf-8 -*-

import logging
import time
import math

from tuikit.container import Container


class TopWindow(Container):

    '''Top window of an application. Covers entire screen.'''

    def __init__(self):
        '''Create top window.'''
        Container.__init__(self)

        self.top = self

        self.timeout = []
        self.timelast = None

    def draw(self, screen, x=0, y=0):
        """Draw the top window and its children.

        This is entry point for full screen redraw.

        """
        screen.erase()
        super().draw(screen, x, y)

    def add_timeout(self, s, func):
        if not len(self.timeout):
            self.timelast = time.time()
        self.timeout += [[s, func]]


    def remove_timeout(self, func):
        for to in self.timeout[:]:
            if to[1] == func:
                self.timeout.remove(to)


    def has_timeout(self):
        return len(self.timeout) and True or False


    def nearest_timeout(self):
        return min(self.timeout)[0]


    def process_timeout(self):
        now = time.time()
        lasted = now - self.timelast
        self.timelast = now

        for to in self.timeout[:]:
            newt = to[0] - lasted
            if newt <= 0.0:
                to[1]()
                self.timeout.remove(to)
            else:
                to[0] = newt


class Application:

    '''Application class. Defines main loop.'''

    def __init__(self, driver = 'curses'):
        '''Create application.'''

        self.top = TopWindow()
        '''Top window.'''

        self.quit = False

        self.driver = self.get_driver_instance(driver)
        '''Driver class instance (render + input), e.g. DriverCurses.'''

        self.log = logging.getLogger('tuikit')
        self.log.setLevel(logging.DEBUG)
        handler = logging.FileHandler('./tuikit.log')
        formatter = logging.Formatter('%(asctime)s %(levelname)-5s %(message)s', '%y-%m-%d %H:%M:%S')
        handler.setFormatter(formatter)
        self.log.addHandler(handler)
        self.log.info('=== start ===')

    def start(self):
        '''Start application. Runs main loop.'''
        self.driver.start(self.mainloop)

    def terminate(self):
        '''Terminate application.'''
        self.quit = True

    def mainloop(self):
        '''The main loop.'''
        self.applytheme()
        self.top.size = self.driver.size  # link top widget size to screen size
        self.top.emit('resize')

        while True:
            self.top.draw(self.driver)
            self.driver.commit()

            timeout = None
            if self.top.has_timeout():
                timeout = int(math.ceil(self.top.nearest_timeout() * 10))

            events = self.driver.getevents(timeout)

            if self.top.has_timeout():
                self.top.process_timeout()

            for event in events:
                if event[0] == 'quit':
                    self.quit = True
                else:
                    self.top.emit(event[0], *event[1:])

            if self.quit:
                break


    def applytheme(self):
        driver = self.driver
        driver.setcolor('normal',                  'white on black')
        driver.setcolor('strong',                  'white on black, bold')
        driver.setcolor('active',                  'black on cyan')
        driver.setcolor('window:normal',           'white on blue')
        driver.setcolor('window:controls',         'white on blue, bold')
        driver.setcolor('window:controls-active',  'cyan on blue, bold')
        driver.setcolor('button',                  'black on white')
        driver.setcolor('button-active',           'black on cyan')
        driver.setcolor('menu',                    'black on cyan')
        driver.setcolor('menu-active',             'white on cyan, bold')
        driver.setcolor('combo:normal',            'black on green')


    def get_driver_instance(self, name):
        module = __import__('tuikit.driver_' + name, fromlist=['driverclass'])
        return module.driverclass()