[shpy-commit] r2869 - in shpy/trunk/dist/shpy: . net
hpk@codespeak.net
hpk@codespeak.net
Tue, 20 Jan 2004 22:48:12 +0100 (MET)
Author: hpk
Date: Tue Jan 20 22:48:11 2004
New Revision: 2869
Modified:
shpy/trunk/dist/shpy/net/shared.py
shpy/trunk/dist/shpy/ui_pygame.py
Log:
- hi michael :-)
- we now draw a list of cells
- a cell now contains a list of structures (each representing a line)
so that lines can be updated and propagated independently, and so that we
can use a reference to the "current" line of each cursor
instead of an index into some list.
- the screen is drawn starting from the *last line* that is visible
and then up backwards from there.
- the screen doesn't yet scroll automatically to follow the cursor
Modified: shpy/trunk/dist/shpy/net/shared.py
==============================================================================
--- shpy/trunk/dist/shpy/net/shared.py (original)
+++ shpy/trunk/dist/shpy/net/shared.py Tue Jan 20 22:48:11 2004
@@ -17,10 +17,27 @@
def __init__(self, **attributes):
self.__dict__.update(attributes)
+
+def structurelist(*args):
+ l = []
+ for arg in args:
+ l.append(Structure(content=arg))
+ return l
+
root = Structure()
-root.cells = Structure()
-cell = Structure(lines=open('/etc/passwd', 'r').read().split('\n'))
-root.cells.list = [cell]
+root.cells = Structure(list = [
+ Structure(lines = structurelist(
+ 'def f():',
+ ' for i in range(10):',
+ ' print i * 42',
+ ' break',
+ )),
+ Structure(lines = structurelist(
+ 'def f():',
+ ' print 42',
+ )),
+ ]
+)
root.users = Structure()
Modified: shpy/trunk/dist/shpy/ui_pygame.py
==============================================================================
--- shpy/trunk/dist/shpy/ui_pygame.py (original)
+++ shpy/trunk/dist/shpy/ui_pygame.py Tue Jan 20 22:48:11 2004
@@ -39,131 +39,198 @@
self.servergateway = shpy.net.register.ServerGateway(hostport, ns)
pygame.init()
pygame.key.set_repeat(500,30)
- pygame.display.set_mode(RESOLUTION, RESIZABLE)
+ self.screen = pygame.display.set_mode(RESOLUTION, RESIZABLE)
self.font = pygame.font.Font(FONT, HEIGHT)
self.fontheight = self.font.size('X')[1]
self.root = self.servergateway.registerclient()
+ self.changed = {}
username = info.getusername()
try:
self.cursor = getattr(self.root.users, username)
except AttributeError:
- self.cursor = Structure(x=0, y=0, color=info.getcolor())
+ self.cursor = Structure(x=0, color=info.getcolor())
setattr(self.root.users, username, self.cursor)
- self.notifychanges(self.cursor, self.root.users)
- print self.root.users.__dict__
- self.cell = self.root.cells.list[0]
- self.vscroll = 0
+ #print self.root.users.__dict__
+ self.celllist = self.root.cells.list
+ if not hasattr(self.cursor, 'cell') or self.cursor.cell not in self.celllist:
+ self.cursor.cell = self.celllist[-1]
+ if not hasattr(self.cursor, 'line') or self.cursor.line not in self.cursor.cell.lines:
+ self.cursor.line = self.cursor.cell.lines[-1]
+ self.lastline_cell = self.cursor.cell
+ self.lastline = self.lastline_cell.lines[-1]
+ self.changed[self.cursor] = 1
+ self.changed[self.root.users] = 1
def repaint(self):
- screen = pygame.display.get_surface()
- screen.fill((255,255,255))
- self.drawcell(screen, self.cell)
+ self.screen.fill((255,255,255))
+ self.bring_lastline_in_view_of_cursor()
+ self.line2ypos = {}
+
+ index = self.lastline_cell.lines.index(self.lastline)
+ lines = self.lastline_cell.lines[:index+1]
+ ypos = self.drawlinesbackwards(lines)
+ if ypos > 0:
+ index = self.celllist.index(self.lastline_cell)
+ remainingcells = self.celllist[:index]
+ while remainingcells and ypos > 0:
+ cell = remainingcells.pop()
+ ypos = self.drawspacing(ypos)
+ ypos = self.drawlinesbackwards(cell.lines, ypos)
+ self.drawcursors()
pygame.display.flip()
- def drawcell(self, screen, cell):
- self.scroll_cursor_into_view(screen)
- start = -self.vscroll//self.fontheight
- stop = (-self.vscroll + screen.get_size()[1])//self.fontheight + 1
- ypos = self.vscroll + start*self.fontheight
- for line in cell.lines[start:stop]:
- lineimage = self.font.render(line or ' ', 1, (0,0,0))
- screen.blit(lineimage, (0, ypos))
- ypos += self.fontheight
- self.drawcursors(screen, cell)
-
- def char_pos(self, cell, x, y):
- line = cell.lines[y]
- return (self.font.size(line[:x])[0],
- y*self.fontheight + self.vscroll)
-
- def char_rect(self, cell, x, y):
- c = cell.lines[y][x:x+1]
- if not c:
- c = ' '
- return Rect(self.char_pos(x, y), self.font.size(c))
-
- def scroll_cursor_into_view(self, screen):
- ypos = self.vscroll + self.cursor.y * self.fontheight
- if ypos < 0:
- screen.fill((255, 255, 255))
- self.vscroll -= ypos
- elif ypos + self.fontheight > screen.get_size()[1]:
- screen.fill((255, 255, 255))
- self.vscroll -= ypos + self.fontheight - screen.get_size()[1]
-
- def drawcursors(self, screen, cell):
+ def drawcursors(self):
for cursor in self.root.users.__dict__.values():
x = cursor.x
- y = cursor.y
- if y >= len(cell.lines):
- y = len(cell.lines)-1
- char = cell.lines[y][x:x+1]
+ line = cursor.line
+ try:
+ ypos = self.line2ypos[line]
+ except KeyError:
+ continue
+ char = line.content[x:x+1]
if not char:
char = ' '
charimage = self.font.render(char, 1, (255,255,255), cursor.color)
- screen.blit(charimage, self.char_pos(cell, x, y))
+ startoflineimagesize = self.font.size(line.content[:x])
+ self.screen.blit(charimage, (startoflineimagesize[0], ypos))
+
+ def drawspacing(self, ypos):
+ self.screen.fill((160, 160, 160), Rect(0, ypos-2, 100, 1))
+ return ypos - 3
+
+ def drawlinesbackwards(self, lines, ypos = None):
+ if ypos is None:
+ ypos = self.screen.get_size()[1]
+ l = lines[:]
+ while l and ypos > 0:
+ line = l.pop()
+ lineimage = self.font.render(line.content or ' ', 1, (0,0,0))
+ ypos -= self.fontheight
+ self.screen.blit(lineimage, (0, ypos))
+ self.line2ypos[line] = ypos
+ return ypos
+
+ def bring_lastline_in_view_of_cursor(self):
+ pass
+
+## def drawcell(self, screen, cell):
+## self.scroll_cursor_into_view(screen)
+## start = -self.vscroll//self.fontheight
+## stop = (-self.vscroll + screen.get_size()[1])//self.fontheight + 1
+## ypos = self.vscroll + start*self.fontheight
+## for line in cell.lines[start:stop]:
+## lineimage = self.font.render(line or ' ', 1, (0,0,0))
+## screen.blit(lineimage, (0, ypos))
+## ypos += self.fontheight
+## self.drawcursors(screen, cell)
+
+## def char_pos(self, cell, x, y):
+## line = cell.lines[y]
+## return (self.font.size(line[:x])[0],
+## y*self.fontheight + self.vscroll)
+
+## def char_rect(self, cell, x, y):
+## c = cell.lines[y][x:x+1]
+## if not c:
+## c = ' '
+## return Rect(self.char_pos(x, y), self.font.size(c))
+
+## def scroll_cursor_into_view(self, screen):
+## ypos = self.vscroll + self.cursor.y * self.fontheight
+## if ypos < 0:
+## self.vscroll -= ypos
+## elif ypos + self.fontheight > screen.get_size()[1]:
+## self.vscroll -= ypos + self.fontheight - screen.get_size()[1]
+
+## def drawcursors(self, screen, cell):
+## for cursor in self.root.users.__dict__.values():
+## x = cursor.x
+## y = cursor.y
+## if y >= len(cell.lines):
+## y = len(cell.lines)-1
+## char = cell.lines[y][x:x+1]
+## if not char:
+## char = ' '
+## charimage = self.font.render(char, 1, (255,255,255), cursor.color)
+## screen.blit(charimage, self.char_pos(cell, x, y))
def PRINTABLE_KEY(self, event):
assert event.unicode
x = self.cursor.x
- y = self.cursor.y
- line = self.cell.lines[y]
- line = line[:x] + event.unicode + line[x:]
- self.cell.lines[y] = line
+ line = self.cursor.line
+ line.content = line.content[:x] + event.unicode + line.content[x:]
self.cursor.x += len(event.unicode)
- self.changed[self.cell] = 1
+ self.changed[line] = 1
def CTRL_K_a(self, event):
self.cursor.x = 0
def CTRL_K_e(self, event):
- self.cursor.x = len(self.cell.lines[self.cursor.y])
+ self.cursor.x = len(self.cursor.line.content)
def K_UP(self, event):
- if self.cursor.y > 0:
- self.cursor.y -= 1
-
+ index = self.cursor.cell.lines.index(self.cursor.line)
+ if index > 0:
+ self.cursor.line = self.cursor.cell.lines[index-1]
+ else:
+ # XXX this changes if we have output cells ...
+ index = self.celllist.index(self.cursor.cell)
+ if index > 0:
+ self.cursor.cell = self.celllist[index-1]
+ self.cursor.line = self.cursor.cell.lines[-1]
+
def K_DOWN(self, event):
- if self.cursor.y < len(self.cell.lines)-1:
- self.cursor.y += 1
+ index = self.cursor.cell.lines.index(self.cursor.line)
+ if index + 1 < len(self.cursor.cell.lines):
+ self.cursor.line = self.cursor.cell.lines[index+1]
+ else:
+ # XXX this changes if we have output cells ...
+ index = self.celllist.index(self.cursor.cell)
+ if index + 1 < len(self.celllist):
+ self.cursor.cell = self.celllist[index+1]
+ self.cursor.line = self.cursor.cell.lines[0]
def K_LEFT(self, event):
if self.cursor.x > 0:
self.cursor.x -= 1
def K_RIGHT(self, event):
- line = self.cell.lines[self.cursor.y]
- if self.cursor.x < len(line):
+ if self.cursor.x < len(self.cursor.line.content):
self.cursor.x += 1
def K_BACKSPACE(self, event):
x = self.cursor.x
- y = self.cursor.y
+ line = self.cursor.line
if x > 0:
- line = self.cell.lines[y]
- line = line[:x-1] + line[x:]
- self.cell.lines[y] = line
+ line.content = line.content[:x-1] + line.content[x:]
+ self.changed[line] = 1
self.cursor.x -= 1
- elif y > 0:
- line = self.cell.lines[y]
- prevline = self.cell.lines[y-1]
- self.cell.lines[y-1:y+1] = [prevline + line]
- self.cursor.y -= 1
- self.cursor.x = len(prevline)
- self.changed[self.cell] = 1
+ else:
+ index = self.cursor.cell.lines.index(line)
+ if index > 0:
+ prevline = self.cursor.cell.lines[index-1]
+ prevline.content += line.content
+ del self.cursor.cell.lines[index]
+ self.changed[prevline] = 1
+ self.changed[self.cursor.cell] = 1
+ self.cursor.line = prevline
+ self.cursor.x = len(prevline.content)
def K_RETURN(self, event):
x = self.cursor.x
- y = self.cursor.y
- line = self.cell.lines[y]
- self.cell.lines[y:y+1] = [line[:x], line[x:]]
+ line = self.cursor.line
+ newline = Structure(content=line.content[x:])
+ line.content = line.content[:x]
+ index = self.cursor.cell.lines.index(line)
+ self.cursor.cell.lines.insert(index+1, newline)
+ self.cursor.line = newline
self.cursor.x = 0
- self.cursor.y += 1
- self.changed[self.cell] = 1
+ self.changed[self.cursor.cell] = 1
+ self.changed[line] = 1
+ self.changed[newline] = 1
def run(self):
self.invalid = True
- self.changed = {}
while 1:
if self.changed:
self.notifychanges(*self.changed.keys())
@@ -190,7 +257,7 @@
if event.type == QUIT:
break
if event.type == VIDEORESIZE:
- pygame.display.set_mode(event.size, RESIZABLE)
+ self.screen = pygame.display.set_mode(event.size, RESIZABLE)
self.invalid = True
def close(self):