new input control

This commit is contained in:
Will McGugan
2022-09-28 12:24:28 +01:00
parent effd6211d3
commit 72e59aad26
7 changed files with 31 additions and 8 deletions

View File

@@ -1,5 +1,5 @@
from textual.app import App from textual.app import App
from textual.widgets import TextInput from textual.widgets import Input
class InputApp(App): class InputApp(App):
@@ -11,7 +11,9 @@ class InputApp(App):
""" """
def compose(self): def compose(self):
yield TextInput(initial="foo") yield Input("foo")
app = InputApp() if __name__ == "__main__":
app = InputApp()
app.run()

View File

@@ -522,20 +522,24 @@ class MessagePump(metaclass=MessagePumpMeta):
return False return False
# TODO: Does dispatch_key belong on message pump? # TODO: Does dispatch_key belong on message pump?
async def dispatch_key(self, event: events.Key) -> None: async def dispatch_key(self, event: events.Key) -> bool:
"""Dispatch a key event to method. """Dispatch a key event to method.
This method will call the method named 'key_<event.key>' if it exists. This method will call the method named 'key_<event.key>' if it exists.
Args: Args:
event (events.Key): A key event. event (events.Key): A key event.
Returns:
bool: True if key was handled, otherwise False.
""" """
key_method = getattr(self, f"key_{event.key_name}", None) or getattr( key_method = getattr(self, f"key_{event.key_name}", None) or getattr(
self, f"_key_{event.key_name}", None self, f"_key_{event.key_name}", None
) )
if key_method is not None: if key_method is not None:
await invoke(key_method, event) await invoke(key_method, event)
event.prevent_default() return True
return False
async def on_timer(self, event: events.Timer) -> None: async def on_timer(self, event: events.Timer) -> None:
event.prevent_default() event.prevent_default()

View File

@@ -184,6 +184,7 @@ class Reactive(Generic[ReactiveType]):
compute_method = getattr(obj, f"compute_{compute}") compute_method = getattr(obj, f"compute_{compute}")
except AttributeError: except AttributeError:
continue continue
value = await invoke(compute_method) value = await invoke(compute_method)
setattr(obj, compute, value) setattr(obj, compute, value)

View File

@@ -71,6 +71,7 @@ class Timer:
self._skip = skip self._skip = skip
self._active = Event() self._active = Event()
self._task: Task | None = None self._task: Task | None = None
self._reset: bool = False
if not pause: if not pause:
self._active.set() self._active.set()
@@ -116,6 +117,10 @@ class Timer:
""" """
self._active.clear() self._active.clear()
def reset(self) -> None:
self._active.set()
self._reset = True
def resume(self) -> None: def resume(self) -> None:
"""Resume a paused timer.""" """Resume a paused timer."""
self._active.set() self._active.set()
@@ -144,8 +149,14 @@ class Timer:
wait_time = max(0, next_timer - now) wait_time = max(0, next_timer - now)
if wait_time: if wait_time:
await _clock.sleep(wait_time) await _clock.sleep(wait_time)
count += 1 count += 1
await self._active.wait() await self._active.wait()
if self._reset:
start = _clock.get_time_no_wait()
count = 0
self._reset = False
continue
try: try:
await self._tick(next_timer=next_timer, count=count) await self._tick(next_timer=next_timer, count=count)
except EventTargetGone: except EventTargetGone:

View File

@@ -1808,12 +1808,15 @@ class Widget(DOMNode):
await self.broker_event("click", event) await self.broker_event("click", event)
async def _on_key(self, event: events.Key) -> None: async def _on_key(self, event: events.Key) -> None:
await self.handle_key(event)
async def handle_key(self, event: events.Key) -> bool:
try: try:
binding = self._bindings.get_key(event.key) binding = self._bindings.get_key(event.key)
except NoBinding: except NoBinding:
await self.dispatch_key(event) return await self.dispatch_key(event)
else: await self.action(binding.action)
await self.action(binding.action) return True
def _on_compose(self, event: events.Compose) -> None: def _on_compose(self, event: events.Compose) -> None:
widgets = self.compose() widgets = self.compose()

View File

@@ -20,6 +20,7 @@ __all__ = [
"Pretty", "Pretty",
"Static", "Static",
"TextInput", "TextInput",
"Input",
"TextLog", "TextLog",
"TreeControl", "TreeControl",
"Welcome", "Welcome",

View File

@@ -7,6 +7,7 @@ from ._header import Header as Header
from ._placeholder import Placeholder as Placeholder from ._placeholder import Placeholder as Placeholder
from ._pretty import Pretty as Pretty from ._pretty import Pretty as Pretty
from ._static import Static as Static from ._static import Static as Static
from ._input import Input as Input
from ._text_input import TextInput as TextInput from ._text_input import TextInput as TextInput
from ._text_log import TextLog as TextLog from ._text_log import TextLog as TextLog
from ._tree_control import TreeControl as TreeControl from ._tree_control import TreeControl as TreeControl