From 4903e7c79fc9bdf9fec7efd9f8bf11c9ffeab37e Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sat, 18 Sep 2021 20:45:24 +0100 Subject: [PATCH] fix for refreshing layout --- docs/examples/widgets/placeholders.py | 3 +-- src/textual/app.py | 8 ++------ src/textual/driver.py | 1 + src/textual/message.py | 6 ++++-- src/textual/message_pump.py | 13 ++++++++++++- src/textual/reactive.py | 1 - src/textual/view.py | 5 ++--- src/textual/widgets/_button.py | 1 + 8 files changed, 23 insertions(+), 15 deletions(-) diff --git a/docs/examples/widgets/placeholders.py b/docs/examples/widgets/placeholders.py index 28406add0..30e566b5b 100644 --- a/docs/examples/widgets/placeholders.py +++ b/docs/examples/widgets/placeholders.py @@ -1,4 +1,3 @@ -from textual import events from textual.app import App from textual.widgets import Placeholder @@ -6,7 +5,7 @@ from textual.widgets import Placeholder class SimpleApp(App): """Demonstrates smooth animation""" - async def on_mount(self, event: events.Mount) -> None: + async def on_mount(self) -> None: """Build layout here.""" await self.view.dock(Placeholder(), edge="left", size=40) diff --git a/src/textual/app.py b/src/textual/app.py index 2b3a79346..331c31563 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -135,9 +135,10 @@ class App(MessagePump): if self.log_file and verbosity <= self.log_verbosity: output = f" ".join(str(arg) for arg in args) if kwargs: - output += " " + " ".join( + key_values = " ".join( f"{key}={value}" for key, value in kwargs.items() ) + output = " ".join((output, key_values)) self.log_file.write(output + "\n") self.log_file.flush() except Exception: @@ -301,11 +302,6 @@ class App(MessagePump): if self.log_file is not None: self.log_file.close() - async def call_later(self, callback: Callable, *args, **kwargs) -> None: - await self.post_message( - events.Callback(self, partial(callback, *args, **kwargs)) - ) - def register(self, child: MessagePump, parent: MessagePump) -> bool: if child not in self.children: self.children.add(child) diff --git a/src/textual/driver.py b/src/textual/driver.py index 3235b5b3f..ed4df782d 100644 --- a/src/textual/driver.py +++ b/src/textual/driver.py @@ -7,6 +7,7 @@ from abc import ABC, abstractmethod from typing import TYPE_CHECKING from . import events +from . import log from ._types import MessageTarget if TYPE_CHECKING: diff --git a/src/textual/message.py b/src/textual/message.py index 466fde61f..7a5af02a9 100644 --- a/src/textual/message.py +++ b/src/textual/message.py @@ -77,7 +77,7 @@ class Message: """ return False - def prevent_default(self, prevent: bool = True) -> None: + def prevent_default(self, prevent: bool = True) -> Message: """Suppress the default action. Args: @@ -85,14 +85,16 @@ class Message: or False if the default actions should be performed. Defaults to True. """ self._no_default_action = prevent + return self - def stop(self, stop: bool = True) -> None: + def stop(self, stop: bool = True) -> Message: """Stop propagation of the message to parent. Args: stop (bool, optional): The stop flag. Defaults to True. """ self._stop_propagation = stop + return self async def wait(self) -> None: """Wait for the message to be processed.""" diff --git a/src/textual/message_pump.py b/src/textual/message_pump.py index 4761246cc..0da7c6953 100644 --- a/src/textual/message_pump.py +++ b/src/textual/message_pump.py @@ -3,6 +3,7 @@ from __future__ import annotations import asyncio from asyncio import CancelledError from asyncio import Queue, QueueEmpty, Task +from functools import partial from typing import TYPE_CHECKING, Awaitable, Iterable, Callable from weakref import WeakSet @@ -144,10 +145,20 @@ class MessagePump: self._child_tasks.add(asyncio.get_event_loop().create_task(timer.run())) return timer + async def call_later(self, callback: Callable, *args, **kwargs) -> None: + """Run a callback after processing all messages and refreshing the screen. + + Args: + callback (Callable): A callable. + """ + await self.post_message( + events.Callback(self, partial(callback, *args, **kwargs)) + ) + def close_messages_no_wait(self) -> None: self._message_queue.put_nowait(None) - async def close_messages(self, wait: bool = True) -> None: + async def close_messages(self) -> None: """Close message queue, and optionally wait for queue to finish processing.""" if self._closed: return diff --git a/src/textual/reactive.py b/src/textual/reactive.py index 4ef0818ae..df0470751 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -129,7 +129,6 @@ class Reactive(Generic[ReactiveType]): except AttributeError: continue value = await invoke(compute_method) - # value = await compute_method() setattr(obj, compute, value) diff --git a/src/textual/view.py b/src/textual/view.py index e345920a6..c85862bdc 100644 --- a/src/textual/view.py +++ b/src/textual/view.py @@ -106,13 +106,14 @@ class View(Widget): assert isinstance(widget, Widget) display_update = self.layout.update_widget(self.console, widget) + # self.log("UPDATE", widget, display_update) if display_update is not None: self.app.display(display_update) async def handle_layout(self, message: messages.Layout) -> None: + await self.refresh_layout() if self.is_root_view: message.stop() - await self.refresh_layout() self.app.refresh() async def mount(self, *anon_widgets: Widget, **widgets: Widget) -> None: @@ -142,9 +143,7 @@ class View(Widget): return hidden, shown, resized = self.layout.reflow(self, Size(*self.console.size)) - assert self.layout.map is not None - # self.virtual_size = self.layout.map.virtual_size for widget in hidden: widget.post_message_no_wait(events.Hide(self)) diff --git a/src/textual/widgets/_button.py b/src/textual/widgets/_button.py index 3a7fd4c82..770edb197 100644 --- a/src/textual/widgets/_button.py +++ b/src/textual/widgets/_button.py @@ -63,4 +63,5 @@ class Button(Widget): return ButtonRenderable(self.label, style=self.button_style) async def on_click(self, event: events.Click) -> None: + event.prevent_default().stop() await self.emit(ButtonPressed(self))