[Alpha] TreeGUI

I’m on a bit of a roll. Here’s better text editing, including caret drawing and left/right/home/end. (This patch subsumes the previous one.)

=== modified file treegui/drawer.py
--- treegui/drawer.py	2009-09-06 19:37:05 +0000
+++ treegui/drawer.py	2009-09-25 21:43:22 +0000
@@ -118,15 +118,18 @@
                 u,v,us,vs = rect
                 self.rectStreatch((realX,realY,us,vs),(u,v,us,vs))
             
-        if thing.text:
+        if thing.text is not None:
             # draw text stuff
             self.color = Vec4(0,0,0,1)
             self.drawText(
                 gui.theme.defineFont(thing.font),
                 thing.text,
                 realX,
-                realY)
+                realY,
+                selection = thing.text_selection,
+                caret_pos = thing.caret_pos)
             self.color = Vec4(1,1,1,1)
+
             
         if thing.children:
             for child in thing.children:
@@ -138,7 +141,7 @@
     
      
     
-    def drawText(self, font, text, x, y):
+    def drawText(self, font, text, x, y, selection=(0,0), caret_pos=-1):
         """ 
             draws the text
             needs more work! 
@@ -148,12 +151,17 @@
         ox = x
         baseLetter = self.atlas.getChar(name + str(ord("T")))
         omaxh = baseLetter[3] - baseLetter[4][1]
-
+        char_count = 0
+            
         for line in text.split("\n"):
             build = []
             maxh = omaxh  
-                
+
             for c in line:
+                if char_count == caret_pos:
+                    u,v,w,h,e = self.atlas.getChar(name + str(ord('|')))
+                    build.append((x-w/2,y+e[1],u,v,w,h))
+                char_count += 1
                 code = ord(c)            
                 if code <= 32:
                     u,v,w,h,e = self.atlas.getChar(name + str(77))
@@ -163,6 +171,13 @@
                 build.append((x,y+e[1],u,v,w,h))
                 x += e[0]
                 maxh = max(maxh,h-e[1])
+
+            else:
+                if char_count == caret_pos:
+                    u,v,w,h,e = self.atlas.getChar(name + str(ord('|')))
+                    build.append((x-w/2,y+e[1],u,v,w,h))
+
+            char_count += 1
                  
             for x,y,u,v,w,h in build:
                 self.rectStreatch((x,y+maxh-h,w,h),(u,v,w,h))
@@ -170,7 +185,6 @@
             x = ox     
             y += maxh
         
-        
     def rect(self,(x,y,xs,ys),(u,v)):
         """ draw a rectangle """
         us = xs

=== modified file treegui/keys.py
--- treegui/keys.py	2009-09-05 00:34:29 +0000
+++ treegui/keys.py	2009-09-25 21:30:46 +0000
@@ -25,17 +25,21 @@
         letters = "abcdefghijklmnopqrstuvwxyz"     
         symbols = "1234567890-=,./[]\\;'`"
         shifted = "!@#$%^&*()_+<>?{}|:\"~"
-        work = ['enter','backspace','space','tab']        
+        work = ['enter','backspace','space','tab','delete','home','end','arrow_left','arrow_up','arrow_down','arrow_right']        
         self.mouseEvents = dict.fromkeys(["mouse1", "mouse2", "mouse3"])
         for mouseEvent in ["mouse1", "mouse2", "mouse3","mouse1-up","mouse2-up","mouse3-up","shift-mouse1"]:
             base.accept(mouseEvent,self.onKey,[mouseEvent])
         for letter in symbols+letters:
             base.accept(letter,self.onKey,[letter])
+            base.accept(letter+'-repeat',self.onKey,[letter])
             base.accept('shift-'+letter,self.onKey,[letter.upper()])
+            base.accept('shift-'+letter+'-repeat',self.onKey,[letter.upper()])
         for event in work:
             base.accept(event,self.onKey,[event])
+            base.accept(event+'-repeat',self.onKey,[event])
         for index,key in enumerate(symbols):
             base.accept('shift-'+key,self.onKey, [shifted[index]] )
+            base.accept('shift-'+key+'-repeat',self.onKey, [shifted[index]] )
         self.inputKeys = dict.fromkeys(list(letters+letters.upper()+symbols+shifted)+work)
 
         self.lastMouseTime = 0

=== modified file treegui/widgets.py
--- treegui/widgets.py	2009-09-08 17:31:46 +0000
+++ treegui/widgets.py	2009-09-25 21:35:52 +0000
@@ -26,7 +26,10 @@
 
 
     text = None     
-    font = "default_font"     
+    font = "default_font"
+    text_selection = (0,0)
+    caret_pos = -1
+         
     icon = None
 
     visable = True       # can we see
@@ -159,7 +162,7 @@
     style = "entry"
     text = ""
     control = True
-    
+    caret_pos = -1
     textLimit = None
     
     def onClick(self):
@@ -167,17 +170,44 @@
         return True
     
     def onKey(self,char):
+        print "char:",char
         if len(char) == 1:
-            self.text += char
+            self.text = self.text[:self.caret_pos]+char+self.text[self.caret_pos:]
+            self.caret_pos += 1
         elif char == "backspace":
-            self.text = self.text[:-1]
+            if self.caret_pos > 0:
+                self.text = self.text[:self.caret_pos-1]+self.text[self.caret_pos:]
+                self.caret_pos -= 1
+        elif char == "delete":
+            if self.caret_pos < len(self.text):
+                self.text = self.text[:self.caret_pos]+self.text[self.caret_pos+1:]
         elif char == "space":
-            self.text += " "
+            self.text = self.text[:self.caret_pos]+" "+self.text[self.caret_pos:]
+            self.caret_pos += 1
+        elif char == "arrow_left":
+            if self.caret_pos > 0:
+                self.caret_pos -= 1
+        elif char == "arrow_right":
+            if self.caret_pos < len(self.text):
+                self.caret_pos += 1
+        elif char == "home":
+            if self.caret_pos > 0:
+                self.caret_pos = 0
+        elif char == "end":
+            if self.caret_pos > 0:
+                self.caret_pos = len(self.text)
+                
         else:
             print char,"undefined for tree text entry yet"
             
         if self.textLimit:
             self.text = self.text[:self.textLimit]
+            
+    def onFocus(self):
+        self.caret_pos = len(self.text)
+        
+    def onUnfocus(self):
+        self.caret_pos = -1
     
 class PasswordEntry(Entry):
     """ single line entry that types as stars "*" """