DriverSDL: Implement cursor, handle window resize.
# -*- coding: utf-8 -*-
'''SDL driver.
Requires C++ extension module.
See sdlterm directory.
'''
from tuikit.driver import Driver
import logging
import sys
sys.path.insert(0, 'sdlterm/build/lib.linux-x86_64-3.2')
from sdlterm import SDLTerminal
class DriverSDL(Driver):
'''SDL driver class'''
color_map = {
'black' : 0,
'blue' : 1,
'green' : 2,
'cyan' : 3,
'red' : 4,
'magenta' : 5,
'brown' : 6,
'lightgray' : 7,
'gray' : 8,
'lightblue' : 9,
'lightgreen' : 10,
'lightcyan' : 11,
'lightred' : 12,
'lightmagenta' : 13,
'yellow' : 14,
'white' : 15,
}
style_map = {
'bold' : 1 << 0, # bold font
'underline' : 1 << 1, # underline text
'standout' : 1 << 2, # inverse bg/fg
'blink' : 1 << 3, # blinking text
'dim' : 0,
}
def __init__(self):
'''Initialize instance attributes'''
Driver.__init__(self)
self.log = logging.getLogger('tuikit')
self.sdlterm = SDLTerminal()
self.colors = {} # maps names to attributes
self.colorstack = [] # pushcolor/popcolor puts or gets attributes from this
def start(self, mainfunc):
'''Start driver and run mainfunc.'''
self.sdlterm.resize(800, 600)
self.sdlterm.select_font("sdlterm/font/DejaVuSansMono.ttf", "sdlterm/font/DejaVuSansMono-Bold.ttf", 12)
self.size.w, self.size.h = self.sdlterm.width, self.sdlterm.height
mainfunc()
## input ##
def getevents(self, timeout=None):
'''Process input, return list of events.'''
event = self.sdlterm.get_next_event()
if event[0] == 'resize':
self.size.w, self.size.h = self.sdlterm.width, self.sdlterm.height
return [event]
## drawing ##
def erase(self):
'''Clear screen.'''
self.sdlterm.erase()
def putch(self, x, y, c):
'''Output one unicode character to specified coordinates.'''
if not self.clipstack.test(x, y):
return
self.sdlterm.putch(x, y, c)
def commit(self):
'''Commit changes to the screen.'''
self.sdlterm.commit()
## colors ##
def setcolor(self, name, desc):
'''Define color name.
name - name of color (e.g. 'normal', 'active')
desc - color description - foreground, background, attributes (e.g. 'black on white, bold')
'''
parts = desc.split(',')
fg, bg = parts[0].split(' on ')
style = parts[1:]
fg = self._color_by_name(fg)
bg = self._color_by_name(bg)
style = self._style_by_names(style)
self.colors[name] = self.sdlterm.prepare_attr(fg, bg, style);
def pushcolor(self, name):
'''Add color on top of stack and use this color for following output.'''
if len(self.colorprefix):
prefixname = self.colorprefix[-1] + name
if prefixname in self.colors:
name = prefixname
attr = self.colors[name]
self.sdlterm.set_attr(attr)
self.colorstack.append(attr)
def popcolor(self):
'''Remove color from top of stack and use new top color for following output.'''
self.colorstack.pop()
if len(self.colorstack):
attr = self.colorstack[-1]
else:
attr = 0
self.sdlterm.set_attr(attr)
def _color_by_name(self, name):
name = name.lower().strip()
return self.color_map[name]
def _style_by_names(self, names):
style = 0
for name in names:
name = name.lower().strip()
style |= self.style_map[name]
return style
## cursor ##
def showcursor(self, x, y):
'''Set cursor to be shown at x, y coordinates.'''
if not self.clipstack.test(x, y):
return
self.sdlterm.show_cursor(x, y)
def hidecursor(self):
'''Hide cursor.'''
self.sdlterm.hide_cursor()
driverclass = DriverSDL