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)