tuikit/editbox.py
changeset 0 a35731b5e31a
child 3 33ec838dc021
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tuikit/editbox.py	Wed Feb 16 23:51:30 2011 +0100
@@ -0,0 +1,210 @@
+# -*- coding: utf-8 -*-
+
+from .widget import Widget
+
+class EditBox(Widget):
+    def __init__(self, width=20, height=20, text=''):
+        Widget.__init__(self, width, height)
+
+        self.set_text(text)
+
+        self.xofs = 0
+        self.yofs = 0
+
+        # cursor
+        self.cline = 0
+        self.cpos = 0
+
+        # selection
+        self.sline = 0
+        self.spos = 0
+
+        self.connect('draw', self.on_draw)
+        self.connect('keypress', self.on_keypress)
+        self.connect('mousewheel', self.on_mousewheel)
+
+        self.newevent('scroll')
+        self.newevent('areasize')
+
+
+    def on_draw(self, screen, x, y):
+        for j in range(self.height):
+            if self.yofs + j >= len(self.lines):
+                break
+            line = self.lines[self.yofs + j]
+            #if len(line) < self.width:
+                #line += ' ' * (self.width - len(line))
+            #else:
+                #line = line[:self.width]
+            screen.puts(x, y + j, line)
+
+        screen.showcursor(x + self.get_cpos() - self.xofs, y + self.cline - self.yofs)
+
+
+    def on_keypress(self, keyname, char):
+        if keyname:
+            if keyname == 'left':
+                self.move_left()
+
+            if keyname == 'right':
+                self.move_right()
+
+            if keyname == 'home':
+                self.move_home()
+
+            if keyname == 'end':
+                self.move_end()
+
+            if keyname == 'up':
+                self.move_up()
+
+            if keyname == 'down':
+                self.move_down()
+
+            if keyname == 'pageup':
+                self.move_pageup()
+
+            if keyname == 'pagedown':
+                self.move_pagedown()
+
+            if keyname == 'backspace':
+                if self.cline > 0 or self.cpos > 0:
+                    self.move_left()
+                    self.del_char()
+
+            if keyname == 'delete':
+                self.del_char()
+
+            if keyname == 'enter':
+                self.add_newline()
+                self.move_right()
+
+        if char:
+            self.add_char(char)
+            self.move_right()
+
+        self.redraw()
+
+
+    def on_mousewheel(self, ev):
+        # up
+        if ev.button == 4:
+            self.move_up()
+        # down
+        if ev.button == 5:
+            self.move_down()
+        self.redraw()
+
+
+    def set_text(self, text):
+        self.lines = text.split('\n')
+
+
+    def get_text(self):
+        return '\n'.join(self.lines)
+
+
+    def get_linelen(self):
+        return len(self.lines[self.cline])
+
+
+    def get_cpos(self):
+        if self.cpos > self.get_linelen():
+            return self.get_linelen()
+        return self.cpos
+
+
+    def set_yofs(self, yofs):
+        if yofs < 0:
+            yofs = 0
+        if yofs > len(self.lines) - self.height:
+            yofs = len(self.lines) - self.height
+        self.yofs = yofs
+        self.handle('scroll')
+
+
+    def move_left(self):
+        if self.cpos > 0:
+            self.cpos = self.get_cpos() - 1
+        else:
+            if self.move_up():
+                self.cpos = self.get_linelen()
+
+
+    def move_right(self):
+        if self.cpos < self.get_linelen():
+            self.cpos += 1
+        else:
+            if self.move_down():
+                self.cpos = 0
+
+
+    def move_home(self):
+        self.cpos = 0
+
+
+    def move_end(self):
+        self.cpos = self.get_linelen()
+
+
+    def move_up(self):
+        if self.cline > 0:
+            self.cline -= 1
+            if self.cline < self.yofs:
+                self.set_yofs(self.cline)
+            return True
+        return False
+
+
+    def move_down(self):
+        if self.cline < len(self.lines) - 1:
+            self.cline += 1
+            if self.cline > self.yofs + self.height - 1:
+                self.set_yofs(self.cline - (self.height - 1))
+            return True
+        return False
+
+
+    def move_pageup(self):
+        if self.cline >= self.height - 1:
+            self.cline -= self.height - 1
+            self.set_yofs(self.yofs - (self.height - 1))
+        else:
+            self.cline = 0
+            self.set_yofs(0)
+
+
+    def move_pagedown(self):
+        if self.cline <= len(self.lines) - (self.height - 1):
+            self.cline += self.height - 1
+            self.set_yofs(self.yofs + (self.height - 1))
+        else:
+            self.cline = len(self.lines) - 1
+            self.set_yofs(self.cline)
+
+
+    def add_char(self, c):
+        ln = self.lines[self.cline]
+        cpos = self.get_cpos()
+        self.lines[self.cline] = ln[:cpos] + c + ln[cpos:]
+        self.cpos = cpos
+
+
+    def add_newline(self):
+        ln = self.lines[self.cline]
+        cpos = self.get_cpos()
+        self.lines[self.cline] = ln[cpos:]
+        self.lines.insert(self.cline, ln[:cpos])
+        self.handle('areasize')
+
+
+    def del_char(self):
+        ln = self.lines[self.cline]
+        cpos = self.get_cpos()
+        if cpos == self.get_linelen():
+            if self.cline + 1 < len(self.lines):
+                self.lines[self.cline] = self.lines[self.cline] + self.lines[self.cline+1]
+                del self.lines[self.cline+1]
+                self.handle('areasize')
+        else:
+            self.lines[self.cline] = ln[:cpos] + ln[cpos+1:]