invoke changes

This commit is contained in:
Will McGugan
2021-08-17 19:49:24 +01:00
parent a5f0a8948a
commit 98a0670dc1
9 changed files with 45 additions and 27 deletions

View File

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

View File

@@ -1,5 +1,4 @@
from textual.app import App
from textual import events
from textual.widgets import Placeholder

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,6 @@
from __future__ import annotations
from asyncio import Event
from typing import Awaitable, Callable, Type, TYPE_CHECKING, TypeVar
import rich.repr

View File

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

View File

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

View File

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