2017-09-27 21:15:34 +00:00
|
|
|
# Copyright (c) 2014-2017 esotericnonsense (Daniel Edgecumbe)
|
|
|
|
# Distributed under the MIT software license, see the accompanying
|
|
|
|
# file COPYING or https://opensource.org/licenses/mit-license.php
|
|
|
|
|
|
|
|
from macros import MODES
|
|
|
|
|
|
|
|
|
|
|
|
class ModeHandler(object):
|
2017-09-28 02:06:10 +00:00
|
|
|
def __init__(self, base_callbacks):
|
2017-09-27 21:15:34 +00:00
|
|
|
self._mode = None
|
|
|
|
|
|
|
|
self._callbacks = {} # mode -> callback, one per mode.
|
2017-09-28 02:06:10 +00:00
|
|
|
self._base_callbacks = base_callbacks
|
2017-09-27 21:15:34 +00:00
|
|
|
|
|
|
|
self._keypress_handlers = {} # mode -> keypress handler.
|
|
|
|
|
|
|
|
def add_callback(self, key, callback):
|
|
|
|
self._callbacks[key] = callback
|
|
|
|
|
|
|
|
def add_keypress_handler(self, key, handler):
|
|
|
|
self._keypress_handlers[key] = handler
|
|
|
|
|
|
|
|
async def _call_callbacks(self, oldmode, newmode):
|
|
|
|
# Tell the old mode that it's no longer active
|
|
|
|
try:
|
|
|
|
cb1 = self._callbacks[oldmode]
|
|
|
|
except KeyError:
|
|
|
|
cb1 = None
|
|
|
|
|
|
|
|
if cb1 is not None:
|
|
|
|
await cb1(newmode)
|
|
|
|
|
|
|
|
# Tell the new mode that it's now active
|
|
|
|
try:
|
|
|
|
cb2 = self._callbacks[newmode]
|
|
|
|
except KeyError:
|
|
|
|
cb2 = None
|
|
|
|
|
|
|
|
if cb2 is not None:
|
|
|
|
await cb2(newmode)
|
|
|
|
|
2017-09-28 02:06:10 +00:00
|
|
|
# Base callbacks (FooterView, HeaderView)
|
|
|
|
for bcb in self._base_callbacks:
|
|
|
|
await bcb(newmode)
|
2017-09-27 21:15:34 +00:00
|
|
|
|
|
|
|
async def set_mode(self, newmode):
|
|
|
|
if self._mode == newmode:
|
|
|
|
return
|
|
|
|
|
|
|
|
await self._call_callbacks(self._mode, newmode)
|
|
|
|
self._mode = newmode
|
|
|
|
|
|
|
|
async def _seek_mode(self, seek):
|
|
|
|
if self._mode is None:
|
|
|
|
# Can't seek if no mode
|
|
|
|
return
|
|
|
|
|
|
|
|
idx = MODES.index(self._mode)
|
|
|
|
idx = (idx + seek) % len(MODES)
|
|
|
|
newmode = MODES[idx]
|
|
|
|
|
|
|
|
await self.set_mode(newmode)
|
|
|
|
|
|
|
|
async def handle_keypress(self, key):
|
|
|
|
# See if it's related to switching modes.
|
|
|
|
if key == "KEY_LEFT":
|
|
|
|
await self._seek_mode(-1)
|
|
|
|
return None
|
|
|
|
|
|
|
|
if key == "KEY_RIGHT":
|
|
|
|
await self._seek_mode(1)
|
|
|
|
return None
|
|
|
|
|
|
|
|
if len(key) == 1:
|
|
|
|
for mode in MODES:
|
|
|
|
if mode[0] == key.lower():
|
|
|
|
await self.set_mode(mode)
|
|
|
|
return None
|
|
|
|
|
|
|
|
# See if the current mode can handle it.
|
|
|
|
if self._mode is None:
|
|
|
|
return key
|
|
|
|
|
|
|
|
try:
|
|
|
|
handler = self._keypress_handlers[self._mode]
|
|
|
|
except KeyError:
|
|
|
|
return key
|
|
|
|
|
|
|
|
key = await handler(key)
|
|
|
|
|
|
|
|
return key # Either none by this point, or still there.
|