Rework layouts: Layout is now normal Container which places its children upon resize event.
Drop TopWindow, top is now any subclass of Container.
Add floater concept: floaters are widgets drawn over normal widgets, not clipped by parent.
Add HScrollbar and Scrollbar abstract base class.
# -*- coding: utf-8 -*-
import locale
from tuikit.widget import Widget
class EditField(Widget):
def __init__(self, value=''):
Widget.__init__(self)
self._default_size.update(10, 1)
self.allow_focus = True
self.code = locale.getpreferredencoding()
if not isinstance(value, str):
value = str(value, self.code)
self.value = value
self.maxlen = None # unlimited
self.tw = 0 # real width of text field (minus space for arrows)
self.pos = len(value) # position of cursor in value
self.ofs = 0 # position of value beginning on screen
def on_resize(self, ev):
self.tw = self.width - 2
def on_draw(self, ev):
ev.driver.pushcolor('normal')
# 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
ev.driver.puts(ev.x + 1, ev.y, val.encode(self.code))
# draw arrows if content overflows
c = ' '
if self.ofs > 0:
c = '<'
ev.driver.putch(ev.x, ev.y, c)
c = ' '
if len(self.value[self.ofs:]) > self.tw:
c = '>'
ev.driver.putch(ev.x + self.width-1, ev.y, c)
self.cursor = (1 + self.pos - self.ofs, 0)
ev.driver.popcolor()
def on_keypress(self, ev):
handled = False
if ev.keyname:
handled = True
if ev.keyname == 'left':
self.move_left()
elif ev.keyname == 'right':
self.move_right()
elif ev.keyname == 'backspace':
if self.pos > 0:
self.move_left()
self.del_char()
elif ev.keyname == 'delete':
self.del_char()
else:
handled = False
if ev.char:
self.add_char(ev.char)
self.move_right()
handled = True
self.redraw()
return handled
def move_left(self):
if self.pos - self.ofs > 1 or (self.ofs == 0 and self.pos == 1):
# move cursor
self.pos -= 1
else:
# move content in field
if self.ofs > 0:
self.pos -= 1
self.ofs -= 1
def move_right(self):
if self.pos < len(self.value):
if self.pos - self.ofs < self.tw - 2 \
or (self.pos - self.ofs == self.tw - 2 and self.pos == len(self.value)-1):
# move cursor
self.pos += 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:]