Fixed escape sequence handling.
# -*- coding: utf-8 -*-
from .widget import Widget
class EditBox(Widget):
def __init__(self, width=20, height=20, text=''):
Widget.__init__(self, width, height)
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')
self.set_text(text)
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')
self.handle('areasize')
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 > len(self.lines) - self.height:
yofs = len(self.lines) - self.height
if yofs < 0:
yofs = 0
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 move_pagefirst(self):
self.cline = 0
self.set_yofs(0)
def move_pagelast(self):
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:]