tuikit/common.py
author Radek Brich <radek.brich@devl.cz>
Sun, 09 Oct 2011 19:30:25 +0200
changeset 24 b248ef500557
parent 23 4e72fd2a0e14
child 26 37745c5abc49
permissions -rw-r--r--
Add DriverPygame (incomplete). Move unicode graphics constants to UnicodeGraphics class. Move shared parts of drivers to Driver base class.

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


class Coords:
    
    '''2D coordinates.'''
    
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __getitem__(self, key):
        try:
            tupl = (self.x, self.y)
            return tupl[key]
        except TypeError:
            pass
        return self.__dict__[key]
    
    def __setitem__(self, key, value):
        if key == 0:
            self.x = value
        if key == 1:
            self.y = value

    def __repr__(self):
        return 'Coords(x={0.x},y={0.y})'.format(self)


class Size:
    
    '''Size class.
    
    Implements attribute access (.w, .h), list-like access([0],[1])
    and dict-like access (['w'],['h']).
    
    '''
    
    def __init__(self, w=None, h=None):
        self.w = w
        self.h = h
    
    def __getitem__(self, key):
        try:
            tupl = (self.w, self.h)
            return tupl[key]
        except TypeError:
            pass
        return self.__dict__[key]

    def __setitem__(self, key, value):
        if key in [0, 'w']:
            self.w = value
        if key in [1, 'h']:
            self.h = value
    
    def __repr__(self):
        return 'Size(w={0.w},h={0.h})'.format(self)


class Rect:
    
    '''Rectangle is defined by 2D coordinates and size.'''
    
    def __init__(self, x=0, y=0, w=0, h=0):
        self.x = x
        self.y = y
        self.w = w
        self.h = h

    def __repr__(self):
        return 'Rect(x={0.x},y={0.y},w={0.w},h={0.h})'.format(self)


class Borders:
    
    '''Borders are defined by left, top, right, bottom border size.
    
    Ordering is clock-wise, starting with left. This may seem weird,
    but it corresponds to X/Y or W/H used elsewhere. Left and right are
    on X axis, so they are defined first.
    
    '''
    
    def __init__(self, l=0, t=0, r=0, b=0):
        self.l = l # left
        self.t = t # top
        self.r = r # right
        self.b = b # bottom

    def __getitem__(self, key):
        try:
            tupl = (self.l, self.t, self.r, self.b)
            return tupl[key]
        except TypeError:
            pass
        return self.__dict__[key]
    
    def __repr__(self):
        return 'Borders(l={0.l},t={0.t},r={0.r},b={0.b})'.format(self)


class ClipStack:
    
    '''Stack of clipping regions.'''
    
    def __init__(self):
        self.stack = []
    
    def push(self, x, y, w, h):
        newclip = Rect(x, y, w, h)
        if len(self.stack):
            oldclip = self.stack[-1]
            newclip = self.intersect(oldclip, newclip)
        self.stack.append(newclip)

    def pop(self):
        self.stack.pop()

    def test(self, x, y):
        # no clip rectangle on stack => passed
        if not len(self.stack):
            return True
        # test against top clip rect from stack
        clip = self.stack[-1]
        if x < clip.x or y < clip.y \
        or x >= clip.x + clip.w or y >= clip.y + clip.h:
            return False
        # passed
        return True

    def intersect(self, r1, r2):
        x1 = max(r1.x, r2.x)
        y1 = max(r1.y, r2.y)
        x2 = min(r1.x + r1.w, r2.x + r2.w)
        y2 = min(r1.y + r1.h, r2.y + r2.h)
        if x1 >= x2 or y1 >= y2:
            return Rect()
        return Rect(x1, y1, x2-x1, y2-y1)

    def union(self, r1, r2):
        x = min(r1.x, r2.x)
        y = min(r1.y, r2.y)
        w = max(r1.x + r1.w, r2.x + r2.w) - x
        h = max(r1.y + r1.h, r2.y + r2.h) - y
        return Rect(x, y, w, h)


class UnicodeGraphics:
    
    '''Unicode graphics bank.
    
    This class can be overriden to change graphics style (round corners etc.).'''
    
    # http://en.wikipedia.org/wiki/List_of_Unicode_characters#Geometric_shapes
    UP_ARROW = '▲' #curses.ACS_UARROW
    DOWN_ARROW = '▼' #curses.ACS_DARROW
    
    # http://en.wikipedia.org/wiki/Box-drawing_characters
    LIGHT_SHADE = '░' #curses.ACS_BOARD
    MEDIUM_SHADE = '▒'
    DARK_SHADE = '▓'
    BLOCK = '█'
    
    COLUMN = '▁▂▃▄▅▆▇█'
    CORNER_ROUND = '╭╮╰╯'
    CORNER = '┌┐└┘'
    LINE = '─━│┃┄┅┆┇┈┉┊┋'

    HLINE = '─' # curses.ACS_HLINE
    VLINE = '│' # curses.ACS_VLINE
    ULCORNER = '┌' # curses.ACS_ULCORNER
    URCORNER = '┐' # curses.ACS_URCORNER
    LLCORNER = '└' # curses.ACS_LLCORNER
    LRCORNER = '┘' # curses.ACS_LRCORNER
    LTEE = '├'
    RTEE = '┤'