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.widgets import TextInput
from textual.widgets import Input
class InputApp(App):
@@ -11,7 +11,9 @@ class InputApp(App):
"""
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
# 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.
This method will call the method named 'key_<event.key>' if it exists.
Args:
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(
self, f"_key_{event.key_name}", None
)
if key_method is not None:
await invoke(key_method, event)
event.prevent_default()
return True
return False
async def on_timer(self, event: events.Timer) -> None:
event.prevent_default()

View File

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

View File

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

View File

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

View File

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

View File

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