mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
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'.
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user