Update PyGame driver.
authorrbrich
Fri, 14 Dec 2012 10:16:33 +0100
changeset 31 629d5edb1602
parent 30 05500124d7fb
child 32 088b92ffb119
Update PyGame driver.
tuikit/driver_pygame.py
--- a/tuikit/driver_pygame.py	Thu Dec 13 10:01:32 2012 +0100
+++ b/tuikit/driver_pygame.py	Fri Dec 14 10:16:33 2012 +0100
@@ -28,11 +28,54 @@
         
         # choose self.render() implementation
         if hasattr(self.font, 'render_glyph'):
-            self.render = self.render_glyph
+            self.render_char = self.render_glyph
         else:
-            self.render = self.render_noglyph
+            self.render_char = self.render_noglyph
+            
+        self.chars = None
+        self.attrs = None
+        self.default_attr = None
+        self.current_attr = None
+
+    def set_default_attr(self, fg, bg, flags):
+        self.default_attr = (fg, bg, flags)
+    
+    def set_attr(self, fg, bg, flags):
+        self.current_attr = (fg, bg, flags)
+    
+    def reset_attr(self):
+        self.current_attr = self.default_attr
 
-    def render_glyph(self, screen, x, y, c, fgcolor, bgcolor, defcolor, attr):
+    def reset(self, w, h):
+        self.w, self.h = w, h
+        numchars = w * h
+        self.chars = [' '] * numchars
+        self.attrs = [self.default_attr] * numchars
+    
+    def clear(self):
+        numchars = self.w * self.h
+        for pos in range(numchars):
+            self.chars[pos] = ' '
+            self.attrs[pos] = self.default_attr
+    
+    def putch(self, x, y, c):
+        pos = y * self.w + x
+        self.chars[pos] = c
+        self.attrs[pos] = self.current_attr
+    
+    def update(self, surface):
+        pos = 0
+        for y in range(self.h):
+            for x in range(self.w):
+                fgcolor, bgcolor, flags = self.attrs[pos]
+                c = self.chars[pos]
+                if c == ' ':
+                    c = None
+                self.render_char(surface, x, y, c,
+                    fgcolor, bgcolor, flags)
+                pos += 1
+
+    def render_glyph(self, screen, x, y, c, fgcolor, bgcolor, flags):
         '''Render using render_glyph and metrics.
         
         This is the correct way, but the output seems same as of render_noglyph
@@ -43,14 +86,14 @@
         '''                
         # draw background
         dest = Coords(x * self.charsize.w, y * self.charsize.h)
-        if bgcolor != defcolor:
+        if bgcolor != self.default_attr[1]:
             screen.fill(bgcolor, pygame.Rect(dest.x, dest.y, self.charsize.w, self.charsize.h))
         
         if not c:
             return
 
         # choose font
-        if attr == 'bold':
+        if flags == 1:
             font = self.font_bold
         else:
             font = self.font
@@ -175,22 +218,20 @@
         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.term = TerminalScreen()
         self.charsize = self.term.charsize
         self.resize_screen()
+        self.term.set_default_attr(self.colormap['white'], self.colormap['black'], 0)
+        self.term.reset_attr()
         mainfunc()
 
     def resize_screen(self):
         mode = self.size.w * self.charsize.w, self.size.h * self.charsize.h
         self.screen = pygame.display.set_mode(mode, pygame.RESIZABLE)
-        numchars = self.size.w * self.size.h
-        self.screenchars = [' '] * numchars
-        self.screencolors = [self.default_color] * numchars
+        self.term.reset(self.size.w, self.size.h)
 
     ## input ##
     
@@ -251,31 +292,17 @@
     
     def erase(self):
         '''Clear screen.'''
-        numchars = self.size.w * self.size.h
-        for pos in range(numchars):
-            self.screenchars[pos] = ' '
-            self.screencolors[pos] = self.default_color
-        self.screen.fill(self.default_color[1])
+        self.term.clear()
+        self.screen.fill(self.term.default_attr[1])
     
     def putch(self, x, y, c):
         if not self.clipstack.test(x, y):
             return
-        pos = y*self.size.w+x
-        self.screencolors[pos] = self.current_color
-        self.screenchars[pos] = c
+        self.term.putch(x, y, c)
 
     def commit(self):
         '''Commit changes to the screen.'''
-        pos = 0
-        for y in range(self.size.h):
-            for x in range(self.size.w):
-                fgcolor, bgcolor, attr = self.screencolors[pos]
-                c = self.screenchars[pos]
-                if c == ' ':
-                    c = None
-                self.term.render(self.screen, x, y, c,
-                    fgcolor, bgcolor, self.default_color[1], attr)
-                pos += 1
+        self.term.update(self.screen)
         pygame.display.flip()
 
 
@@ -292,7 +319,7 @@
         for a in attrs:
             a = a.lower().strip()
             if a == 'bold':
-                res = a
+                res = 1
         return res
 
     def setcolor(self, name, desc):
@@ -326,9 +353,9 @@
         self.colorstack.pop()
         if len(self.colorstack):
             col = self.colorstack[-1]
+            self.term.set_attr(col[0], col[1], col[2])
         else:
-            col = self.default_color
-        self.current_color = col
+            self.term.reset_attr()
 
 
     ## cursor ##