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 = '┤'