tuikit/editfield.py
changeset 0 a35731b5e31a
child 5 ae128c885d0f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tuikit/editfield.py	Wed Feb 16 23:51:30 2011 +0100
@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+
+import curses
+import locale
+
+from .widget import Widget
+
+
+class EditField(Widget):
+    def __init__(self, width=10, value=''):
+        Widget.__init__(self, width, 1)
+
+        self.code = locale.getpreferredencoding()
+        if not type(value) is str:
+            value = str(value, self.code)
+
+        self.value = value
+        self.maxlen = None   # unlimited
+
+        self.tw = self.width - 2  # real width of text field (minus space for arrows)
+        self.cursor = 0   # position of cursor on screen
+        self.pos = 0      # position of cursor in value
+        self.ofs = 0      # position of value beginning on screen
+
+        self.connect('draw', self.on_draw)
+        self.connect('keypress', self.on_keypress)
+
+
+    def on_draw(self, screen, x, y):
+        # draw value
+        val = self.value + ' ' * self.tw         # add spaces to fill rest of field
+        val = val[self.ofs : self.ofs + self.tw]  # cut value - begin from ofs, limit to tw chars
+        screen.puts(x + 1, y, val.encode(self.code))
+
+        # draw arrows if content overflows
+        c = ' '
+        if self.ofs > 0:
+            c = '<'
+        screen.putch(x, y, c)
+
+        c = ' '
+        if len(self.value[self.ofs:]) > self.tw:
+            c = '>'
+        screen.putch(x + self.width-1, y, c)
+
+        # move cursor to the position
+        screen.showcursor(x + 1 + self.cursor, y)
+
+
+    def on_keypress(self, keyname, char):
+        if keyname:
+            if keyname == 'left':
+                self.move_left()
+
+            if keyname == 'right':
+                self.move_right()
+
+            if keyname == 'backspace':
+                if self.pos > 0:
+                    self.move_left()
+                    self.del_char()
+
+            if keyname == 'delete':
+                self.del_char()
+
+        if char:
+            self.add_char(char)
+            self.move_right()
+
+        self.redraw()
+
+
+    def move_left(self):
+        if self.cursor > 1 or (self.cursor == 1 and self.pos == 1):
+            # move cursor
+            self.pos -= 1
+            self.cursor -= 1
+        else:
+            # move content in field
+            if self.pos > self.cursor:
+                self.pos -= 1
+                self.ofs -= 1
+
+
+    def move_right(self):
+        if self.pos < len(self.value):
+            if self.cursor < self.tw - 2 \
+            or (self.cursor == self.tw - 2 and self.pos == len(self.value)-1):
+                # move cursor
+                self.pos += 1
+                self.cursor += 1
+            else:
+                # move content in field
+                self.pos += 1
+                self.ofs += 1
+
+
+    def add_char(self, c):
+        self.value = self.value[:self.pos] + c + self.value[self.pos:]
+
+
+    def del_char(self):
+        self.value = self.value[:self.pos] + self.value[self.pos+1:]
+