tuikit/backend_curses.py
changeset 7 d4a291b31cbb
parent 5 ae128c885d0f
child 9 7175ed629a76
--- a/tuikit/backend_curses.py	Sun Apr 10 22:56:13 2011 +0200
+++ b/tuikit/backend_curses.py	Wed Apr 13 01:33:27 2011 +0200
@@ -69,13 +69,28 @@
         (0x1b,0x5b,0x5b,0x45,       'f5'            ),  # linux
     )
 
+    color_names = {
+        'black'   : curses.COLOR_BLACK,
+        'blue'    : curses.COLOR_BLUE,
+        'cyan'    : curses.COLOR_CYAN,
+        'green'   : curses.COLOR_GREEN,
+        'magenta' : curses.COLOR_MAGENTA,
+        'red'     : curses.COLOR_RED,
+        'white'   : curses.COLOR_WHITE,
+        'yellow'  : curses.COLOR_YELLOW,
+    }
+
     def __init__(self, screen):
         self.screen = screen
         self.height, self.width = screen.getmaxyx()
 
         self.cursor = None
         self.clipstack = []
-        self.colorstack = []
+
+        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.inputqueue = []
         self.mbtnstack = []
 
@@ -89,16 +104,6 @@
         screen.immedok(0)
         screen.keypad(0)
 
-        curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK)
-        curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_CYAN)
-        curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_CYAN)
-        curses.init_pair(4, curses.COLOR_WHITE, curses.COLOR_BLUE)
-        curses.init_pair(5, curses.COLOR_CYAN, curses.COLOR_BLUE)
-
-        self.BOLD = curses.A_BOLD
-        self.BLINK = curses.A_BLINK
-        self.UNDERLINE = curses.A_UNDERLINE
-
         # http://en.wikipedia.org/wiki/List_of_Unicode_characters#Geometric_shapes
         self.UP_ARROW = '▲' #curses.ACS_UARROW
         self.DOWN_ARROW = '▼' #curses.ACS_DARROW
@@ -171,22 +176,60 @@
 
     ## attributes ##
 
-    def pushcolor(self, col, attr=0):
-        if type(col) is tuple:
-            col, attr = col
-        if attr == 'bold':
-            attr = self.BOLD
-        self.screen.attrset(curses.color_pair(col) | attr)
-        self.colorstack.append((col, attr))
+    def _parsecolor(self, name):
+        name = name.lower().strip()
+        return self.color_names[name]
+
+
+    def _getcolorpair(self, fg, bg):
+        pair = (fg, bg)
+        if pair in self.colorpairs:
+            return self.colorpairs[pair]
+        num = len(self.colorpairs) + 1
+        curses.init_pair(num, fg, bg)
+        self.colorpairs[pair] = num
+        return num
+
+
+    def _parseattrs(self, attrs):
+        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]
+        return res
+
+
+    def setcolor(self, name, desc):
+        parts = desc.split(',')
+        fg, bg = parts[0].split(' on ')
+        attrs = parts[1:]
+        fg = self._parsecolor(fg)
+        bg = self._parsecolor(bg)
+        col = self._getcolorpair(fg, bg)
+        attr = self._parseattrs(attrs)
+        self.colors[name] = curses.color_pair(col) | attr
+
+
+    def pushcolor(self, name):
+        attr = self.colors[name]
+        self.screen.attrset(attr)
+        self.colorstack.append(attr)
 
 
     def popcolor(self):
         self.colorstack.pop()
         if len(self.colorstack):
-            col, attr = self.colorstack[-1]
+            attr = self.colorstack[-1]
         else:
-            col, attr = 0, 0
-        self.screen.attrset(curses.color_pair(col) | attr)
+            attr = 0
+        self.screen.attrset(attr)
 
 
     ## drawing ##
@@ -257,8 +300,8 @@
         if not self.testclip(x, y):
             return
         self.cursor = (y, x)
-    
-        
+
+
     def hidecursor(self):
         curses.curs_set(False)
         self.cursor = None