Implement cursor movement APIs

This commit is contained in:
Kovid Goyal 2016-10-19 20:15:07 +05:30
parent fea7c2dcb0
commit b354e95401
2 changed files with 49 additions and 17 deletions

View File

@ -66,6 +66,11 @@ class Screen(QObject):
def notify_cursor_position(self, x, y):
if self._notify_cursor_position:
if x >= self.columns:
if y < self.lines - 1:
x, y = 0, y + 1
else:
x, y = x - 1, y
self.cursor_position_changed(self.cursor, x, y)
@property
@ -707,59 +712,63 @@ class Screen(QObject):
self.cursor.x = max(0, min(self.cursor.x, self.columns - 1))
self.cursor.y = max(top, min(self.cursor.y, bottom))
def cursor_up(self, count=None):
def cursor_up(self, count=1, do_carriage_return=False, move_direction=-1):
"""Moves cursor up the indicated # of lines in same column.
Cursor stops at top margin.
:param int count: number of lines to skip.
"""
self.cursor.y -= count or 1
x, y = self.cursor.x, self.cursor.y
self.cursor.y += move_direction * (count or 1)
self.ensure_bounds(use_margins=True)
if do_carriage_return:
self.cursor.x = 0
if y != self.cursor.y or x != self.cursor.x:
self.notify_cursor_position(x, y)
def cursor_up1(self, count=None):
def cursor_up1(self, count=1):
"""Moves cursor up the indicated # of lines to column 1. Cursor
stops at bottom margin.
:param int count: number of lines to skip.
"""
self.cursor_up(count)
self.carriage_return()
self.cursor_up(count, do_carriage_return=True)
def cursor_down(self, count=None):
def cursor_down(self, count=1):
"""Moves cursor down the indicated # of lines in same column.
Cursor stops at bottom margin.
:param int count: number of lines to skip.
"""
self.cursor.y += count or 1
self.ensure_bounds(use_margins=True)
self.cursor_up(count, move_direction=1)
def cursor_down1(self, count=None):
def cursor_down1(self, count=1):
"""Moves cursor down the indicated # of lines to column 1.
Cursor stops at bottom margin.
:param int count: number of lines to skip.
"""
self.cursor_down(count)
self.carriage_return()
self.cursor_up(count, do_carriage_return=True, move_direction=1)
def cursor_back(self, count=None):
def cursor_back(self, count=1, move_direction=-1):
"""Moves cursor left the indicated # of columns. Cursor stops
at left margin.
:param int count: number of columns to skip.
"""
self.cursor.x -= count or 1
x = self.cursor.x
self.cursor.x += move_direction * (count or 1)
self.ensure_bounds()
if x != self.cursor.x:
self.notify_cursor_position(x, self.cursor.y)
def cursor_forward(self, count=None):
def cursor_forward(self, count=1):
"""Moves cursor right the indicated # of columns. Cursor stops
at right margin.
:param int count: number of columns to skip.
"""
self.cursor.x += count or 1
self.ensure_bounds()
self.cursor_back(count, move_direction=1)
def cursor_position(self, line=None, column=None):
"""Set the cursor to a specific `line` and `column`.

View File

@ -64,7 +64,7 @@ class TestScreen(BaseTest):
self.ae(str(s.linebuf[0]), 'ココx')
self.ae(str(s.linebuf[1]), 'ニチ ')
self.ae(str(s.linebuf[2]), '')
self.assertChanges(t, ignore='cursor', cells={0: ((5, 5),), 1: ((0, 3),), 2: ((0, 1),)})
self.assertChanges(t, ignore='cursor', cells={1: ((0, 3),), 2: ((0, 1),)})
self.ae(s.cursor.x, 2), self.ae(s.cursor.y, 2)
s.draw('Ƶ̧\u0308'.encode('utf-8'))
self.ae(str(s.linebuf[2]), 'ハƵ̧\u0308 ')
@ -192,3 +192,26 @@ class TestScreen(BaseTest):
self.ae(s.display, (' ', ' ', ' ', ' ', ' '))
self.assertChanges(t, lines=set(range(5)))
self.assertFalse(s.linebuf[0].cursor_from(1).bold)
def test_cursor_movement(self):
s, t = self.create_screen()
s.draw(b'12345' * 5)
t.reset()
s.cursor_up(2)
self.ae((s.cursor.x, s.cursor.y), (4, 2))
self.assertChanges(t, ignore='cursor', cells={4: ((4, 4),)})
s.cursor_up1()
self.ae((s.cursor.x, s.cursor.y), (0, 1))
self.assertChanges(t, ignore='cursor', cells={2: ((4, 4),)})
s.cursor_forward(3)
self.ae((s.cursor.x, s.cursor.y), (3, 1))
self.assertChanges(t, ignore='cursor', cells={1: ((0, 0),)})
s.cursor_back()
self.ae((s.cursor.x, s.cursor.y), (2, 1))
self.assertChanges(t, ignore='cursor', cells={1: ((3, 3),)})
s.cursor_down()
self.ae((s.cursor.x, s.cursor.y), (2, 2))
self.assertChanges(t, ignore='cursor', cells={1: ((2, 2),)})
s.cursor_down1(5)
self.ae((s.cursor.x, s.cursor.y), (0, 4))
self.assertChanges(t, ignore='cursor', cells={2: ((2, 2),)})