mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
invoke changes
This commit is contained in:
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Callbacks may be async or non-async.
|
||||
- Event handler event argument is optional.
|
||||
- Fixed exception in clock example https://github.com/willmcgugan/textual/issues/52
|
||||
- Added Message.wait() which waits for a message to be processed
|
||||
|
||||
## [0.1.9] - 2021-08-06
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from textual.app import App
|
||||
from textual import events
|
||||
from textual.widgets import Placeholder
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ async def invoke(callback: Callable, *params: object) -> Any:
|
||||
Returns:
|
||||
Any: [description]
|
||||
"""
|
||||
_rich_traceback_guard = True
|
||||
parameter_count = count_parameters(callback)
|
||||
|
||||
result = callback(*params[:parameter_count])
|
||||
|
||||
@@ -35,10 +35,10 @@ class LinuxDriver(Driver):
|
||||
width: int | None = 80
|
||||
height: int | None = 25
|
||||
try:
|
||||
width, height = os.get_terminal_size(sys.stdin.fileno())
|
||||
width, height = os.get_terminal_size(sys.__stdin__.fileno())
|
||||
except (AttributeError, ValueError, OSError):
|
||||
try:
|
||||
width, height = os.get_terminal_size(sys.stdout.fileno())
|
||||
width, height = os.get_terminal_size(sys.__stdout__.fileno())
|
||||
except (AttributeError, ValueError, OSError):
|
||||
pass
|
||||
width = width or 80
|
||||
|
||||
@@ -28,6 +28,7 @@ from .layouts.dock import DockLayout, Dock
|
||||
from ._linux_driver import LinuxDriver
|
||||
from .message_pump import MessagePump
|
||||
from .message import Message
|
||||
from ._profile import timer
|
||||
from .view import View
|
||||
from .views import DockView
|
||||
from .widget import Widget, Widget, Reactive
|
||||
@@ -181,7 +182,6 @@ class App(MessagePump):
|
||||
async def push_view(self, view: ViewType) -> ViewType:
|
||||
self.register(view, self)
|
||||
self._view_stack.append(view)
|
||||
# await view.post_message(events.Mount(sender=self))
|
||||
return view
|
||||
|
||||
def on_keyboard_interupt(self) -> None:
|
||||
@@ -252,22 +252,24 @@ class App(MessagePump):
|
||||
|
||||
async def process_messages(self) -> None:
|
||||
active_app.set(self)
|
||||
driver = self._driver = self.driver_class(self.console, self)
|
||||
|
||||
log("---")
|
||||
log(f"driver={self.driver_class}")
|
||||
|
||||
await self.dispatch_message(events.Load(sender=self))
|
||||
load_event = events.Load(sender=self)
|
||||
await self.dispatch_message(load_event)
|
||||
await self.post_message(events.Mount(self))
|
||||
await self.push_view(DockView())
|
||||
|
||||
# Wait for the load event to be processed, so we don't go in to application mode beforehand
|
||||
await load_event.wait()
|
||||
|
||||
driver = self._driver = self.driver_class(self.console, self)
|
||||
try:
|
||||
driver.start_application_mode()
|
||||
except Exception:
|
||||
self.console.print_exception()
|
||||
else:
|
||||
traceback: Traceback | None = None
|
||||
|
||||
try:
|
||||
self.title = self._title
|
||||
self.refresh()
|
||||
@@ -275,24 +277,15 @@ class App(MessagePump):
|
||||
await super().process_messages()
|
||||
log("PROCESS END")
|
||||
await self.animator.stop()
|
||||
|
||||
await self.close_all()
|
||||
|
||||
# while self.children:
|
||||
# child = self.children.pop()
|
||||
# log(f"closing {child}")
|
||||
# await child.close_messages()
|
||||
|
||||
# while self._view_stack:
|
||||
# view = self._view_stack.pop()
|
||||
# await view.close_messages()
|
||||
except Exception:
|
||||
self.panic()
|
||||
finally:
|
||||
driver.stop_application_mode()
|
||||
if self._exit_renderables:
|
||||
for traceback in self._exit_renderables:
|
||||
self.error_console.print(traceback)
|
||||
for renderable in self._exit_renderables:
|
||||
self.error_console.print(renderable)
|
||||
if self.log_file is not None:
|
||||
self.log_file.close()
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from asyncio import Event
|
||||
from typing import Awaitable, Callable, Type, TYPE_CHECKING, TypeVar
|
||||
|
||||
import rich.repr
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from asyncio import Event
|
||||
from time import monotonic
|
||||
from typing import ClassVar
|
||||
|
||||
@@ -17,6 +20,7 @@ class Message:
|
||||
"time",
|
||||
"_no_default_action",
|
||||
"_stop_propagation",
|
||||
"__done_event",
|
||||
]
|
||||
|
||||
sender: MessageTarget
|
||||
@@ -35,6 +39,7 @@ class Message:
|
||||
self.time = monotonic()
|
||||
self._no_default_action = False
|
||||
self._stop_propagation = False
|
||||
self.__done_event: Event | None = None
|
||||
super().__init__()
|
||||
|
||||
def __rich_repr__(self) -> rich.repr.Result:
|
||||
@@ -45,14 +50,20 @@ class Message:
|
||||
cls.bubble = bubble
|
||||
cls.verbosity = verbosity
|
||||
|
||||
@property
|
||||
def _done_event(self) -> Event:
|
||||
if self.__done_event is None:
|
||||
self.__done_event = Event()
|
||||
return self.__done_event
|
||||
|
||||
def can_replace(self, message: "Message") -> bool:
|
||||
"""Check if another message may supersede this one.
|
||||
|
||||
Args:
|
||||
message (Message): [description]
|
||||
message (Message): Another message.
|
||||
|
||||
Returns:
|
||||
bool: [description]
|
||||
bool: True if this message may replace the given message
|
||||
"""
|
||||
return False
|
||||
|
||||
@@ -66,4 +77,13 @@ class Message:
|
||||
self._no_default_action = prevent
|
||||
|
||||
def stop(self, stop: bool = True) -> None:
|
||||
"""Stop propagation of the message to parent.
|
||||
|
||||
Args:
|
||||
stop (bool, optional): The stop flag. Defaults to True.
|
||||
"""
|
||||
self._stop_propagation = stop
|
||||
|
||||
async def wait(self) -> None:
|
||||
"""Wait for the message to be processed."""
|
||||
await self._done_event.wait()
|
||||
|
||||
@@ -218,11 +218,14 @@ class MessagePump:
|
||||
|
||||
async def dispatch_message(self, message: Message) -> bool | None:
|
||||
_rich_traceback_guard = True
|
||||
if isinstance(message, events.Event):
|
||||
if not isinstance(message, events.Null):
|
||||
await self.on_event(message)
|
||||
else:
|
||||
return await self.on_message(message)
|
||||
try:
|
||||
if isinstance(message, events.Event):
|
||||
if not isinstance(message, events.Null):
|
||||
await self.on_event(message)
|
||||
else:
|
||||
return await self.on_message(message)
|
||||
finally:
|
||||
message._done_event.set()
|
||||
return False
|
||||
|
||||
def _get_dispatch_methods(
|
||||
|
||||
@@ -75,7 +75,7 @@ class DirectoryTree(TreeControl[DirEntry]):
|
||||
await node.add(entry.name, DirEntry(entry.path, entry.is_dir()))
|
||||
node.loaded = True
|
||||
await node.expand()
|
||||
# self.refresh(layout=True)
|
||||
self.refresh(layout=True)
|
||||
|
||||
async def message_tree_click(self, message: TreeClick[DirEntry]) -> None:
|
||||
dir_entry = message.node.data
|
||||
|
||||
Reference in New Issue
Block a user