--- a/tuikit/driver_curses.py Tue Oct 11 10:09:58 2011 +0200
+++ b/tuikit/driver_curses.py Wed Oct 12 00:58:46 2011 +0200
@@ -47,7 +47,7 @@
(0x1b,0x5b,0x5b,0x45, 'f5' ), # linux
)
- color_names = {
+ color_map = {
'black' : curses.COLOR_BLACK,
'blue' : curses.COLOR_BLUE,
'cyan' : curses.COLOR_CYAN,
@@ -58,6 +58,14 @@
'yellow' : curses.COLOR_YELLOW,
}
+ attr_map = {
+ 'blink' : curses.A_BLINK,
+ 'bold' : curses.A_BOLD,
+ 'dim' : curses.A_DIM,
+ 'standout' : curses.A_STANDOUT,
+ 'underline' : curses.A_UNDERLINE,
+ }
+
def __init__(self):
'''Set driver attributes to default values.'''
Driver.__init__(self)
@@ -67,7 +75,6 @@
self.colors = {} # maps names to curses attributes
self.colorpairs = {} # maps tuple (fg,bg) to curses color_pair
self.colorstack = [] # pushcolor/popcolor puts or gets attributes from this
- self.colorprefix = [] # stack of color prefixes
self.inputqueue = []
self.mbtnstack = []
@@ -92,7 +99,7 @@
def _parsecolor(self, name):
name = name.lower().strip()
- return self.color_names[name]
+ return self.color_map[name]
def _getcolorpair(self, fg, bg):
pair = (fg, bg)
@@ -107,14 +114,7 @@
res = 0
for a in attrs:
a = a.lower().strip()
- trans = {
- 'blink' : curses.A_BLINK,
- 'bold' : curses.A_BOLD,
- 'dim' : curses.A_DIM,
- 'standout' : curses.A_STANDOUT,
- 'underline' : curses.A_UNDERLINE,
- }
- res = res | trans[a]
+ res = res | self.attr_map[a]
return res
def setcolor(self, name, desc):
@@ -128,7 +128,7 @@
self.colors[name] = curses.color_pair(col) | attr
def pushcolor(self, name):
- # add prefix if available
+ # add prefix if such color is available
if len(self.colorprefix):
prefixname = self.colorprefix[-1] + name
if prefixname in self.colors:
@@ -144,13 +144,7 @@
else:
attr = 0
self.screen.attrset(attr)
-
- def pushcolorprefix(self, name):
- self.colorprefix.append(name)
-
- def popcolorprefix(self):
- self.colorprefix.pop()
-
+
## drawing ##
--- a/tuikit/driver_pygame.py Tue Oct 11 10:09:58 2011 +0200
+++ b/tuikit/driver_pygame.py Wed Oct 12 00:58:46 2011 +0200
@@ -17,7 +17,9 @@
'''
def __init__(self):
- self.font = pygame.font.SysFont('dejavusansmono,liberationmono,freemono', 14)
+ fontselect = 'dejavusansmono,liberationmono,freemono'
+ self.font = pygame.font.SysFont(fontselect, 14)
+ self.font_bold = pygame.font.SysFont(fontselect, 14, True)
# get advance of some random char (all should be same in monospace font)
advance = self.font.metrics('Q')[0][4]
height = self.font.get_height()
@@ -30,7 +32,7 @@
else:
self.render = self.render_noglyph
- def render_glyph(self, screen, x, y, c, fgcolor, bgcolor):
+ def render_glyph(self, screen, x, y, c, fgcolor, bgcolor, attr):
'''Render using render_glyph and metrics.
This is the correct way, but the output seems same as of render_noglyph
@@ -39,9 +41,14 @@
This implements render() method. See render_noglyph for other implementation.
'''
+ if attr == 'bold':
+ font = self.font_bold
+ else:
+ font = self.font
+
# render character, get metrics
- surface = self.font.render_glyph(c, True, fgcolor, bgcolor)
- metrics = self.font.metrics(c)[0]
+ surface = font.render_glyph(c, True, fgcolor, bgcolor)
+ metrics = font.metrics(c)[0]
minx, maxx, miny, maxy, advance = metrics
height, ascent = self.charsize.h, self.ascent
@@ -68,15 +75,20 @@
area = pygame.Rect(startx, starty, maxx - minx, maxy - miny)
screen.blit(surface, tuple(dest), area)
- def render_noglyph(self, screen, x, y, c, fgcolor, bgcolor):
+ def render_noglyph(self, screen, x, y, c, fgcolor, bgcolor, attr):
'''Render character using normal text rendering.
This implements render() method. See render_glyph for other implementation.
- '''
+ '''
+ if attr == 'bold':
+ font = self.font_bold
+ else:
+ font = self.font
+
# render character, get metrics
- surface = self.font.render(c, True, fgcolor, bgcolor)
- metrics = self.font.metrics(c)[0]
+ surface = font.render(c, True, fgcolor, bgcolor)
+ metrics = font.metrics(c)[0]
minx = metrics[0]
startx = 0
if minx < 0:
@@ -95,7 +107,7 @@
'''PyGame driver class.'''
- key_map = {
+ keymap = {
pygame.K_ESCAPE : 'escape',
pygame.K_TAB : 'tab',
pygame.K_RETURN : 'enter',
@@ -127,15 +139,23 @@
pygame.K_PAUSE : 'pause',
}
- color_map = {
- 'black' : (0,0,0),
- 'blue' : (0,0,0),
- 'cyan' : (0,0,0),
- 'green' : (0,0,0),
- 'magenta' : (0,0,0),
- 'red' : (0,0,0),
- 'white' : (0,0,0),
- 'yellow' : (0,0,0),
+ colormap = {
+ 'black' : (0,0,0),
+ 'blue' : (23,23,178),
+ 'green' : (23,178,23),
+ 'cyan' : (23,178,178),
+ 'red' : (178,23,23),
+ 'magenta' : (178,23,178),
+ 'yellow' : (178,103,23),
+ 'white' : (178,178,178),
+ 'intenseblack' : (104,104,104),
+ 'intenseblue' : (84,84,255),
+ 'intensegreen' : (84,255,84),
+ 'intensecyan' : (84,255,255),
+ 'intensered' : (255,84,84),
+ 'intensemagenta': (255,84,255),
+ 'intenseyellow' : (255,255,84),
+ 'intensewhite' : (255,255,255),
}
def __init__(self):
@@ -146,15 +166,19 @@
self.size.w, self.size.h = 120, 40 # screen size in characters
self.charcache = None
self.charsize = Size(16, 8) # character size in pixels
-
- self.colorprefix = [] # stack of color prefixes
+ self.last_keypress = None
+ self.last_key = None
+ self.colors = {} # maps names to curses attributes
+ self.colorstack = [] # pushcolor/popcolor puts or gets attributes from this
+ self.default_color = (self.colormap['white'], self.colormap['black'], 0)
+ self.current_color = self.default_color
def start(self, mainfunc):
pygame.init()
self.charcache = CharCache()
self.charsize = self.charcache.charsize
mode = self.size.w * self.charsize.w, self.size.h * self.charsize.h
- self.screen = pygame.display.set_mode(mode)
+ self.screen = pygame.display.set_mode(mode, pygame.RESIZABLE)
mainfunc()
@@ -177,10 +201,11 @@
# keyboard
elif ev.type == pygame.KEYDOWN:
keypress = self.keypress_from_pygame_event(ev)
- events.append(keypress)
- self.last_keypress = keypress
- self.last_key = ev.key
- pygame.time.set_timer(pygame.USEREVENT, 200)
+ if keypress:
+ events.append(keypress)
+ self.last_keypress = keypress
+ self.last_key = ev.key
+ pygame.time.set_timer(pygame.USEREVENT, 200)
elif ev.type == pygame.USEREVENT: # repeat last key press
events.append(self.last_keypress)
pygame.time.set_timer(pygame.USEREVENT, 50)
@@ -188,12 +213,14 @@
if ev.key == self.last_key:
pygame.time.set_timer(pygame.USEREVENT, 0)
- # window resize
+ # window
elif ev.type == pygame.VIDEORESIZE:
- #self.size.h, self.size.w = self.screen.getmaxyx()
- events.append(('resize',))
-
- # window close
+ neww, newh = ev.w // self.charsize.w, ev.h // self.charsize.h
+ if neww != self.size.w or newh != self.size.h:
+ self.size.w, self.size.h = neww, newh
+ mode = self.size.w * self.charsize.w, self.size.h * self.charsize.h
+ self.screen = pygame.display.set_mode(mode, pygame.RESIZABLE)
+ events.append(('resize',))
elif ev.type == pygame.QUIT:
events.append(('quit',))
@@ -202,24 +229,26 @@
return events
def keypress_from_pygame_event(self, ev):
- if ev.key in self.key_map:
- keypress = ('keypress', self.key_map[ev.key], None)
+ if ev.key in self.keymap:
+ keypress = ('keypress', self.keymap[ev.key], None)
elif ev.unicode:
keypress = ('keypress', None, ev.unicode)
+ else:
+ self.log.debug('Unknown key: key=%r unicode=%r' % (ev.key, ev.unicode))
+ keypress = None
return keypress
## drawing ##
def erase(self):
'''Clear screen.'''
- self.screen.fill(self.color_map['black'])
+ self.screen.fill(self.colormap['black'])
def putch(self, x, y, c):
if not self.clipstack.test(x, y):
return
- fgcolor = (255,255,255)
- bgcolor = (70,70,70)
- self.charcache.render(self.screen, x, y, c, fgcolor, bgcolor)
+ fgcolor, bgcolor, attr = self.current_color
+ self.charcache.render(self.screen, x, y, c, fgcolor, bgcolor, attr)
def commit(self):
'''Commit changes to the screen.'''
@@ -228,6 +257,20 @@
## colors ##
+ def _parsecolor(self, name, attr=None):
+ name = name.lower().strip()
+ if attr == 'bold':
+ name = 'intense' + name
+ return self.colormap[name]
+
+ def _parseattrs(self, attrs):
+ res = ''
+ for a in attrs:
+ a = a.lower().strip()
+ if a == 'bold':
+ res = a
+ return res
+
def setcolor(self, name, desc):
'''Define color name.
@@ -235,18 +278,33 @@
desc - color description - foreground, background, attributes (e.g. 'black on white, bold')
'''
+ parts = desc.split(',')
+ fg, bg = parts[0].split(' on ')
+ attrs = parts[1:]
+ attr = self._parseattrs(attrs)
+ fg = self._parsecolor(fg, attr)
+ bg = self._parsecolor(bg)
+ self.colors[name] = (fg, bg, attr)
def pushcolor(self, name):
'''Add color on top of stack and use this color for following output.'''
+ # add prefix if such color is available
+ if len(self.colorprefix):
+ prefixname = self.colorprefix[-1] + name
+ if prefixname in self.colors:
+ name = prefixname
+ col = self.colors[name]
+ self.current_color = col
+ self.colorstack.append(col)
def popcolor(self):
'''Remove color from top of stack and use new top color for following output.'''
-
- def pushcolorprefix(self, name):
- self.colorprefix.append(name)
-
- def popcolorprefix(self):
- self.colorprefix.pop()
+ self.colorstack.pop()
+ if len(self.colorstack):
+ col = self.colorstack[-1]
+ else:
+ col = self.default_color
+ self.current_color = col
## cursor ##