From ee97553c189a559f56bf32603316a7bfb58257a6 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 19 Aug 2022 10:22:58 +0100 Subject: [PATCH] fix for watchers --- docs/examples/introduction/timers.css | 20 +++++++++------- docs/examples/introduction/timers.py | 6 ++--- src/textual/reactive.py | 11 +++------ src/textual/widget.py | 34 +++++++++++++-------------- 4 files changed, 35 insertions(+), 36 deletions(-) diff --git a/docs/examples/introduction/timers.css b/docs/examples/introduction/timers.css index a5f2295fb..5d6272b7e 100644 --- a/docs/examples/introduction/timers.css +++ b/docs/examples/introduction/timers.css @@ -8,12 +8,24 @@ TimerWidget { transition: background 200ms linear; } +TimerWidget.started { + text-style: bold; + background: $success; + color: $text-success; + border: tall $success-darken-2; +} + + TimeDisplay { content-align: center middle; opacity: 60%; height: 3; } +TimerWidget.started TimeDisplay { + opacity: 100%; +} + Button { width: 16; } @@ -23,14 +35,6 @@ Button { } -TimerWidget.started { - opacity: 100%; - text-style: bold; - background: $success; - color: $text-success; - border: tall $success-darken-2; -} - TimerWidget.started #start { display: none } diff --git a/docs/examples/introduction/timers.py b/docs/examples/introduction/timers.py index 043591935..fc1abe5a0 100644 --- a/docs/examples/introduction/timers.py +++ b/docs/examples/introduction/timers.py @@ -68,15 +68,15 @@ class TimerApp(App): def compose(self) -> ComposeResult: yield Header() yield Footer() - yield Container(TimerWidget(), TimerWidget(), TimerWidget()) + yield Container(TimerWidget(), TimerWidget(), TimerWidget(), id="timers") def action_add_timer(self) -> None: new_timer = TimerWidget() - self.query_one(Container).mount(new_timer) + self.query_one("#timers").mount(new_timer) new_timer.scroll_visible() def action_remove_timer(self) -> None: - timers = self.query("Container TimerWidget") + timers = self.query("#timers TimerWidget") if timers: timers.last().remove() diff --git a/src/textual/reactive.py b/src/textual/reactive.py index 84d6ed990..a5d52e70a 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -4,7 +4,6 @@ from inspect import isawaitable from functools import partial from typing import ( Any, - Awaitable, Callable, Generic, Type, @@ -44,7 +43,6 @@ class Reactive(Generic[ReactiveType]): self._default = default self.layout = layout self.repaint = repaint - self._first = True def __set_name__(self, owner: Type[MessageTarget], name: str) -> None: @@ -68,19 +66,16 @@ class Reactive(Generic[ReactiveType]): return getattr(obj, self.internal_name) def __set__(self, obj: Reactable, value: ReactiveType) -> None: - name = self.name current_value = getattr(obj, self.internal_name, None) validate_function = getattr(obj, f"validate_{name}", None) + first_set = getattr(obj, f"{self.internal_name}__first_set", True) if callable(validate_function): value = validate_function(value) - - if current_value != value or self._first: - - self._first = False + if current_value != value or first_set: + setattr(obj, f"{self.internal_name}__first_set", True) setattr(obj, self.internal_name, value) self.check_watchers(obj, name, current_value) - if self.layout or self.repaint: obj.refresh(repaint=self.repaint, layout=self.layout) diff --git a/src/textual/widget.py b/src/textual/widget.py index 3feb3a827..9d4a2938a 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -1183,16 +1183,16 @@ class Widget(DOMNode): async def broker_event(self, event_name: str, event: events.Event) -> bool: return await self.app.broker_event(event_name, event, default_namespace=self) - async def on_mouse_down(self, event: events.MouseUp) -> None: + async def _on_mouse_down(self, event: events.MouseUp) -> None: await self.broker_event("mouse.down", event) - async def on_mouse_up(self, event: events.MouseUp) -> None: + async def _on_mouse_up(self, event: events.MouseUp) -> None: await self.broker_event("mouse.up", event) - async def on_click(self, event: events.Click) -> None: + async def _on_click(self, event: events.Click) -> None: 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.dispatch_key(event) def _on_mount(self, event: events.Mount) -> None: @@ -1201,23 +1201,23 @@ class Widget(DOMNode): self.mount(*widgets) self.screen.refresh(repaint=False, layout=True) - def on_leave(self, event: events.Leave) -> None: + def _on_leave(self, event: events.Leave) -> None: self.mouse_over = False - def on_enter(self, event: events.Enter) -> None: + def _on_enter(self, event: events.Enter) -> None: self.mouse_over = True - def on_focus(self, event: events.Focus) -> None: + def _on_focus(self, event: events.Focus) -> None: self.emit_no_wait(events.DescendantFocus(self)) self.has_focus = True self.refresh() - def on_blur(self, event: events.Blur) -> None: + def _on_blur(self, event: events.Blur) -> None: self.emit_no_wait(events.DescendantBlur(self)) self.has_focus = False self.refresh() - def on_descendant_focus(self, event: events.DescendantFocus) -> None: + def _on_descendant_focus(self, event: events.DescendantFocus) -> None: self.descendant_has_focus = True if "focus-within" in self.pseudo_classes: sender = event.sender @@ -1226,7 +1226,7 @@ class Widget(DOMNode): if child is sender: break - def on_descendant_blur(self, event: events.DescendantBlur) -> None: + def _on_descendant_blur(self, event: events.DescendantBlur) -> None: self.descendant_has_focus = False if "focus-within" in self.pseudo_classes: sender = event.sender @@ -1235,37 +1235,37 @@ class Widget(DOMNode): if child is sender: break - def on_mouse_scroll_down(self, event) -> None: + def _on_mouse_scroll_down(self, event) -> None: if self.allow_vertical_scroll: if self.scroll_down(animate=False): event.stop() - def on_mouse_scroll_up(self, event) -> None: + def _on_mouse_scroll_up(self, event) -> None: if self.allow_vertical_scroll: if self.scroll_up(animate=False): event.stop() - def on_scroll_to(self, message: ScrollTo) -> None: + def _on_scroll_to(self, message: ScrollTo) -> None: if self.is_scrollable: self.scroll_to(message.x, message.y, animate=message.animate, duration=0.1) message.stop() - def on_scroll_up(self, event: ScrollUp) -> None: + def _on_scroll_up(self, event: ScrollUp) -> None: if self.is_scrollable: self.scroll_page_up() event.stop() - def on_scroll_down(self, event: ScrollDown) -> None: + def _on_scroll_down(self, event: ScrollDown) -> None: if self.is_scrollable: self.scroll_page_down() event.stop() - def on_scroll_left(self, event: ScrollLeft) -> None: + def _on_scroll_left(self, event: ScrollLeft) -> None: if self.is_scrollable: self.scroll_page_left() event.stop() - def on_scroll_right(self, event: ScrollRight) -> None: + def _on_scroll_right(self, event: ScrollRight) -> None: if self.is_scrollable: self.scroll_page_right() event.stop()