From c85e428228be8f82a93814bc48457a4f456d90f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 18 May 2023 16:24:07 +0100 Subject: [PATCH 1/2] Fix placeholder color cycling. --- CHANGELOG.md | 5 +++++ src/textual/widgets/_placeholder.py | 20 ++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42bf44a47..98a555d10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## Unreleased + +### Changed + +- `Placeholder` now sets its color cycle per app https://github.com/Textualize/textual/issues/2590 ## [0.25.0] - 2023-05-17 diff --git a/src/textual/widgets/_placeholder.py b/src/textual/widgets/_placeholder.py index fb0858aaf..a6ac37302 100644 --- a/src/textual/widgets/_placeholder.py +++ b/src/textual/widgets/_placeholder.py @@ -3,10 +3,14 @@ from __future__ import annotations from itertools import cycle +from typing import Iterator +from weakref import WeakKeyDictionary from rich.console import RenderableType from typing_extensions import Literal, Self +from textual.app import App + from .. import events from ..css._error_tools import friendly_list from ..reactive import Reactive, reactive @@ -72,18 +76,13 @@ class Placeholder(Widget): """ # Consecutive placeholders get assigned consecutive colors. - _COLORS = cycle(_PLACEHOLDER_BACKGROUND_COLORS) + _COLORS: WeakKeyDictionary[App, Iterator[str]] = WeakKeyDictionary() _SIZE_RENDER_TEMPLATE = "[b]{} x {}[/b]" variant: Reactive[PlaceholderVariant] = reactive[PlaceholderVariant]("default") _renderables: dict[PlaceholderVariant, str] - @classmethod - def reset_color_cycle(cls) -> None: - """Reset the placeholder background color cycle.""" - cls._COLORS = cycle(_PLACEHOLDER_BACKGROUND_COLORS) - def __init__( self, label: str | None = None, @@ -113,8 +112,6 @@ class Placeholder(Widget): super().__init__(name=name, id=id, classes=classes) - self.styles.background = f"{next(Placeholder._COLORS)} 50%" - self.variant = self.validate_variant(variant) """The current variant of the placeholder.""" @@ -123,6 +120,13 @@ class Placeholder(Widget): while next(self._variants_cycle) != self.variant: pass + def on_mount(self) -> None: + """Set the color for this placeholder.""" + colors = Placeholder._COLORS.setdefault( + self.app, cycle(_PLACEHOLDER_BACKGROUND_COLORS) + ) + self.styles.background = f"{next(colors)} 50%" + def render(self) -> RenderableType: """Render the placeholder. From 6523fbaff1a1e239691b20f196f0e4f18afeae9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Thu, 18 May 2023 16:26:24 +0100 Subject: [PATCH 2/2] Fix tests. --- CHANGELOG.md | 4 + docs/examples/styles/width_comparison.py | 8 +- .../__snapshots__/test_snapshots.ambr | 128 +++++++++--------- tests/snapshot_tests/test_snapshots.py | 2 - 4 files changed, 73 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98a555d10..418606fff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `Placeholder` now sets its color cycle per app https://github.com/Textualize/textual/issues/2590 +### Removed + +- `Placeholder.reset_color_cycle` + ## [0.25.0] - 2023-05-17 ### Changed diff --git a/docs/examples/styles/width_comparison.py b/docs/examples/styles/width_comparison.py index 2971425b6..f801bde4a 100644 --- a/docs/examples/styles/width_comparison.py +++ b/docs/examples/styles/width_comparison.py @@ -1,6 +1,6 @@ from textual.app import App from textual.containers import Horizontal -from textual.widgets import Placeholder, Label, Static +from textual.widgets import Label, Placeholder, Static class Ruler(Static): @@ -9,7 +9,7 @@ class Ruler(Static): yield Label(ruler_text) -class HeightComparisonApp(App): +class WidthComparisonApp(App): def compose(self): yield Horizontal( Placeholder(id="cells"), # (1)! @@ -25,4 +25,6 @@ class HeightComparisonApp(App): yield Ruler() -app = HeightComparisonApp(css_path="width_comparison.css") +app = WidthComparisonApp(css_path="width_comparison.css") +if __name__ == "__main__": + app.run() diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr index c0e2e96b9..e39be06d6 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -12292,141 +12292,141 @@ font-weight: 700; } - .terminal-1938916138-matrix { + .terminal-4051010257-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1938916138-title { + .terminal-4051010257-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1938916138-r1 { fill: #c5c8c6 } - .terminal-1938916138-r2 { fill: #e8e0e7 } - .terminal-1938916138-r3 { fill: #eae3e5 } - .terminal-1938916138-r4 { fill: #ede6e6 } - .terminal-1938916138-r5 { fill: #efe9e4 } - .terminal-1938916138-r6 { fill: #efeedf } - .terminal-1938916138-r7 { fill: #e9eee5 } - .terminal-1938916138-r8 { fill: #e4eee8 } - .terminal-1938916138-r9 { fill: #e2edeb } - .terminal-1938916138-r10 { fill: #dfebed } - .terminal-1938916138-r11 { fill: #ddedf9 } + .terminal-4051010257-r1 { fill: #c5c8c6 } + .terminal-4051010257-r2 { fill: #e8e0e7 } + .terminal-4051010257-r3 { fill: #eae3e5 } + .terminal-4051010257-r4 { fill: #ede6e6 } + .terminal-4051010257-r5 { fill: #efe9e4 } + .terminal-4051010257-r6 { fill: #efeedf } + .terminal-4051010257-r7 { fill: #e9eee5 } + .terminal-4051010257-r8 { fill: #e4eee8 } + .terminal-4051010257-r9 { fill: #e2edeb } + .terminal-4051010257-r10 { fill: #dfebed } + .terminal-4051010257-r11 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - HeightComparisonApp + WidthComparisonApp - + - - - - - - - - - - - - - #cells#percent#w#h#vw#vh#auto#fr1#fr3 - - - - - - - - - - - - ····•····•····•····•····•····•····•····•····•····•····•····•····•····•····•····• + + + + + + + + + + + + + #cells#percent#w#h#vw#vh#auto#fr1#fr3 + + + + + + + + + + + + ····•····•····•····•····•····•····•····•····•····•····•····•····•····•····•····• diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index bdedbced3..874f096d9 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -91,7 +91,6 @@ def test_buttons_render(snap_compare): def test_placeholder_render(snap_compare): # Testing the rendering of the multiple placeholder variants and labels. - Placeholder.reset_color_cycle() assert snap_compare(WIDGET_EXAMPLES_DIR / "placeholder.py") @@ -261,7 +260,6 @@ PATHS = [ @pytest.mark.parametrize("file_name", PATHS) def test_css_property(file_name, snap_compare): path_to_app = STYLES_EXAMPLES_DIR / file_name - Placeholder.reset_color_cycle() assert snap_compare(path_to_app)