Text justify initial work, help text

This commit is contained in:
Darren Burns
2022-08-25 10:53:44 +01:00
parent 9eea01f5a1
commit 0db5fe47e0
8 changed files with 102 additions and 2 deletions

View File

@@ -0,0 +1,43 @@
from __future__ import annotations
from rich.text import Text
from textual.app import App, ComposeResult
from textual.widgets import Static
TEXT = """I must not fear.
Fear is the mind-killer.
Fear is the little-death that brings total obliteration.
I will face my fear.
I will permit it to pass over me and through me.
And when it has gone past, I will turn the inner eye to see its path.
Where the fear has gone there will be nothing. Only I will remain."""
class TextJustify(App):
def compose(self) -> ComposeResult:
left = Static(Text(TEXT))
left.styles.text_justify = "left"
yield left
right = Static(TEXT)
right.styles.text_justify = "right"
yield right
center = Static(TEXT)
center.styles.text_justify = "center"
yield center
full = Static(TEXT)
full.styles.text_justify = "full"
yield full
app = TextJustify(css_path="text_justify.scss", watch_css=True)
if __name__ == "__main__":
from rich.console import Console
console = Console()
text = Text(TEXT)
console.print(TEXT, justify="full")

View File

View File

@@ -13,6 +13,7 @@ from textual.css.constants import (
VALID_ALIGN_HORIZONTAL,
VALID_ALIGN_VERTICAL,
VALID_STYLE_FLAGS,
VALID_JUSTIFY,
)
if sys.version_info >= (3, 8):
@@ -648,6 +649,39 @@ def align_help_text() -> HelpText:
)
def text_justify_help_text(context: str) -> HelpText:
"""Help text to show when the user supplies an invalid value for the text-justify property
Returns:
HelpText: Renderable for displaying the help text for this property.
"""
return HelpText(
summary="Invalid value for the [i]text-justify[/] property.",
bullets=[
*ContextSpecificBullets(
css=[
Bullet(
f"The [i]text-justify[/] property must be one of {friendly_list(VALID_JUSTIFY)}",
examples=[
Example("text-justify: center;"),
Example("text-justify: right;"),
],
)
],
inline=[
Bullet(
f"The [i]text_justify[/] property must be one of {friendly_list(VALID_JUSTIFY)}",
examples=[
Example("widget.styles.text_justify = 'center'"),
Example("widget.styles.text_justify = 'right'"),
],
)
],
).get_by_context(context)
],
)
def offset_single_axis_help_text(property_name: str) -> HelpText:
"""Help text to show when the user supplies an invalid value for an offset-* property.

View File

@@ -24,6 +24,7 @@ from ._help_text import (
property_invalid_value_help_text,
scrollbar_size_property_help_text,
scrollbar_size_single_axis_help_text,
text_justify_help_text,
)
from .constants import (
VALID_ALIGN_HORIZONTAL,
@@ -36,6 +37,7 @@ from .constants import (
VALID_VISIBILITY,
VALID_STYLE_FLAGS,
VALID_SCROLLBAR_GUTTER,
VALID_JUSTIFY,
)
from .errors import DeclarationError, StyleValueError
from .model import Declaration
@@ -618,6 +620,19 @@ class StylesBuilder:
style_definition = " ".join(token.value for token in tokens)
self.styles.text_style = style_definition
def process_text_justify(self, name: str, tokens: list[Token]) -> None:
if not tokens:
return
if len(tokens) > 1 or tokens[0].value not in VALID_JUSTIFY:
self.error(
name,
tokens[0],
text_justify_help_text("css"),
)
self.styles._rules["text_justify"] = tokens[0].value
def process_dock(self, name: str, tokens: list[Token]) -> None:
if not tokens:
return

View File

@@ -38,6 +38,7 @@ VALID_BOX_SIZING: Final = {"border-box", "content-box"}
VALID_OVERFLOW: Final = {"scroll", "hidden", "auto"}
VALID_ALIGN_HORIZONTAL: Final = {"left", "center", "right"}
VALID_ALIGN_VERTICAL: Final = {"top", "middle", "bottom"}
VALID_JUSTIFY: Final = {"left", "center", "right", "full"}
VALID_SCROLLBAR_GUTTER: Final = {"auto", "stable"}
VALID_STYLE_FLAGS: Final = {
"none",

View File

@@ -41,6 +41,7 @@ from .constants import (
VALID_OVERFLOW,
VALID_SCROLLBAR_GUTTER,
VALID_VISIBILITY,
VALID_JUSTIFY,
)
from .scalar import Scalar, ScalarOffset, Unit
from .scalar_animation import ScalarAnimation
@@ -56,6 +57,7 @@ from .types import (
Specificity3,
Specificity6,
Visibility,
TextJustify,
)
if sys.version_info >= (3, 8):
@@ -142,6 +144,8 @@ class RulesMap(TypedDict, total=False):
content_align_horizontal: AlignHorizontal
content_align_vertical: AlignVertical
text_justify: TextJustify
RULE_NAMES = list(RulesMap.__annotations__.keys())
RULE_NAMES_SET = frozenset(RULE_NAMES)
@@ -249,6 +253,8 @@ class StylesBase(ABC):
content_align_vertical = StringEnumProperty(VALID_ALIGN_VERTICAL, "top")
content_align = AlignProperty()
text_justify = StringEnumProperty(VALID_JUSTIFY, "left")
def __eq__(self, styles: object) -> bool:
"""Check that Styles contains the same rules."""
if not isinstance(styles, StylesBase):
@@ -458,7 +464,6 @@ class StylesBase(ABC):
@rich.repr.auto
@dataclass
class Styles(StylesBase):
node: DOMNode | None = None
_rules: RulesMap = field(default_factory=dict)

View File

@@ -39,6 +39,7 @@ ScrollbarGutter = Literal["auto", "stable"]
BoxSizing = Literal["border-box", "content-box"]
Overflow = Literal["scroll", "hidden", "auto"]
EdgeStyle = Tuple[EdgeType, Color]
TextJustify = Literal["left", "center", "right", "full"]
Specificity3 = Tuple[int, int, int]
Specificity4 = Tuple[int, int, int, int]

View File

@@ -982,11 +982,12 @@ class Widget(DOMNode):
"""
if isinstance(renderable, str):
renderable = Text.from_markup(renderable)
renderable = Text.from_markup(renderable, justify=self.styles.text_justify)
rich_style = self.rich_style
if isinstance(renderable, Text):
renderable.stylize(rich_style)
renderable.justify = self.styles.text_justify
else:
renderable = Styled(renderable, rich_style)