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 itertools import cycle
from .. import events from .. import events
from ..containers import Container
from ..css._error_tools import friendly_list from ..css._error_tools import friendly_list
from ..reactive import Reactive, reactive from ..reactive import Reactive, reactive
from ..widget import Widget, RenderResult from ..widget import Widget, RenderResult
@@ -36,19 +35,10 @@ _LOREM_IPSUM_PLACEHOLDER_TEXT = "Lorem ipsum dolor sit amet, consectetur adipisc
class InvalidPlaceholderVariant(Exception): class InvalidPlaceholderVariant(Exception):
pass """Raised when an invalid Placeholder variant is set."""
class _PlaceholderLabel(Widget): class Placeholder(Widget):
def __init__(self, content, classes) -> None:
super().__init__(classes=classes)
self._content = content
def render(self) -> RenderResult:
return self._content
class Placeholder(Container):
"""A simple placeholder widget to use before you build your custom widgets. """A simple placeholder widget to use before you build your custom widgets.
This placeholder has a couple of variants that show different data. This placeholder has a couple of variants that show different data.
@@ -63,44 +53,24 @@ class Placeholder(Container):
DEFAULT_CSS = """ DEFAULT_CSS = """
Placeholder { Placeholder {
align: center middle; content-align: center middle;
overflow: hidden; overflow: hidden;
color: $text;
} }
Placeholder.-text { Placeholder.-text {
padding: 1; 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. # Consecutive placeholders get assigned consecutive colors.
_COLORS = cycle(_PLACEHOLDER_BACKGROUND_COLORS) _COLORS = cycle(_PLACEHOLDER_BACKGROUND_COLORS)
_SIZE_RENDER_TEMPLATE = "[b]{} x {}[/b]" _SIZE_RENDER_TEMPLATE = "[b]{} x {}[/b]"
variant: Reactive[PlaceholderVariant] = reactive("default") variant: Reactive[PlaceholderVariant] = reactive("default")
_renderables: dict[PlaceholderVariant, RenderResult]
@classmethod @classmethod
def reset_color_cycle(cls) -> None: def reset_color_cycle(cls) -> None:
"""Reset the placeholder background color cycle.""" """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 classes (str | None, optional): A space separated string with the CSS classes
of the placeholder, if any. Defaults to None. of the placeholder, if any. Defaults to None.
""" """
# Create and cache labels for all the variants. # Create and cache renderables for all the variants.
self._default_label = _PlaceholderLabel( self._renderables = {
label if label else f"#{id}" if id else "Placeholder", "default": label if label else f"#{id}" if id else "Placeholder",
"-default", "size": "",
) "text": "\n\n".join(_LOREM_IPSUM_PLACEHOLDER_TEXT for _ in range(5)),
self._size_label = _PlaceholderLabel( }
"",
"-size", super().__init__(name=name, id=id, classes=classes)
)
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,
)
self.styles.background = f"{next(Placeholder._COLORS)} 50%" self.styles.background = f"{next(Placeholder._COLORS)} 50%"
@@ -158,6 +115,9 @@ class Placeholder(Container):
while next(self._variants_cycle) != self.variant: while next(self._variants_cycle) != self.variant:
pass pass
def render(self) -> RenderResult:
return self._renderables[self.variant]
def cycle_variant(self) -> None: def cycle_variant(self) -> None:
"""Get the next variant in the cycle.""" """Get the next variant in the cycle."""
self.variant = next(self._variants_cycle) self.variant = next(self._variants_cycle)
@@ -183,6 +143,6 @@ class Placeholder(Container):
def on_resize(self, event: events.Resize) -> None: def on_resize(self, event: events.Resize) -> None:
"""Update the placeholder "size" variant with the new placeholder size.""" """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": if self.variant == "size":
self._size_label.refresh(layout=True) self.refresh(layout=True)