mirror of
https://github.com/Textualize/rich.git
synced 2025-07-07 21:04:58 +00:00
fix for text in panel title
This commit is contained in:
parent
0099f505c3
commit
066c024be2
4 changed files with 94 additions and 10 deletions
|
@ -2,11 +2,12 @@ from typing import TYPE_CHECKING, Optional
|
|||
|
||||
from .align import AlignMethod
|
||||
from .box import ROUNDED, Box
|
||||
from .cells import cell_len
|
||||
from .jupyter import JupyterMixin
|
||||
from .measure import Measurement, measure_renderables
|
||||
from .padding import Padding, PaddingDimensions
|
||||
from .segment import Segment
|
||||
from .style import StyleType
|
||||
from .style import Style, StyleType
|
||||
from .text import Text, TextType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -149,9 +150,53 @@ class Panel(JupyterMixin):
|
|||
safe_box: bool = console.safe_box if self.safe_box is None else self.safe_box
|
||||
box = self.box.substitute(options, safe=safe_box)
|
||||
|
||||
def align_text(
|
||||
text: Text, width: int, align: str, character: str, style: Style
|
||||
) -> Text:
|
||||
"""Gets new aligned text.
|
||||
|
||||
Args:
|
||||
text (Text): Title or subtitle text.
|
||||
width (int): Desired width.
|
||||
align (str): Alignment.
|
||||
character (str): Character for alignment.
|
||||
style (Style): Border style
|
||||
|
||||
Returns:
|
||||
Text: New text instance
|
||||
"""
|
||||
text = text.copy()
|
||||
text.truncate(width)
|
||||
excess_space = width - cell_len(text.plain)
|
||||
if excess_space:
|
||||
if align == "left":
|
||||
return Text.assemble(
|
||||
text,
|
||||
(character * excess_space, style),
|
||||
no_wrap=True,
|
||||
end="",
|
||||
)
|
||||
elif align == "center":
|
||||
left = excess_space // 2
|
||||
return Text.assemble(
|
||||
(character * left, style),
|
||||
text,
|
||||
(character * (excess_space - left), style),
|
||||
no_wrap=True,
|
||||
end="",
|
||||
)
|
||||
else:
|
||||
return Text.assemble(
|
||||
(character * excess_space, style),
|
||||
text,
|
||||
no_wrap=True,
|
||||
end="",
|
||||
)
|
||||
return text
|
||||
|
||||
title_text = self._title
|
||||
if title_text is not None:
|
||||
title_text.style = border_style
|
||||
title_text.stylize_before(border_style)
|
||||
|
||||
child_width = (
|
||||
width - 2
|
||||
|
@ -180,7 +225,14 @@ class Panel(JupyterMixin):
|
|||
if title_text is None or width <= 4:
|
||||
yield Segment(box.get_top([width - 2]), border_style)
|
||||
else:
|
||||
title_text.align(self.title_align, width - 4, character=box.top)
|
||||
# title_text.align(self.title_align, width - 4, character=box.top)
|
||||
title_text = align_text(
|
||||
title_text,
|
||||
width - 4,
|
||||
self.title_align,
|
||||
box.top,
|
||||
border_style,
|
||||
)
|
||||
yield Segment(box.top_left + box.top, border_style)
|
||||
yield from console.render(title_text, child_options.update_width(width - 4))
|
||||
yield Segment(box.top + box.top_right, border_style)
|
||||
|
@ -194,12 +246,19 @@ class Panel(JupyterMixin):
|
|||
|
||||
subtitle_text = self._subtitle
|
||||
if subtitle_text is not None:
|
||||
subtitle_text.style = border_style
|
||||
subtitle_text.stylize_before(border_style)
|
||||
|
||||
if subtitle_text is None or width <= 4:
|
||||
yield Segment(box.get_bottom([width - 2]), border_style)
|
||||
else:
|
||||
subtitle_text.align(self.subtitle_align, width - 4, character=box.bottom)
|
||||
# subtitle_text.align(self.subtitle_align, width - 4, character=box.bottom)
|
||||
subtitle_text = align_text(
|
||||
subtitle_text,
|
||||
width - 4,
|
||||
self.subtitle_align,
|
||||
box.bottom,
|
||||
border_style,
|
||||
)
|
||||
yield Segment(box.bottom_left + box.bottom, border_style)
|
||||
yield from console.render(
|
||||
subtitle_text, child_options.update_width(width - 4)
|
||||
|
|
27
rich/text.py
27
rich/text.py
|
@ -450,7 +450,6 @@ class Text(JupyterMixin):
|
|||
style (Union[str, Style]): Style instance or style definition to apply.
|
||||
start (int): Start offset (negative indexing is supported). Defaults to 0.
|
||||
end (Optional[int], optional): End offset (negative indexing is supported), or None for end of text. Defaults to None.
|
||||
|
||||
"""
|
||||
if style:
|
||||
length = len(self)
|
||||
|
@ -465,6 +464,32 @@ class Text(JupyterMixin):
|
|||
return
|
||||
self._spans.append(Span(start, min(length, end), style))
|
||||
|
||||
def stylize_before(
|
||||
self,
|
||||
style: Union[str, Style],
|
||||
start: int = 0,
|
||||
end: Optional[int] = None,
|
||||
) -> None:
|
||||
"""Apply a style to the text, or a portion of the text. Styles will be applied before other styles already present.
|
||||
|
||||
Args:
|
||||
style (Union[str, Style]): Style instance or style definition to apply.
|
||||
start (int): Start offset (negative indexing is supported). Defaults to 0.
|
||||
end (Optional[int], optional): End offset (negative indexing is supported), or None for end of text. Defaults to None.
|
||||
"""
|
||||
if style:
|
||||
length = len(self)
|
||||
if start < 0:
|
||||
start = length + start
|
||||
if end is None:
|
||||
end = length
|
||||
if end < 0:
|
||||
end = length + end
|
||||
if start >= length or end <= start:
|
||||
# Span not in text or not valid
|
||||
return
|
||||
self._spans.insert(0, Span(start, min(length, end), style))
|
||||
|
||||
def apply_meta(
|
||||
self, meta: Dict[str, Any], start: int = 0, end: Optional[int] = None
|
||||
) -> None:
|
||||
|
|
|
@ -37,7 +37,7 @@ def render_log():
|
|||
|
||||
def test_log():
|
||||
expected = replace_link_ids(
|
||||
"\x1b[2;36m[TIME]\x1b[0m\x1b[2;36m \x1b[0m \x1b]8;id=0;foo\x1b\\\x1b[2msource.py\x1b[0m\x1b]8;;\x1b\\\x1b[2m:\x1b[0m\x1b]8;id=0;foo\x1b\\\x1b[2m32\x1b[0m\x1b]8;;\x1b\\\n\x1b[2;36m \x1b[0m\x1b[2;36m \x1b[0mHello from \x1b[1m<\x1b[0m\x1b[1;95mconsole\x1b[0m\x1b[39m \x1b[0m\x1b[33mwidth\x1b[0m\x1b[39m=\x1b[0m\x1b[1;36m80\x1b[0m\x1b[39m ColorSystem.TRUECOLOR\x1b[0m\x1b[1m>\x1b[0m ! \x1b]8;id=0;foo\x1b\\\x1b[2msource.py\x1b[0m\x1b]8;;\x1b\\\x1b[2m:\x1b[0m\x1b]8;id=0;foo\x1b\\\x1b[2m33\x1b[0m\x1b]8;;\x1b\\\n\x1b[2;36m \x1b[0m\x1b[2;36m \x1b[0m\x1b[1m[\x1b[0m\x1b[1;36m1\x1b[0m, \x1b[1;36m2\x1b[0m, \x1b[1;36m3\x1b[0m\x1b[1m]\x1b[0m \x1b]8;id=0;foo\x1b\\\x1b[2msource.py\x1b[0m\x1b]8;;\x1b\\\x1b[2m:\x1b[0m\x1b]8;id=0;foo\x1b\\\x1b[2m34\x1b[0m\x1b]8;;\x1b\\\n\x1b[2;36m \x1b[0m\x1b[34m╭─\x1b[0m\x1b[34m───────────────────── \x1b[0m\x1b[3;34mlocals\x1b[0m\x1b[34m ─────────────────────\x1b[0m\x1b[34m─╮\x1b[0m \x1b[2m \x1b[0m\n\x1b[2;36m \x1b[0m\x1b[34m│\x1b[0m \x1b[3;33mconsole\x1b[0m\x1b[31m =\x1b[0m \x1b[1m<\x1b[0m\x1b[1;95mconsole\x1b[0m\x1b[39m \x1b[0m\x1b[33mwidth\x1b[0m\x1b[39m=\x1b[0m\x1b[1;36m80\x1b[0m\x1b[39m ColorSystem.TRUECOLOR\x1b[0m\x1b[1m>\x1b[0m \x1b[34m│\x1b[0m \x1b[2m \x1b[0m\n\x1b[2;36m \x1b[0m\x1b[34m╰────────────────────────────────────────────────────╯\x1b[0m \x1b[2m \x1b[0m\n"
|
||||
"\x1b[2;36m[TIME]\x1b[0m\x1b[2;36m \x1b[0m \x1b]8;id=0;foo\x1b\\\x1b[2msource.py\x1b[0m\x1b]8;;\x1b\\\x1b[2m:\x1b[0m\x1b]8;id=0;foo\x1b\\\x1b[2m32\x1b[0m\x1b]8;;\x1b\\\n\x1b[2;36m \x1b[0m\x1b[2;36m \x1b[0mHello from \x1b[1m<\x1b[0m\x1b[1;95mconsole\x1b[0m\x1b[39m \x1b[0m\x1b[33mwidth\x1b[0m\x1b[39m=\x1b[0m\x1b[1;36m80\x1b[0m\x1b[39m ColorSystem.TRUECOLOR\x1b[0m\x1b[1m>\x1b[0m ! \x1b]8;id=0;foo\x1b\\\x1b[2msource.py\x1b[0m\x1b]8;;\x1b\\\x1b[2m:\x1b[0m\x1b]8;id=0;foo\x1b\\\x1b[2m33\x1b[0m\x1b]8;;\x1b\\\n\x1b[2;36m \x1b[0m\x1b[2;36m \x1b[0m\x1b[1m[\x1b[0m\x1b[1;36m1\x1b[0m, \x1b[1;36m2\x1b[0m, \x1b[1;36m3\x1b[0m\x1b[1m]\x1b[0m \x1b]8;id=0;foo\x1b\\\x1b[2msource.py\x1b[0m\x1b]8;;\x1b\\\x1b[2m:\x1b[0m\x1b]8;id=0;foo\x1b\\\x1b[2m34\x1b[0m\x1b]8;;\x1b\\\n\x1b[2;36m \x1b[0m\x1b[34m╭─\x1b[0m\x1b[34m─────────────────────\x1b[0m\x1b[34m \x1b[0m\x1b[3;34mlocals\x1b[0m\x1b[34m \x1b[0m\x1b[34m─────────────────────\x1b[0m\x1b[34m─╮\x1b[0m \x1b[2m \x1b[0m\n\x1b[2;36m \x1b[0m\x1b[34m│\x1b[0m \x1b[3;33mconsole\x1b[0m\x1b[31m =\x1b[0m \x1b[1m<\x1b[0m\x1b[1;95mconsole\x1b[0m\x1b[39m \x1b[0m\x1b[33mwidth\x1b[0m\x1b[39m=\x1b[0m\x1b[1;36m80\x1b[0m\x1b[39m ColorSystem.TRUECOLOR\x1b[0m\x1b[1m>\x1b[0m \x1b[34m│\x1b[0m \x1b[2m \x1b[0m\n\x1b[2;36m \x1b[0m\x1b[34m╰────────────────────────────────────────────────────╯\x1b[0m \x1b[2m \x1b[0m\n"
|
||||
)
|
||||
rendered = render_log()
|
||||
print(repr(rendered))
|
||||
|
|
|
@ -63,9 +63,9 @@ def test_render_size():
|
|||
expected = [
|
||||
[
|
||||
Segment("╭─", Style()),
|
||||
Segment(
|
||||
"────────────────────────────────── Hello ───────────────────────────────────"
|
||||
),
|
||||
Segment("──────────────────────────────────", Style()),
|
||||
Segment(" Hello ", Style()),
|
||||
Segment("───────────────────────────────────", Style()),
|
||||
Segment("─╮", Style()),
|
||||
],
|
||||
[
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue