mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
new border renderable includes outline
This commit is contained in:
@@ -14,25 +14,55 @@ class Border:
|
||||
self,
|
||||
renderable: RenderableType,
|
||||
edge_styles: tuple[EdgeStyle, EdgeStyle, EdgeStyle, EdgeStyle],
|
||||
outline: bool = False,
|
||||
):
|
||||
self.renderable = renderable
|
||||
self.edge_styles = edge_styles
|
||||
self.outline = outline
|
||||
|
||||
@property
|
||||
def sides(self) -> tuple[str, str, str, str]:
|
||||
(top, _), (right, _), (bottom, _), (left, _) = self.edge_styles
|
||||
return (top or "none", right or "none", bottom or "none", left or "none")
|
||||
(
|
||||
(top, top_style),
|
||||
(right, right_style),
|
||||
(bottom, bottom_style),
|
||||
(left, left_style),
|
||||
) = edge_styles
|
||||
self._sides = (top or "none", right or "none", bottom or "none", left or "none")
|
||||
self._styles = (top_style, right_style, bottom_style, left_style)
|
||||
|
||||
@property
|
||||
def styles(self) -> tuple[Style, Style, Style, Style]:
|
||||
(_, top), (_, right), (_, left), (_, bottom) = self.edge_styles
|
||||
return (top, right, left, bottom)
|
||||
def _crop_renderable(self, lines: list[list[Segment]], width: int) -> None:
|
||||
"""Crops a renderable in place.
|
||||
|
||||
Args:
|
||||
lines (list[list[Segment]]): Segment lines.
|
||||
width (int): Desired width.
|
||||
"""
|
||||
top, right, bottom, left = self._sides
|
||||
has_left = left != "none"
|
||||
has_right = right != "none"
|
||||
has_top = top != "none"
|
||||
has_bottom = bottom != "none"
|
||||
|
||||
if has_top:
|
||||
lines.pop(0)
|
||||
if has_bottom:
|
||||
lines.pop(-1)
|
||||
|
||||
divide = Segment.divide
|
||||
if has_left and has_right:
|
||||
for line in lines:
|
||||
_, line[:] = divide(line, [1, width - 1])
|
||||
elif has_left:
|
||||
for line in lines:
|
||||
_, line[:] = divide(line, [1, width])
|
||||
elif has_right:
|
||||
for line in lines:
|
||||
line[:], _ = divide(line, [width - 1, width])
|
||||
|
||||
def __rich_console__(
|
||||
self, console: "Console", options: "ConsoleOptions"
|
||||
) -> "RenderResult":
|
||||
top, right, bottom, left = self.sides
|
||||
top_style, right_style, bottom_style, left_style = self.styles
|
||||
top, right, bottom, left = self._sides
|
||||
top_style, right_style, bottom_style, left_style = self._styles
|
||||
BOX = BOX_STYLES
|
||||
|
||||
has_left = left != "none"
|
||||
@@ -41,6 +71,9 @@ class Border:
|
||||
has_bottom = bottom != "none"
|
||||
|
||||
width = options.max_width - has_left - has_right
|
||||
if self.outline:
|
||||
render_options = options
|
||||
else:
|
||||
if options.height is None:
|
||||
render_options = options.update_width(width)
|
||||
else:
|
||||
@@ -48,6 +81,8 @@ class Border:
|
||||
render_options = options.update_dimensions(width, height)
|
||||
|
||||
lines = console.render_lines(self.renderable, render_options)
|
||||
if self.outline:
|
||||
self._crop_renderable(lines, options.max_width)
|
||||
|
||||
_Segment = Segment
|
||||
new_line = _Segment.line()
|
||||
@@ -63,13 +98,12 @@ class Border:
|
||||
box_left = BOX[left][1][0]
|
||||
box_right = BOX[right][1][2]
|
||||
left_segment = _Segment(box_left, left_style)
|
||||
right_segment = _Segment(box_right, right_style)
|
||||
right_segment = _Segment(box_right + "\n", right_style)
|
||||
if has_left and has_right:
|
||||
for line in lines:
|
||||
yield left_segment
|
||||
yield from line
|
||||
yield right_segment
|
||||
yield new_line
|
||||
elif has_left:
|
||||
for line in lines:
|
||||
yield left_segment
|
||||
@@ -79,7 +113,6 @@ class Border:
|
||||
for line in lines:
|
||||
yield from line
|
||||
yield right_segment
|
||||
yield new_line
|
||||
else:
|
||||
for line in lines:
|
||||
yield from line
|
||||
@@ -100,14 +133,18 @@ if __name__ == "__main__":
|
||||
from rich.text import Text
|
||||
|
||||
text = Text("Textual " * 40, style="dim")
|
||||
print(
|
||||
Border(
|
||||
border = Border(
|
||||
text,
|
||||
(
|
||||
("outer", Style.parse("green on red")),
|
||||
("none", Style.parse("green")),
|
||||
("double", Style.parse("green")),
|
||||
("double", Style.parse("green")),
|
||||
("outer", Style.parse("green")),
|
||||
("outer", Style.parse("green")),
|
||||
("outer", Style.parse("green")),
|
||||
("outer", Style.parse("green")),
|
||||
),
|
||||
)
|
||||
)
|
||||
print(text)
|
||||
print()
|
||||
print(border)
|
||||
print()
|
||||
border.outline = True
|
||||
print(border)
|
||||
|
||||
Reference in New Issue
Block a user