text style properties

This commit is contained in:
Will McGugan
2021-11-11 15:14:44 +00:00
parent fd6381fddc
commit c669ab85d4
6 changed files with 47 additions and 18 deletions

View File

@@ -143,11 +143,10 @@ class StyleProperty:
color = getattr(obj, self._color_name) or Color.default() color = getattr(obj, self._color_name) or Color.default()
bgcolor = getattr(obj, self._bgcolor_name) or Color.default() bgcolor = getattr(obj, self._bgcolor_name) or Color.default()
style = Style(color=color, bgcolor=bgcolor) style = Style.from_color(color, bgcolor)
style_flags = getattr(obj, self._style_name) style_flags = getattr(obj, self._style_name)
if style_flags is not None: if style_flags is not None:
flags = Style.parse(style_flags) style += style_flags
style += flags
return style return style
def __set__(self, obj: Styles, style: Style | str | None) -> Style | str | None: def __set__(self, obj: Styles, style: Style | str | None) -> Style | str | None:
@@ -327,22 +326,35 @@ class ColorProperty:
class StyleFlagsProperty: class StyleFlagsProperty:
_VALID_PROPERTIES = {"not", "bold", "italic", "underline", "overline", "strike"} _VALID_PROPERTIES = {
"not",
"bold",
"italic",
"underline",
"overline",
"strike",
"b",
"i",
"u",
"o",
}
def __set_name__(self, owner: Styles, name: str) -> None: def __set_name__(self, owner: Styles, name: str) -> None:
self._name = name self._name = name
self._internal_name = f"_rule_{name}" self._internal_name = f"_rule_{name}"
def __get__(self, obj: Styles, objtype: type[Styles] | None = None) -> str: def __get__(self, obj: Styles, objtype: type[Styles] | None = None) -> Style:
return getattr(obj, self._internal_name, None) or "" return getattr(obj, self._internal_name, None) or Style.null()
def __set__(self, obj: Styles, style_flags: str | None) -> str | None: def __set__(self, obj: Styles, style_flags: str | None) -> str | None:
if style_flags is None: if style_flags is None:
setattr(self, self._internal_name, None) setattr(self, self._internal_name, None)
else: else:
# TODO: more specific error words = [word.strip() for word in style_flags.split(" ")]
words = {word.strip() for word in style_flags.split(" ")} valid_word = self._VALID_PROPERTIES.__contains__
if words not in self._VALID_PROPERTIES: for word in words:
raise StyleValueError(f"unknown style attribute(s) in {style_flags!r}") if not valid_word(word):
setattr(self, self._internal_name, " ".join(words)) raise StyleValueError(f"unknown word {word!r} in style flags")
style = Style.parse(" ".join(words))
setattr(obj, self._internal_name, style)
return style_flags return style_flags

View File

@@ -239,6 +239,10 @@ class StylesBuilder:
name, token, f"unexpected token {token.value!r} in declaration" name, token, f"unexpected token {token.value!r} in declaration"
) )
def process_text_style(self, name: str, tokens: list[Token]) -> None:
style_definition = " ".join(token.value for token in tokens)
self.styles.text_style = style_definition
def process_dock_group(self, name: str, tokens: list[Token]) -> None: def process_dock_group(self, name: str, tokens: list[Token]) -> None:
if len(tokens) > 1: if len(tokens) > 1:

View File

@@ -45,7 +45,7 @@ class Styles:
_rule_text_color: Color | None = None _rule_text_color: Color | None = None
_rule_text_bgcolor: Color | None = None _rule_text_bgcolor: Color | None = None
_rule_text_style: str | None = None _rule_text_style: Style | None = None
_rule_padding: Spacing | None = None _rule_padding: Spacing | None = None
_rule_margin: Spacing | None = None _rule_margin: Spacing | None = None
@@ -274,12 +274,15 @@ if __name__ == "__main__":
styles.border = ("solid", "rgb(10,20,30)") styles.border = ("solid", "rgb(10,20,30)")
styles.outline_right = ("solid", "red") styles.outline_right = ("solid", "red")
styles.docks = "foo bar" styles.docks = "foo bar"
styles.text = "italic blue" styles.text_style = "italic"
styles.dock_group = "bar" styles.dock_group = "bar"
styles.layers = "foo bar" styles.layers = "foo bar"
from rich import inspect, print from rich import inspect, print
print(styles.text_style)
print(styles.text)
print(styles) print(styles)
print(styles.css) print(styles.css)

View File

@@ -9,9 +9,8 @@ import rich.repr
from .errors import StylesheetError from .errors import StylesheetError
from .match import _check_selectors from .match import _check_selectors
from .model import CombinatorType, RuleSet, Selector from .model import RuleSet
from .parse import parse from .parse import parse
from .styles import Styles
from .types import Specificity3, Specificity4 from .types import Specificity3, Specificity4
from ..dom import DOMNode from ..dom import DOMNode
@@ -133,13 +132,15 @@ if __name__ == "__main__":
} }
Widget{ Widget{
text: purple; text: red;
text-style: bold
} }
/*
View #widget1 { View #widget1 {
text: green !important; text: green !important;
} }
*/
App > View.-subview { App > View.-subview {
@@ -152,8 +153,12 @@ if __name__ == "__main__":
stylesheet = Stylesheet() stylesheet = Stylesheet()
stylesheet.parse(CSS) stylesheet.parse(CSS)
print(widget1.styles)
stylesheet.apply(widget1) stylesheet.apply(widget1)
print(widget1.styles)
# from .query import DOMQuery # from .query import DOMQuery
# tests = ["View", "App > View", "Widget.float", ".float.transient", "*"] # tests = ["View", "App > View", "Widget.float", ".float.transient", "*"]

View File

@@ -44,6 +44,9 @@ class Token(NamedTuple):
name: str name: str
value: str value: str
def __str__(self) -> str:
return self.value
class Tokenizer: class Tokenizer:
def __init__(self, text: str) -> None: def __init__(self, text: str) -> None:

View File

@@ -3,7 +3,7 @@ from __future__ import annotations
from itertools import chain from itertools import chain
from typing import Callable, Iterable, ClassVar, TYPE_CHECKING from typing import Callable, Iterable, ClassVar, TYPE_CHECKING
from rich.console import Console, ConsoleOptions, RenderResult, RenderableType from rich.console import RenderableType
import rich.repr import rich.repr
from rich.style import Style from rich.style import Style
@@ -143,9 +143,11 @@ class View(Widget):
name_widgets = chain( name_widgets = chain(
((None, widget) for widget in anon_widgets), widgets.items() ((None, widget) for widget in anon_widgets), widgets.items()
) )
stylesheet = self.app.stylesheet
for name, widget in name_widgets: for name, widget in name_widgets:
if name is not None: if name is not None:
widget.name = name widget.name = name
stylesheet.apply(widget)
self._add_child(widget) self._add_child(widget)
self.refresh() self.refresh()