diff --git a/src/textual/strip.py b/src/textual/strip.py index d6706cad03..d11f6ee242 100644 --- a/src/textual/strip.py +++ b/src/textual/strip.py @@ -570,3 +570,15 @@ def render(self, console: Console) -> str: ] ) return self._render_cache + + def crop_pad(self, cell_length: int, left: int, right: int, style: Style) -> Strip: + if cell_length != self.cell_length: + strip = self.adjust_cell_length(cell_length, style) + if not (left or right): + return strip + segments = self._segments.copy() + if left: + segments.insert(0, Segment(" " * left, style)) + if right: + segments.append(Segment(" " * right, style)) + return Strip(segments, cell_length + left + right) diff --git a/src/textual/visual.py b/src/textual/visual.py index d13fe00f8c..3fe7f63494 100644 --- a/src/textual/visual.py +++ b/src/textual/visual.py @@ -245,8 +245,6 @@ def to_strips( height: int, widget: Widget, component_classes: list[str] | None = None, - padding: Spacing = Spacing(), - padding_style: RichStyle = RichStyle(), ) -> list[Strip]: styles: Styles if component_classes: @@ -256,24 +254,7 @@ def to_strips( else: styles = widget.styles - strips = visual.render_strips( - width - padding.width, height - padding.height, widget.visual_style, styles - ) - - if padding: - top_padding = ( - [Strip.blank(width, padding_style)] * padding.top if padding.top else [] - ) - bottom_padding = ( - [Strip.blank(width, padding_style)] * padding.bottom - if padding.bottom - else [] - ) - strips = [ - *top_padding, - *Strip.align(strips, padding_style, width, height, "ce"), - *bottom_padding, - ] + strips = visual.render_strips(width, height, widget.visual_style, styles) return strips @@ -351,3 +332,48 @@ def render_strips( ) ] return strips + + +class Padding(Visual): + def __init__(self, visual: Visual, spacing: Spacing): + self._visual = visual + self._spacing = spacing + + def get_optimal_width(self, tab_size: int = 8) -> int: + return self._visual.get_optimal_width(tab_size) + self._spacing.width + + def get_minimal_width(self, tab_size: int = 8) -> int: + return self._visual.get_minimal_width(tab_size) + self._spacing.width + + def get_height(self, width: int) -> int: + return self._visual.get_height(width) + self._spacing.height + + def render_strips( + self, + width: int, + height: int | None, + base_style: Style, + styles: Styles, + ) -> list[Strip]: + padding = self._spacing + top, right, bottom, left = self._spacing + render_width = width - (left + right) + strips = self._visual.render_strips( + render_width, + None if height is None else height - padding.height, + base_style, + styles, + ) + rich_style = base_style.rich_style + if padding: + top_padding = [Strip.blank(width, rich_style)] * top if top else [] + bottom_padding = [Strip.blank(width, rich_style)] * bottom if bottom else [] + strips = [ + *top_padding, + *[ + strip.crop_pad(render_width, left, right, rich_style) + for strip in strips + ], + *bottom_padding, + ] + return strips diff --git a/src/textual/widgets/_option_list.py b/src/textual/widgets/_option_list.py index e63e191701..31e39aed49 100644 --- a/src/textual/widgets/_option_list.py +++ b/src/textual/widgets/_option_list.py @@ -17,7 +17,7 @@ from textual.reactive import reactive from textual.scroll_view import ScrollView from textual.strip import Strip -from textual.visual import Visual, visualize +from textual.visual import Padding, Visual, visualize if TYPE_CHECKING: from typing_extensions import Self, TypeAlias @@ -478,6 +478,10 @@ def _render_option_content( # return strips visual = visualize(self, content) + padding = self.get_component_styles("option-list--option").padding + if padding: + self.notify(str(padding)) + visual = Padding(visual, padding) strips = Visual.to_strips( visual, @@ -485,7 +489,6 @@ def _render_option_content( 2, self, component_classes=[component_class] if component_class else None, - padding=self.get_component_styles("option-list--option").padding, ) # padding = self.get_component_styles("option-list--option").padding