From 0db3fa6701ec1239aa4b08310f95cdcb0a52b9da 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: Fri, 6 Jan 2023 18:25:01 +0000
Subject: [PATCH 1/3] Simplify Placeholder implementation.
Instead of creating a private widget that is the only child of 'Placeholder', that was inheriting from 'Container', simplify everything. 'Placeholder' now inherits directly from 'Widget' and it saves a dictionary with its renderables per variant, instead of deferring that to the child '_PlaceholderLabel'.
---
src/textual/widgets/_placeholder.py | 80 ++++++++---------------------
1 file changed, 20 insertions(+), 60 deletions(-)
diff --git a/src/textual/widgets/_placeholder.py b/src/textual/widgets/_placeholder.py
index eabe762c9..137a0fd1c 100644
--- a/src/textual/widgets/_placeholder.py
+++ b/src/textual/widgets/_placeholder.py
@@ -3,7 +3,6 @@ from __future__ import annotations
from itertools import cycle
from .. import events
-from ..containers import Container
from ..css._error_tools import friendly_list
from ..reactive import Reactive, reactive
from ..widget import Widget, RenderResult
@@ -36,19 +35,10 @@ _LOREM_IPSUM_PLACEHOLDER_TEXT = "Lorem ipsum dolor sit amet, consectetur adipisc
class InvalidPlaceholderVariant(Exception):
- pass
+ """Raised when an invalid Placeholder variant is set."""
-class _PlaceholderLabel(Widget):
- def __init__(self, content, classes) -> None:
- super().__init__(classes=classes)
- self._content = content
-
- def render(self) -> RenderResult:
- return self._content
-
-
-class Placeholder(Container):
+class Placeholder(Widget):
"""A simple placeholder widget to use before you build your custom widgets.
This placeholder has a couple of variants that show different data.
@@ -63,44 +53,24 @@ class Placeholder(Container):
DEFAULT_CSS = """
Placeholder {
- align: center middle;
+ content-align: center middle;
overflow: hidden;
+ color: $text;
}
Placeholder.-text {
padding: 1;
}
-
- _PlaceholderLabel {
- height: auto;
- color: $text;
- }
-
- Placeholder > _PlaceholderLabel {
- content-align: center middle;
- }
-
- Placeholder.-default > _PlaceholderLabel.-size,
- Placeholder.-default > _PlaceholderLabel.-text,
- Placeholder.-size > _PlaceholderLabel.-default,
- Placeholder.-size > _PlaceholderLabel.-text,
- Placeholder.-text > _PlaceholderLabel.-default,
- Placeholder.-text > _PlaceholderLabel.-size {
- display: none;
- }
-
- Placeholder.-default > _PlaceholderLabel.-default,
- Placeholder.-size > _PlaceholderLabel.-size,
- Placeholder.-text > _PlaceholderLabel.-text {
- display: block;
- }
"""
+
# Consecutive placeholders get assigned consecutive colors.
_COLORS = cycle(_PLACEHOLDER_BACKGROUND_COLORS)
_SIZE_RENDER_TEMPLATE = "[b]{} x {}[/b]"
variant: Reactive[PlaceholderVariant] = reactive("default")
+ _renderables: dict[PlaceholderVariant, RenderResult]
+
@classmethod
def reset_color_cycle(cls) -> None:
"""Reset the placeholder background color cycle."""
@@ -128,27 +98,14 @@ class Placeholder(Container):
classes (str | None, optional): A space separated string with the CSS classes
of the placeholder, if any. Defaults to None.
"""
- # Create and cache labels for all the variants.
- self._default_label = _PlaceholderLabel(
- label if label else f"#{id}" if id else "Placeholder",
- "-default",
- )
- self._size_label = _PlaceholderLabel(
- "",
- "-size",
- )
- self._text_label = _PlaceholderLabel(
- "\n\n".join(_LOREM_IPSUM_PLACEHOLDER_TEXT for _ in range(5)),
- "-text",
- )
- super().__init__(
- self._default_label,
- self._size_label,
- self._text_label,
- name=name,
- id=id,
- classes=classes,
- )
+ # Create and cache renderables for all the variants.
+ self._renderables = {
+ "default": label if label else f"#{id}" if id else "Placeholder",
+ "size": "",
+ "text": "\n\n".join(_LOREM_IPSUM_PLACEHOLDER_TEXT for _ in range(5)),
+ }
+
+ super().__init__(name=name, id=id, classes=classes)
self.styles.background = f"{next(Placeholder._COLORS)} 50%"
@@ -158,6 +115,9 @@ class Placeholder(Container):
while next(self._variants_cycle) != self.variant:
pass
+ def render(self) -> RenderResult:
+ return self._renderables[self.variant]
+
def cycle_variant(self) -> None:
"""Get the next variant in the cycle."""
self.variant = next(self._variants_cycle)
@@ -183,6 +143,6 @@ class Placeholder(Container):
def on_resize(self, event: events.Resize) -> None:
"""Update the placeholder "size" variant with the new placeholder size."""
- self._size_label._content = self._SIZE_RENDER_TEMPLATE.format(*self.size)
+ self._renderables["size"] = self._SIZE_RENDER_TEMPLATE.format(*self.size)
if self.variant == "size":
- self._size_label.refresh(layout=True)
+ self.refresh(layout=True)
From d08699ff503551ef4a60a22a24df024245810e02 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: Fri, 6 Jan 2023 18:30:39 +0000
Subject: [PATCH 2/3] Update placeholder snapshot test.
Although there was no visual difference in the output, the snapshot tool was complaining because there are now less things to draw on the screen, thus the snapshots looked different. Hence, the placeholder snapshot needed to be updated.
---
.../__snapshots__/test_snapshots.ambr | 135 +++++++++---------
1 file changed, 66 insertions(+), 69 deletions(-)
diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr
index 4a9464a81..d920e8d87 100644
--- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr
+++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr
@@ -7800,145 +7800,142 @@
font-weight: 700;
}
- .terminal-2023815619-matrix {
+ .terminal-1570661136-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
- .terminal-2023815619-title {
+ .terminal-1570661136-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
- .terminal-2023815619-r1 { fill: #e8e0e7 }
- .terminal-2023815619-r2 { fill: #c5c8c6 }
- .terminal-2023815619-r3 { fill: #eae3e5 }
- .terminal-2023815619-r4 { fill: #ede6e6 }
- .terminal-2023815619-r5 { fill: #efe9e4 }
- .terminal-2023815619-r6 { fill: #efeedf }
- .terminal-2023815619-r7 { fill: #e9eee5 }
- .terminal-2023815619-r8 { fill: #e4eee8 }
- .terminal-2023815619-r9 { fill: #dfebed }
- .terminal-2023815619-r10 { fill: #e2edeb }
- .terminal-2023815619-r11 { fill: #e4eee8;font-weight: bold }
- .terminal-2023815619-r12 { fill: #dfebed;font-weight: bold }
- .terminal-2023815619-r13 { fill: #e3e6eb }
- .terminal-2023815619-r14 { fill: #dfe9ed }
- .terminal-2023815619-r15 { fill: #e3e6eb;font-weight: bold }
- .terminal-2023815619-r16 { fill: #e6e3e9 }
+ .terminal-1570661136-r1 { fill: #c5c8c6 }
+ .terminal-1570661136-r2 { fill: #eae3e5 }
+ .terminal-1570661136-r3 { fill: #e8e0e7 }
+ .terminal-1570661136-r4 { fill: #efe9e4 }
+ .terminal-1570661136-r5 { fill: #ede6e6 }
+ .terminal-1570661136-r6 { fill: #efeedf }
+ .terminal-1570661136-r7 { fill: #e9eee5 }
+ .terminal-1570661136-r8 { fill: #e2edeb }
+ .terminal-1570661136-r9 { fill: #e4eee8;font-weight: bold }
+ .terminal-1570661136-r10 { fill: #dfebed;font-weight: bold }
+ .terminal-1570661136-r11 { fill: #dfe9ed }
+ .terminal-1570661136-r12 { fill: #e3e6eb;font-weight: bold }
+ .terminal-1570661136-r13 { fill: #e6e3e9 }
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
- PlaceholderApp
+ PlaceholderApp
-
-
-
-
- Placeholder p2 here!
- This is a custom label for p1.
- #p4
- #p3#p5Placeholde
- r
-
- Lorem ipsum dolor sit
- 26 x 6amet, consectetur 27 x 6
- adipiscing elit. Etiam
- feugiat ac elit sit amet
-
-
- Lorem ipsum dolor sit amet,
- consectetur adipiscing elit. Etiam 40 x 6
- feugiat ac elit sit amet accumsan.
- Suspendisse bibendum nec libero quis
- gravida. Phasellus id eleifend ligula.
- Nullam imperdiet sem tellus, sed
- vehicula nisl faucibus sit amet. Lorem ipsum dolor sit amet,
- Praesent iaculis tempor ultricies. Sedconsectetur adipiscing elit. Etiam
- lacinia, tellus id rutrum lacinia, feugiat ac elit sit amet accumsan.
- sapien sapien congue mauris, sit amet Suspendisse bibendum nec libero quis
+
+
+
+
+ Placeholder p2 here!
+ This is a custom label for p1.
+ #p4
+ #p3#p5Placeholde
+ r
+
+ Lorem ipsum dolor sit
+ 26 x 6amet, consectetur 27 x 6
+ adipiscing elit. Etiam
+ feugiat ac elit sit amet
+
+
+ Lorem ipsum dolor sit amet,
+ consectetur adipiscing elit. Etiam 40 x 6
+ feugiat ac elit sit amet accumsan.
+ Suspendisse bibendum nec libero quis
+ gravida. Phasellus id eleifend ligula.
+ Nullam imperdiet sem tellus, sed
+ vehicula nisl faucibus sit amet. Lorem ipsum dolor sit amet,
+ Praesent iaculis tempor ultricies. Sedconsectetur adipiscing elit. Etiam
+ lacinia, tellus id rutrum lacinia, feugiat ac elit sit amet accumsan.
+ sapien sapien congue mauris, sit amet Suspendisse bibendum nec libero quis
From 93453af00ed12acf028a3d59511723936ed42a5d 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: Fri, 6 Jan 2023 18:31:34 +0000
Subject: [PATCH 3/3] Update changelog.
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6eed95593..8da8e3b9e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
- The styles `scrollbar-background-active` and `scrollbar-color-hover` are no longer ignored https://github.com/Textualize/textual/pull/1480
+- The widget `Placeholder` can now have its width set to `auto` https://github.com/Textualize/textual/pull/1508
## [0.9.1] - 2022-12-30