added style attributes to render

This commit is contained in:
Will McGugan
2021-08-17 21:28:47 +01:00
parent 730192a1ad
commit fb141ed6c9
4 changed files with 68 additions and 12 deletions

View File

@@ -116,6 +116,7 @@ class Calculator(GridView):
# The calculator display # The calculator display
self.numbers = Numbers() self.numbers = Numbers()
self.numbers.style_border = "bold"
def make_button(text: str, style: str) -> Button: def make_button(text: str, style: str) -> Button:
"""Create a button with the given Figlet label.""" """Create a button with the given Figlet label."""

View File

@@ -156,11 +156,11 @@ class Region(NamedTuple):
"""Create a region from origin and size. """Create a region from origin and size.
Args: Args:
origin (Point): [description] origin (Point): Origin (top left point)
size (tuple[int, int]): [description] size (tuple[int, int]): Dimensions of region.
Returns: Returns:
Region: [description] Region: A region instance.
""" """
x, y = origin x, y = origin
width, height = size width, height = size
@@ -171,10 +171,25 @@ class Region(NamedTuple):
@property @property
def x_extents(self) -> tuple[int, int]: def x_extents(self) -> tuple[int, int]:
"""Get the starting and ending x coord.
The end value is non inclusive.
Returns:
tuple[int, int]: [description]
"""
return (self.x, self.x + self.width) return (self.x, self.x + self.width)
@property @property
def y_extents(self) -> tuple[int, int]: def y_extents(self) -> tuple[int, int]:
"""Get the starting and ending x coord.
The end value is non inclusive.
Returns:
tuple[int, int]: [description]
"""
return (self.x, self.x + self.width)
return (self.y, self.y + self.height) return (self.y, self.y + self.height)
@property @property
@@ -212,11 +227,11 @@ class Region(NamedTuple):
@property @property
def x_range(self) -> range: def x_range(self) -> range:
return range(self.x, self.x_max) return range(self.x, self.x + self.width)
@property @property
def y_range(self) -> range: def y_range(self) -> range:
return range(self.y, self.y_max) return range(self.y, self.y + self.height)
def __add__(self, other: Any) -> Region: def __add__(self, other: Any) -> Region:
if isinstance(other, tuple): if isinstance(other, tuple):

View File

@@ -12,12 +12,15 @@ from typing import (
cast, cast,
) )
import rich.repr import rich.repr
from rich import box
from rich.align import Align from rich.align import Align
from rich.console import Console, RenderableType from rich.console import Console, RenderableType
from rich.panel import Panel from rich.panel import Panel
from rich.padding import Padding, PaddingDimensions
from rich.pretty import Pretty from rich.pretty import Pretty
from rich.segment import Segment
from rich.style import Style from rich.style import Style
from rich.styled import Styled
from rich.text import TextType
from . import events from . import events
from ._animator import BoundAnimator from ._animator import BoundAnimator
@@ -72,6 +75,25 @@ class Widget(MessagePump):
layout_offset_x: Reactive[float] = Reactive(0.0, layout=True) layout_offset_x: Reactive[float] = Reactive(0.0, layout=True)
layout_offset_y: Reactive[float] = Reactive(0.0, layout=True) layout_offset_y: Reactive[float] = Reactive(0.0, layout=True)
style: Reactive[str | None] = Reactive(None)
style_padding: Reactive[PaddingDimensions | None] = Reactive(None, layout=True)
style_margin: Reactive[PaddingDimensions | None] = Reactive(None, layout=True)
style_border: Reactive[str] = Reactive("none", layout=True)
style_border_style: Reactive[str] = Reactive("")
style_border_title: Reactive[TextType] = Reactive("")
BOX_MAP = {"normal": box.SQUARE, "round": box.ROUNDED, "bold": box.HEAVY}
def validate_style_padding(
self, padding: PaddingDimensions
) -> tuple[int, int, int, int]:
return Padding.unpack(padding)
def validate_style_margin(
self, padding: PaddingDimensions
) -> tuple[int, int, int, int]:
return Padding.unpack(padding)
def validate_layout_offset_x(self, value) -> int: def validate_layout_offset_x(self, value) -> int:
return int(value) return int(value)
@@ -86,11 +108,28 @@ class Widget(MessagePump):
yield "name", self.name yield "name", self.name
def __rich__(self) -> RenderableType: def __rich__(self) -> RenderableType:
return self.render() renderable = self.render_styled()
return renderable
def watch(self, attribute_name, callback: Callable[[Any], Awaitable[None]]) -> None: def watch(self, attribute_name, callback: Callable[[Any], Awaitable[None]]) -> None:
watch(self, attribute_name, callback) watch(self, attribute_name, callback)
def render_styled(self) -> RenderableType:
renderable = self.render()
if self.style_padding is not None:
renderable = Padding(renderable, self.style_padding)
if self.style_border in self.BOX_MAP:
renderable = Panel(
renderable,
box=self.BOX_MAP.get(self.style_border) or box.SQUARE,
style=self.style_border_style,
)
if self.style_margin is not None:
renderable = Padding(renderable, self.style_margin)
if self.style:
renderable = Styled(renderable, self.style)
return renderable
@property @property
def size(self) -> Size: def size(self) -> Size:
return self._size return self._size
@@ -126,7 +165,7 @@ class Widget(MessagePump):
def render_lines(self) -> RenderCache: def render_lines(self) -> RenderCache:
width, height = self.size width, height = self.size
renderable = self.render() renderable = self.render_styled()
options = self.console.options.update_dimensions(width, height) options = self.console.options.update_dimensions(width, height)
lines = self.console.render_lines(renderable, options) lines = self.console.render_lines(renderable, options)
self.render_cache = RenderCache(self.size, lines) self.render_cache = RenderCache(self.size, lines)
@@ -134,7 +173,7 @@ class Widget(MessagePump):
def render_lines_free(self, width: int) -> RenderCache: def render_lines_free(self, width: int) -> RenderCache:
renderable = self.render() renderable = self.render_styled()
options = self.console.options.update(width=width, height=None) options = self.console.options.update(width=width, height=None)

View File

@@ -51,15 +51,16 @@ class Button(Widget):
name: str | None = None, name: str | None = None,
style: StyleType = "white on dark_blue", style: StyleType = "white on dark_blue",
): ):
self.name = name or str(label)
self.style = style
super().__init__(name=name) super().__init__(name=name)
self.name = name or str(label)
self.button_style = style
self.label = label self.label = label
label: Reactive[RenderableType] = Reactive("") label: Reactive[RenderableType] = Reactive("")
def render(self) -> RenderableType: def render(self) -> RenderableType:
return ButtonRenderable(self.label, style=self.style) return ButtonRenderable(self.label, style=self.button_style)
async def on_click(self, event: events.Click) -> None: async def on_click(self, event: events.Click) -> None:
await self.emit(ButtonPressed(self)) await self.emit(ButtonPressed(self))