Implement cursor blink and reverse toggle

This commit is contained in:
Andrew Kay
2019-12-27 20:14:30 -06:00
parent 86fbbdfd29
commit c373457dff
5 changed files with 89 additions and 6 deletions

View File

@@ -5,8 +5,8 @@ oec.controller
import time
import logging
from coax import poll, poll_ack, PollAction, KeystrokePollResponse, ReceiveTimeout, \
ReceiveError, ProtocolError
from coax import poll, poll_ack, load_control_register, PollAction, \
KeystrokePollResponse, ReceiveTimeout, ReceiveError, ProtocolError
from .terminal import Terminal, read_terminal_ids
from .keyboard import Key
@@ -156,8 +156,16 @@ class Controller:
if not key:
return
if key == Key.CLICKER:
self.terminal.keyboard.clicker = not self.terminal.keyboard.clicker
if key == Key.CURSOR_BLINK:
self.terminal.display.toggle_cursor_blink()
self._load_control_register()
elif key == Key.ALT_CURSOR:
self.terminal.display.toggle_cursor_reverse()
self._load_control_register()
elif key == Key.CLICKER:
self.terminal.keyboard.toggle_clicker()
elif self.session:
self.session.handle_key(key, modifiers, scan_code)
@@ -198,3 +206,6 @@ class Controller:
period = self.disconnected_poll_period
return (self.last_poll_time + period) - current_time
def _load_control_register(self):
load_control_register(self.interface, self.terminal.get_control_register())

View File

@@ -181,6 +181,9 @@ class Display:
self.status_line = StatusLine(self.interface, columns)
self.cursor_reverse = False
self.cursor_blink = False
def move_cursor(self, index=None, row=None, column=None, force_load=False):
"""Load the address counter."""
address = self._calculate_address(index=index, row=row, column=column)
@@ -239,6 +242,12 @@ class Display:
self.move_cursor(row=0, column=0, force_load=True)
def toggle_cursor_blink(self):
self.cursor_blink = not self.cursor_blink
def toggle_cursor_reverse(self):
self.cursor_reverse = not self.cursor_reverse
def _get_index(self, row, column):
return (row * self.dimensions.columns) + column

View File

@@ -333,6 +333,9 @@ class Keyboard:
return (key, self.modifiers, False)
def toggle_clicker(self):
self.clicker = not self.clicker
def _apply_modifiers(self, scan_code, key):
# TODO: Consider detection, in single modifier release mode, of entering
# modififier release but the next keystroke not being a modifier... also

View File

@@ -5,7 +5,7 @@ oec.terminal
import time
import logging
from coax import read_terminal_id, read_extended_id, PollAction, ReceiveError, \
from coax import read_terminal_id, read_extended_id, PollAction, Control, ReceiveError, \
ProtocolError
from .display import Dimensions, Display
@@ -87,3 +87,9 @@ class Terminal:
return PollAction.ENABLE_KEYBOARD_CLICKER if self.keyboard.clicker else PollAction.DISABLE_KEYBOARD_CLICKER
return PollAction.NONE
def get_control_register(self):
control = Control(cursor_reverse=self.display.cursor_reverse,
cursor_blink=self.display.cursor_blink)
return control

View File

@@ -37,6 +37,10 @@ class RunLoopTestCase(unittest.TestCase):
self.read_terminal_ids_mock.return_value = TERMINAL_IDS
patcher = patch('oec.controller.load_control_register')
self.load_control_register_mock = patcher.start()
patcher = patch('oec.controller.time.perf_counter')
self.perf_counter_mock = patcher.start()
@@ -114,7 +118,57 @@ class RunLoopTestCase(unittest.TestCase):
self.assertFalse(self.controller.terminal.alarm)
def test_clicker_toggle(self):
def test_toggle_cursor_blink(self):
self._assert_run_loop(0, PowerOnResetCompletePollResponse(0xa), 0, True)
self.assertFalse(self.controller.terminal.display.cursor_blink)
self._assert_run_loop(0, KeystrokePollResponse(0b0101010010), 0, True)
self.assertTrue(self.controller.terminal.display.cursor_blink)
self.load_control_register_mock.assert_called()
self.assertTrue(self.load_control_register_mock.call_args[0][1].cursor_blink)
self.load_control_register_mock.reset_mock()
self._assert_run_loop(0, KeystrokePollResponse(0b0101010010), 0, True)
self.assertFalse(self.controller.terminal.display.cursor_blink)
self.load_control_register_mock.assert_called()
self.assertFalse(self.load_control_register_mock.call_args[0][1].cursor_blink)
def test_toggle_cursor_reverse(self):
self._assert_run_loop(0, PowerOnResetCompletePollResponse(0xa), 0, True)
self.assertFalse(self.controller.terminal.display.cursor_reverse)
self._assert_run_loop(0, KeystrokePollResponse(0b0100111110), 0, True)
self._assert_run_loop(0, KeystrokePollResponse(0b0101010010), 0, True)
self._assert_run_loop(0, KeystrokePollResponse(0b0100111110), 0, True)
self.assertTrue(self.controller.terminal.display.cursor_reverse)
self.load_control_register_mock.assert_called()
self.assertTrue(self.load_control_register_mock.call_args[0][1].cursor_reverse)
self.load_control_register_mock.reset_mock()
self._assert_run_loop(0, KeystrokePollResponse(0b0100111110), 0, True)
self._assert_run_loop(0, KeystrokePollResponse(0b0101010010), 0, True)
self._assert_run_loop(0, KeystrokePollResponse(0b0100111110), 0, True)
self.assertFalse(self.controller.terminal.display.cursor_reverse)
self.load_control_register_mock.assert_called()
self.assertFalse(self.load_control_register_mock.call_args[0][1].cursor_reverse)
def test_toggle_clicker(self):
self._assert_run_loop(0, PowerOnResetCompletePollResponse(0xa), 0, True)
self.assertFalse(self.controller.terminal.keyboard.clicker)