diff --git a/piker/brokers/__init__.py b/piker/brokers/__init__.py index ae14799c..53597752 100644 --- a/piker/brokers/__init__.py +++ b/piker/brokers/__init__.py @@ -18,7 +18,7 @@ def get_brokermod(brokername: str) -> ModuleType: """Return the imported broker module by name. """ module = import_module('.' + brokername, 'piker.brokers') - # we only allows monkeys because it's for internal keying + # we only allow monkeying because it's for internal keying module.name = module.__name__.split('.')[-1] return module diff --git a/piker/ui/pager.py b/piker/ui/pager.py index 65aabf60..a4eb0351 100644 --- a/piker/ui/pager.py +++ b/piker/ui/pager.py @@ -4,7 +4,7 @@ Pager widget + kb controls import inspect from functools import partial -from kivy.core.window import Window +from kivy.core.window import Window, Widget from kivy.uix.textinput import TextInput from kivy.uix.scrollview import ScrollView @@ -12,7 +12,12 @@ from ..log import get_logger log = get_logger('keyboard') -async def handle_input(nursery, widget, patts2funcs: dict, patt_len_limit=3): +async def handle_input( + nursery, + widget, + patts2funcs: dict, + patt_len_limit=3 +) -> None: """Handle keyboard input. For each character pattern-tuple in ``patts2funcs`` invoke the @@ -31,10 +36,13 @@ async def handle_input(nursery, widget, patts2funcs: dict, patt_len_limit=3): while True: async for kb, keycode, text, modifiers in keyq: - log.debug( - f"Keyboard input received:\n" - f"key {keycode}\ntext {text}\nmodifiers {modifiers}" - ) + log.debug(f""" + kb: {kb} + keycode: {keycode} + text: {text} + modifiers: {modifiers} + patts2funcs: {patts2funcs} + """) code, key = keycode if modifiers and key in modifiers: continue @@ -61,6 +69,7 @@ async def handle_input(nursery, widget, patts2funcs: dict, patt_len_limit=3): log.debug(f'invoking kb func {func}') func() last_patt = [] + break if len(last_patt) > patt_len_limit: last_patt = [] @@ -75,26 +84,41 @@ async def handle_input(nursery, widget, patts2funcs: dict, patt_len_limit=3): class SearchBar(TextInput): - def __init__(self, kbctls: dict, container: 'Widget', pager: 'PagerView', - searcher, **kwargs): + def __init__( + self, + container: Widget, + pager: 'PagerView', + searcher, + **kwargs + ): super(SearchBar, self).__init__( multiline=False, hint_text='Ticker Search', - cursor_blink=False, **kwargs ) + self.cursor_blink = False self.foreground_color = self.hint_text_color # actually readable - self.kbctls = kbctls self._container = container self._pager = pager self._searcher = searcher # indicate to ``handle_input`` that search is activated on '/' - self.kbctls.update({ + self._pager.kbctls.update({ ('/',): self.handle_input }) + + self.kbctls = { + ('ctrl-c',): self.undisplay, + } + self._sugg_template = ' '*4 + '{} matches: ' self._matched = [] + def undisplay(self): + "Stop displaying this text widget" + self.dispatch('on_text_validate') # same as pressing + if self.text_validate_unfocus: + self.focus = False + def suggest(self, matches): self.suggestion_text = '' suffix = self._sugg_template.format(len(matches) or "No") @@ -138,14 +162,31 @@ class SearchBar(TextInput): self._pager.scroll_to(widget) async def handle_input(self): + # TODO: wrap this in a cntx mng + old_ctls = self._pager.kbctls.copy() + self._pager.kbctls.clear() + # makes a copy + self._pager.kbctls.update(self.kbctls) + self._container.add_widget(self) # display it self.focus = True # focus immediately (doesn't work from __init__) + + # select any existing text making the widget ready + # to accept new input right away + if self.text: + self.select_all() + # wait for to close search bar await self.async_bind('on_text_validate').__aiter__().__anext__() log.debug(f"Seach text is {self.text}") log.debug("Closing search bar") self._container.remove_widget(self) # stop displaying + + # restore old keyboard bindings + self._pager.kbctls.clear() + self._pager.kbctls.update(old_ctls) + return self.text @@ -167,8 +208,7 @@ class PagerView(ScrollView): # add contained child widget (can only be one) self._contained = contained self.add_widget(contained) - self.search = SearchBar( - self.kbctls, container, self, searcher=contained) + self.search = SearchBar(container, self, searcher=contained) # spawn kb handler task nursery.start_soon(handle_input, nursery, self, self.kbctls)