From 08f90dc9ce082caf62ebc19b44940f77688bf35a Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 11 May 2022 11:07:41 +0100 Subject: [PATCH] refresh mechanism change --- sandbox/basic.css | 3 +-- src/textual/_compositor.py | 2 +- src/textual/_layout.py | 3 +++ src/textual/app.py | 6 +++--- src/textual/screen.py | 1 - src/textual/widget.py | 31 ++++++++++++++++--------------- src/textual/widgets/_static.py | 16 +++------------- 7 files changed, 27 insertions(+), 35 deletions(-) diff --git a/sandbox/basic.css b/sandbox/basic.css index a2ced4868..3934f521c 100644 --- a/sandbox/basic.css +++ b/sandbox/basic.css @@ -167,7 +167,6 @@ TweetBody { OptionItem { height: 3; background: $primary; - transition: background 100ms linear; border-right: outer $primary-darken-2; border-left: hidden; content-align: center middle; @@ -224,4 +223,4 @@ Success { .horizontal { layout: horizontal -} \ No newline at end of file +} diff --git a/src/textual/_compositor.py b/src/textual/_compositor.py index f0f814d3e..30662cdc6 100644 --- a/src/textual/_compositor.py +++ b/src/textual/_compositor.py @@ -571,7 +571,7 @@ class Compositor: chops_line[cut] = segments if regions: - crop_x, crop_y, crop_x2, crop_y2 = crop.corners + crop_y, crop_y2 = crop.y_extents render_lines = self._assemble_chops(chops[crop_y:crop_y2]) render_spans = [ (y, x1, line_crop(render_lines[y - crop_y], x1, x2)) diff --git a/src/textual/_layout.py b/src/textual/_layout.py index ea459a3e0..6ba50370a 100644 --- a/src/textual/_layout.py +++ b/src/textual/_layout.py @@ -24,6 +24,9 @@ class Layout(ABC): name: ClassVar[str] = "" + def __repr__(self) -> str: + return f"<{self.name}>" + @abstractmethod def arrange( self, parent: Widget, size: Size, scroll: Offset diff --git a/src/textual/app.py b/src/textual/app.py index 458897d80..0c6b89739 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -615,7 +615,6 @@ class App(Generic[ReturnType], DOMNode): is_renderable(renderable) for renderable in renderables ), "Can only call panic with strings or Rich renderables" - self.console.bell() prerendered = [ Segments(self.console.render(renderable, self.console.options)) for renderable in renderables @@ -640,6 +639,7 @@ class App(Generic[ReturnType], DOMNode): def fatal_error(self) -> None: """Exits the app after an unhandled exception.""" + self.console.bell() traceback = Traceback( show_locals=True, width=None, locals_max_length=5, suppress=[rich] ) @@ -943,14 +943,14 @@ class App(Generic[ReturnType], DOMNode): action_target = default_namespace or self action_name = target - log("action", action) + log("", action) await self.dispatch_action(action_target, action_name, params) async def dispatch_action( self, namespace: object, action_name: str, params: Any ) -> None: log( - "dispatch_action", + "", namespace=namespace, action_name=action_name, params=params, diff --git a/src/textual/screen.py b/src/textual/screen.py index 2d4b08ccf..c12853b2f 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -162,7 +162,6 @@ class Screen(Widget): event.stop() async def _on_mouse_move(self, event: events.MouseMove) -> None: - try: if self.app.mouse_captured: widget = self.app.mouse_captured diff --git a/src/textual/widget.py b/src/textual/widget.py index 5dc2df686..2913f62ca 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -83,6 +83,7 @@ class Widget(DOMNode): self._virtual_size = Size(0, 0) self._container_size = Size(0, 0) self._layout_required = False + self._repaint_required = False self._default_layout = VerticalLayout() self._animate: BoundAnimator | None = None self._reactive_watches: dict[str, Callable] = {} @@ -294,6 +295,10 @@ class Widget(DOMNode): self._dirty_regions.clear() self._dirty_regions.append(self.size.region) + def set_clean(self) -> None: + """Set the widget as clean.""" + self._dirty_regions.clear() + def scroll_to( self, x: float | None = None, @@ -313,7 +318,6 @@ class Widget(DOMNode): Returns: bool: True if the scroll position changed, otherwise False. """ - scrolled_x = scrolled_y = False if animate: @@ -343,13 +347,13 @@ class Widget(DOMNode): else: if x is not None: - if x != self.scroll_x: - self.scroll_target_x = self.scroll_x = x - scrolled_x = True + scroll_x = self.scroll_x + self.scroll_target_x = self.scroll_x = x + scrolled_x = scroll_x != self.scroll_x if y is not None: - if y != self.scroll_y: - self.scroll_target_y = self.scroll_y = y - scrolled_y = True + scroll_y = self.scroll_y + self.scroll_target_y = self.scroll_y = y + scrolled_y = scroll_y != self.scroll_y if scrolled_x or scrolled_y: self.refresh(repaint=False, layout=True) @@ -699,6 +703,7 @@ class Widget(DOMNode): self.refresh(layout=True) self.call_later(self.scroll_to, self.scroll_x, self.scroll_y) else: + print("size updated refresh") self.refresh() def _render_lines(self) -> None: @@ -766,6 +771,7 @@ class Widget(DOMNode): self._layout_required = True if repaint: self.set_dirty() + self._repaint_required = True self.check_idle() def render(self) -> RenderableType: @@ -774,13 +780,7 @@ class Widget(DOMNode): Returns: RenderableType: Any renderable """ - - # Default displays a pretty repr in the center of the screen - - if self.is_container: - return "" - - return self.css_identifier_styled + return "" if self.is_container else self.css_identifier_styled async def action(self, action: str, *params) -> None: await self.app.action(action, self) @@ -802,8 +802,9 @@ class Widget(DOMNode): if self.check_layout(): self._reset_check_layout() self.screen.post_message_no_wait(messages.Layout(self)) - elif self._dirty_regions: + elif self._repaint_required: self.emit_no_wait(messages.Update(self, self)) + self._repaint_required = False def focus(self) -> None: """Give input focus to this widget.""" diff --git a/src/textual/widgets/_static.py b/src/textual/widgets/_static.py index 733986e2f..66a299e1a 100644 --- a/src/textual/widgets/_static.py +++ b/src/textual/widgets/_static.py @@ -1,9 +1,6 @@ from __future__ import annotations from rich.console import RenderableType -from rich.padding import Padding, PaddingDimensions -from rich.style import StyleType -from rich.styled import Styled from ..widget import Widget @@ -15,20 +12,13 @@ class Static(Widget): name: str | None = None, id: str | None = None, classes: str | None = None, - style: StyleType = "", - padding: PaddingDimensions = 0, ) -> None: super().__init__(name=name, id=id, classes=classes) self.renderable = renderable - self.style = style - self.padding = padding def render(self) -> RenderableType: - renderable = self.renderable - if self.padding: - renderable = Padding(renderable, self.padding) - return Styled(renderable, self.style) + return self.renderable - async def update(self, renderable: RenderableType) -> None: + def update(self, renderable: RenderableType) -> None: self.renderable = renderable - self.refresh() + self.refresh(layout=True)