[shpy-commit] r2897 - shpy/trunk/dist/shpy/ui_pygame

arigo@codespeak.net arigo@codespeak.net
Mon, 26 Jan 2004 18:16:43 +0100 (MET)


Author: arigo
Date: Mon Jan 26 18:16:42 2004
New Revision: 2897

Modified:
   shpy/trunk/dist/shpy/ui_pygame/ui_pygame.py
Log:
A few UI details:
* more robust against the cursor or the firstline being deleted
* details in line colors
* details in scrolling
* K_DOWN creates a new cell after the last one
* K_DELETE deletes an empty cell
(the last two are quick hacks, should think about how to create and delete 
cells...)


Modified: shpy/trunk/dist/shpy/ui_pygame/ui_pygame.py
==============================================================================
--- shpy/trunk/dist/shpy/ui_pygame/ui_pygame.py	(original)
+++ shpy/trunk/dist/shpy/ui_pygame/ui_pygame.py	Mon Jan 26 18:16:42 2004
@@ -40,8 +40,8 @@
     name = decorate.structureproperty('name')
 
     def init_more(self):
+        self.savedposition = 0, 0
         self.fixme()
-        self.lineindex = self.cell.lines.index(self.line)
 
     def moveup(self):
         try:
@@ -88,10 +88,18 @@
         return self.x, self.line
 
     def fixme(self):
-        if self.cell not in self.terminal.root.cells:
-            self.cell = self.terminal.root.cells[0]  # or somewhere else
-        if self.line not in self.cell.lines:
-            self.line = self.cell.lines[0]
+        index1, index2 = self.savedposition
+        try:
+            index1 = self.terminal.root.cells.index(self.cell)
+        except ValueError:
+            index1 = min(index1, len(self.terminal.root.cells)-1)
+            self.cell = self.terminal.root.cells[index1]
+        try:
+            index2 = self.cell.lines.index(self.line)
+        except ValueError:
+            index2 = min(index2, len(self.cell.lines)-1)
+            self.line = self.cell.lines[index2]
+        self.savedposition = index1, index2
 
 
 class Root(decorate.Decorator):
@@ -103,10 +111,14 @@
     typeid = 'cell:0'
     lines = decorate.structureproperty('lines')
 
+    def is_empty(self):
+        return len(self.lines) == 1 and self.lines[0].content == ""
+
 class contentproperty(decorate.structureproperty):
     def __set__(self, ob, value):
-        ob.color = ob.terminal.cursor.color
-        super(contentproperty, self).__set__(ob, value)
+        if value != getattr(ob, 'content', None):
+            ob.color = ob.terminal.cursor.color
+            super(contentproperty, self).__set__(ob, value)
 
 class Line(decorate.Decorator):
     typeid = 'line:0'
@@ -130,7 +142,6 @@
         pygame.key.set_repeat(500,30)
         self.screen = pygame.display.set_mode(RESOLUTION, RESIZABLE)
         self.font = pygame.font.Font(FONT, HEIGHT)
-        self.fontheight = self.font.size('X')[1]
         self.builddecorators()
         self.root = self.Root.decorate(self.servergateway.registerclient())
         username = info.getusername()
@@ -153,6 +164,8 @@
             setattr(self, name, cls)
 
     def repaint(self):
+        self.firstline.fixme()
+        self.cursor.fixme()
         screenheight = self.screen.get_size()[1]
         while 1:
             self.screen.fill((255,255,255))
@@ -177,6 +190,7 @@
             self.scroll_a_bit_towards_cursor()
 
     def drawcursors(self):
+        screenheight = self.screen.get_size()[1]
         cursors = list(self.root.users)
         cursors.remove(self.cursor)
         cursors.append(self.cursor)
@@ -192,9 +206,14 @@
             if not char:
                 char = ' '
             charimage = self.font.render(char, 1, (255,255,255), cursor.color)
-            startoflineimagesize = self.font.size(line.content[:x])
+            startofline = line.content[:x]
+            if startofline:
+                startoflineimagesize = self.font.size(startofline)
+            else:
+                startoflineimagesize = 0, 0
             self.screen.blit(charimage, (startoflineimagesize[0], ypos))
-            if cursor == self.cursor and ypos >= 0:
+            if (cursor == self.cursor and ypos >= 0 and
+                ypos + charimage.get_size()[1] <= screenheight):
                 cursor_in_view = True
         return cursor_in_view
 
@@ -210,7 +229,7 @@
             lineimage = self.font.render(line.content or ' ', 1, line.getcolor())
             self.screen.blit(lineimage, (0, ypos))
             self.line2ypos[line] = ypos
-            ypos += self.fontheight
+            ypos += lineimage.get_size()[1]
         return ypos
                 
     def scroll_a_bit_towards_cursor(self):
@@ -252,7 +271,16 @@
         self.cursor.moveup()
                 
     def K_DOWN(self, event):
-        self.cursor.movedown()
+        try:
+            self.cursor.movedown()
+        except IndexError:
+            if self.cursor.cell.is_empty():
+                raise
+            newline = self.Line(content="")
+            newcell = self.Cell(lines = self.List([newline]))
+            self.root.cells.append(newcell)
+            self.cursor.cell = newcell
+            self.cursor.line = newline
 
     def K_LEFT(self, event):
         self.cursor.moveleft()
@@ -270,6 +298,11 @@
         x, line = self.cursor.xline()
         if x < len(line.content):
             line.content = line.content[:x] + line.content[x+1:]
+        elif self.cursor.cell.is_empty():
+            cell = self.cursor.cell
+            self.cursor.cell = self.root.cells.next(cell)
+            self.cursor.line = self.cursor.cell.lines[0]
+            self.root.cells.remove(cell)
         else:
             nextline = self.cursor.cell.lines.next(line)
             line.content += nextline.content