mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
new input control
This commit is contained in:
@@ -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()
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ __all__ = [
|
|||||||
"Pretty",
|
"Pretty",
|
||||||
"Static",
|
"Static",
|
||||||
"TextInput",
|
"TextInput",
|
||||||
|
"Input",
|
||||||
"TextLog",
|
"TextLog",
|
||||||
"TreeControl",
|
"TreeControl",
|
||||||
"Welcome",
|
"Welcome",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user