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:
Rodrigo Girão Serrão
2023-01-06 18:25:01 +00:00
parent c22cc30e71
commit 94e8b77779

View File

@@ -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)