A slew of tiny pager improvements

- stop displaying search bar widget on <ctrl-c>
- if there's existing search bar content highlight it automatically
  to allow user to start typing new content right away
- when activated allow search bar to insert its own set of keybinding
  controls; restore prior bindings on exit
kivy_mainline_and_py3.8
Tyler Goodlet 2019-03-21 22:01:50 -04:00
parent 3bbb1db2b4
commit 884fcaa88e
2 changed files with 54 additions and 14 deletions

View File

@ -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

View File

@ -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 <enter>
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 <enter> 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)