uix:TextInput fixes for editing that were raised while testing text predictions on

android.
This commit is contained in:
qua-non 2013-04-06 23:15:11 +05:30
parent d4dcbfb0a4
commit b1701f7619
2 changed files with 42 additions and 21 deletions

View File

@ -127,7 +127,8 @@ class CodeInput(TextInput):
width = Cache_get('textinput.width', text + '_' + str(self.lexer)) width = Cache_get('textinput.width', text + '_' + str(self.lexer))
if width: if width:
return width return width
width = self._create_line_label(text).width lbl = self._create_line_label(text)
width = lbl.width if lbl else 0
Cache_append( Cache_append(
'textinput.width', 'textinput.width',
text + '_' + str(self.lexer), width) text + '_' + str(self.lexer), width)

View File

@ -403,7 +403,10 @@ class TextInput(Widget):
start, finish, lines,\ start, finish, lines,\
lineflags, len_lines = self._get_line_from_cursor(cr, new_text) lineflags, len_lines = self._get_line_from_cursor(cr, new_text)
self._trigger_refresh_text('insert', start, finish, lines, # calling trigger here could lead to wrong cursor positioning
# and repeating of text when keys are added rapidly in a automated
# fashion. From Android Keyboard for example.
self._refresh_text_from_property('insert', start, finish, lines,
lineflags, len_lines) lineflags, len_lines)
self.cursor = self.get_cursor_from_index(ci + len_str) self.cursor = self.get_cursor_from_index(ci + len_str)
@ -411,6 +414,7 @@ class TextInput(Widget):
self._set_unredo_insert(ci, ci + len_str, substring, from_undo) self._set_unredo_insert(ci, ci + len_str, substring, from_undo)
def _get_line_from_cursor(self, start, new_text): def _get_line_from_cursor(self, start, new_text):
# get current paragraph from cursor position
finish = start finish = start
lines = self._lines lines = self._lines
linesflags = self._lines_flags linesflags = self._lines_flags
@ -424,7 +428,7 @@ class TextInput(Widget):
except IndexError: except IndexError:
pass pass
lines, lineflags = self._split_smart(new_text) lines, lineflags = self._split_smart(new_text)
len_lines = max(1, len(lines) - 1) len_lines = max(1, len(lines))
return start, finish, lines, lineflags, len_lines return start, finish, lines, lineflags, len_lines
def _set_unredo_insert(self, ci, sci, substring, from_undo): def _set_unredo_insert(self, ci, sci, substring, from_undo):
@ -463,7 +467,7 @@ class TextInput(Widget):
self.insert_text(substring, True) self.insert_text(substring, True)
elif undo_type == 'bkspc': elif undo_type == 'bkspc':
self.cursor = _get_cusror_from_index(x_item['redo_command']) self.cursor = _get_cusror_from_index(x_item['redo_command'])
self.do_backspace(True) self.do_backspace(from_undo=True)
else: else:
# delsel # delsel
ci, sci = x_item['redo_command'] ci, sci = x_item['redo_command']
@ -521,44 +525,59 @@ class TextInput(Widget):
if self.readonly: if self.readonly:
return return
cc, cr = self.cursor cc, cr = self.cursor
text = self._lines[cr] _lines = self._lines
text = _lines[cr]
cursor_index = self.cursor_index() cursor_index = self.cursor_index()
prev_line_len = len(_lines[cr - 1])
text_last_line = _lines[cr - 1]
if cc == 0 and cr == 0: if cc == 0 and cr == 0:
return return
_lines_flags = self._lines_flags _lines_flags = self._lines_flags
start = cr
if cc == 0: if cc == 0:
text_last_line = self._lines[cr - 1]
substring = '\n' if _lines_flags[cr] else ' ' substring = '\n' if _lines_flags[cr] else ' '
self._set_line_text(cr - 1, text_last_line + text) new_text = text_last_line + text
self._set_line_text(cr - 1, new_text)
self._delete_line(cr) self._delete_line(cr)
new_text = '' start = cr - 1
else: else:
#ch = text[cc-1] #ch = text[cc-1]
substring = text[cc - 1] substring = text[cc - 1]
new_text = text[:cc - 1] + text[cc:] new_text = text[:cc - 1] + text[cc:]
self._set_line_text(cr, new_text) self._set_line_text(cr, new_text)
if not self._lines_flags[cr]: # refresh just the current line instead of the whole text
# refresh just the current line instead of the whole text start, finish, lines, lineflags, len_lines =\
start, finish, lines, lineflags, len_lines =\ self._get_line_from_cursor(start, new_text)
self._get_line_from_cursor(cr, new_text) # avoid trigger refresh, leads to issue with
self._trigger_refresh_text('del', start, finish, lines, # keys/text send rapidly through code.
lineflags, len_lines) self._refresh_text_from_property('del', start, finish, lines,
lineflags, len_lines)
# Instead of calling get_cursor_from_index every time avoid till it's
# really needed leads to improvements while editing large amounts of
# text.
if self.selection_from != self.selection_to: if self.selection_from != self.selection_to:
col, row = self.get_cursor_from_index(cursor_index - 1) col, row = self.get_cursor_from_index(cursor_index - 1)
else: else:
col, row = self.cursor col, row = cc, cr
if col == 0: if col == 0:
row -= 1 if row else 0 if row:
col = len(self._lines[row]) row -= 1
col = prev_line_len
else: else:
col, row = col - 1, row if (row > 0) and text_last_line != self._lines[row - 1]:
col, row = self.get_cursor_from_index(cursor_index - 1)
else:
col, row = col - 1, row
self.cursor = col, row self.cursor = col, row
# handle undo and redo # handle undo and redo
self._set_undo_redo_bkspc(cursor_index, self._set_undo_redo_bkspc(
cursor_index - 1, cursor_index,
substring, from_undo) cursor_index - 1,
substring, from_undo)
def _set_undo_redo_bkspc(self, ol_index, new_index, substring, from_undo): def _set_undo_redo_bkspc(self, ol_index, new_index, substring, from_undo):
# handle undo and redo for backspace # handle undo and redo for backspace
@ -651,6 +670,7 @@ class TextInput(Widget):
def cancel_selection(self): def cancel_selection(self):
'''Cancel current selection (if any). '''Cancel current selection (if any).
''' '''
self._selection_from = self._selection_to = self.cursor_index()
self._selection = False self._selection = False
self._selection_finished = True self._selection_finished = True
self._selection_touch = None self._selection_touch = None