mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Merge pull request #1759 from Textualize/typing-fix-9-feb-2023
typing fixes
This commit is contained in:
2315
poetry.lock
generated
2315
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -69,6 +69,7 @@ syrupy = "^3.0.0"
|
|||||||
mkdocs-rss-plugin = "^1.5.0"
|
mkdocs-rss-plugin = "^1.5.0"
|
||||||
httpx = "^0.23.1"
|
httpx = "^0.23.1"
|
||||||
msgpack-types = "^0.2.0"
|
msgpack-types = "^0.2.0"
|
||||||
|
types-setuptools = "^67.2.0.1"
|
||||||
|
|
||||||
[tool.black]
|
[tool.black]
|
||||||
includes = "src"
|
includes = "src"
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ BORDER_LOCATIONS: dict[
|
|||||||
|
|
||||||
INVISIBLE_EDGE_TYPES = cast("frozenset[EdgeType]", frozenset(("", "none", "hidden")))
|
INVISIBLE_EDGE_TYPES = cast("frozenset[EdgeType]", frozenset(("", "none", "hidden")))
|
||||||
|
|
||||||
BorderValue: TypeAlias = Tuple[EdgeType, Union[str, Color, Style]]
|
BorderValue: TypeAlias = Tuple[EdgeType, Color]
|
||||||
|
|
||||||
BoxSegments: TypeAlias = Tuple[
|
BoxSegments: TypeAlias = Tuple[
|
||||||
Tuple[Segment, Segment, Segment],
|
Tuple[Segment, Segment, Segment],
|
||||||
|
|||||||
@@ -10,11 +10,12 @@ when setting and getting.
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
from typing import TYPE_CHECKING, Generic, Iterable, NamedTuple, TypeVar, cast
|
from typing import TYPE_CHECKING, Generic, Iterable, NamedTuple, Sequence, TypeVar, cast
|
||||||
|
|
||||||
import rich.errors
|
import rich.errors
|
||||||
import rich.repr
|
import rich.repr
|
||||||
from rich.style import Style
|
from rich.style import Style
|
||||||
|
from typing_extensions import TypeAlias
|
||||||
|
|
||||||
from .._border import normalize_border_value
|
from .._border import normalize_border_value
|
||||||
from ..color import Color, ColorParseError
|
from ..color import Color, ColorParseError
|
||||||
@@ -51,7 +52,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
from .types import AlignHorizontal, AlignVertical, DockEdge, EdgeType
|
from .types import AlignHorizontal, AlignVertical, DockEdge, EdgeType
|
||||||
|
|
||||||
BorderDefinition = (
|
BorderDefinition: TypeAlias = (
|
||||||
"Sequence[tuple[EdgeType, str | Color] | None] | tuple[EdgeType, str | Color]"
|
"Sequence[tuple[EdgeType, str | Color] | None] | tuple[EdgeType, str | Color]"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -153,7 +154,7 @@ class ScalarProperty:
|
|||||||
Returns:
|
Returns:
|
||||||
The Scalar object or ``None`` if it's not set.
|
The Scalar object or ``None`` if it's not set.
|
||||||
"""
|
"""
|
||||||
return obj.get_rule(self.name)
|
return cast("Scalar | None", obj.get_rule(self.name))
|
||||||
|
|
||||||
def __set__(
|
def __set__(
|
||||||
self, obj: StylesBase, value: float | int | Scalar | str | None
|
self, obj: StylesBase, value: float | int | Scalar | str | None
|
||||||
@@ -233,7 +234,7 @@ class ScalarListProperty:
|
|||||||
def __get__(
|
def __get__(
|
||||||
self, obj: StylesBase, objtype: type[StylesBase] | None = None
|
self, obj: StylesBase, objtype: type[StylesBase] | None = None
|
||||||
) -> tuple[Scalar, ...] | None:
|
) -> tuple[Scalar, ...] | None:
|
||||||
return obj.get_rule(self.name)
|
return cast("tuple[Scalar, ...]", obj.get_rule(self.name))
|
||||||
|
|
||||||
def __set__(
|
def __set__(
|
||||||
self, obj: StylesBase, value: str | Iterable[str | float] | None
|
self, obj: StylesBase, value: str | Iterable[str | float] | None
|
||||||
@@ -289,7 +290,10 @@ class BoxProperty:
|
|||||||
A ``tuple[EdgeType, Style]`` containing the string type of the box and
|
A ``tuple[EdgeType, Style]`` containing the string type of the box and
|
||||||
it's style. Example types are "rounded", "solid", and "dashed".
|
it's style. Example types are "rounded", "solid", and "dashed".
|
||||||
"""
|
"""
|
||||||
return obj.get_rule(self.name) or ("", self._default_color)
|
return cast(
|
||||||
|
"tuple[EdgeType, Color]",
|
||||||
|
obj.get_rule(self.name) or ("", self._default_color),
|
||||||
|
)
|
||||||
|
|
||||||
def __set__(self, obj: Styles, border: tuple[EdgeType, str | Color] | None):
|
def __set__(self, obj: Styles, border: tuple[EdgeType, str | Color] | None):
|
||||||
"""Set the box property.
|
"""Set the box property.
|
||||||
@@ -452,7 +456,7 @@ class BorderProperty:
|
|||||||
check_refresh()
|
check_refresh()
|
||||||
return
|
return
|
||||||
if isinstance(border, tuple) and len(border) == 2:
|
if isinstance(border, tuple) and len(border) == 2:
|
||||||
_border = normalize_border_value(border)
|
_border = normalize_border_value(border) # type: ignore
|
||||||
setattr(obj, top, _border)
|
setattr(obj, top, _border)
|
||||||
setattr(obj, right, _border)
|
setattr(obj, right, _border)
|
||||||
setattr(obj, bottom, _border)
|
setattr(obj, bottom, _border)
|
||||||
@@ -462,15 +466,15 @@ class BorderProperty:
|
|||||||
|
|
||||||
count = len(border)
|
count = len(border)
|
||||||
if count == 1:
|
if count == 1:
|
||||||
_border = normalize_border_value(border[0])
|
_border = normalize_border_value(border[0]) # type: ignore
|
||||||
setattr(obj, top, _border)
|
setattr(obj, top, _border)
|
||||||
setattr(obj, right, _border)
|
setattr(obj, right, _border)
|
||||||
setattr(obj, bottom, _border)
|
setattr(obj, bottom, _border)
|
||||||
setattr(obj, left, _border)
|
setattr(obj, left, _border)
|
||||||
elif count == 2:
|
elif count == 2:
|
||||||
_border1, _border2 = (
|
_border1, _border2 = (
|
||||||
normalize_border_value(border[0]),
|
normalize_border_value(border[0]), # type: ignore
|
||||||
normalize_border_value(border[1]),
|
normalize_border_value(border[1]), # type: ignore
|
||||||
)
|
)
|
||||||
setattr(obj, top, _border1)
|
setattr(obj, top, _border1)
|
||||||
setattr(obj, bottom, _border1)
|
setattr(obj, bottom, _border1)
|
||||||
@@ -478,10 +482,10 @@ class BorderProperty:
|
|||||||
setattr(obj, left, _border2)
|
setattr(obj, left, _border2)
|
||||||
elif count == 4:
|
elif count == 4:
|
||||||
_border1, _border2, _border3, _border4 = (
|
_border1, _border2, _border3, _border4 = (
|
||||||
normalize_border_value(border[0]),
|
normalize_border_value(border[0]), # type: ignore
|
||||||
normalize_border_value(border[1]),
|
normalize_border_value(border[1]), # type: ignore
|
||||||
normalize_border_value(border[2]),
|
normalize_border_value(border[2]), # type: ignore
|
||||||
normalize_border_value(border[3]),
|
normalize_border_value(border[3]), # type: ignore
|
||||||
)
|
)
|
||||||
setattr(obj, top, _border1)
|
setattr(obj, top, _border1)
|
||||||
setattr(obj, right, _border2)
|
setattr(obj, right, _border2)
|
||||||
@@ -513,7 +517,7 @@ class SpacingProperty:
|
|||||||
Returns:
|
Returns:
|
||||||
The Spacing. If unset, returns the null spacing ``(0, 0, 0, 0)``.
|
The Spacing. If unset, returns the null spacing ``(0, 0, 0, 0)``.
|
||||||
"""
|
"""
|
||||||
return obj.get_rule(self.name, NULL_SPACING)
|
return cast(Spacing, obj.get_rule(self.name, NULL_SPACING))
|
||||||
|
|
||||||
def __set__(self, obj: StylesBase, spacing: SpacingDimensions | None):
|
def __set__(self, obj: StylesBase, spacing: SpacingDimensions | None):
|
||||||
"""Set the Spacing.
|
"""Set the Spacing.
|
||||||
@@ -594,7 +598,7 @@ class LayoutProperty:
|
|||||||
Returns:
|
Returns:
|
||||||
The ``Layout`` object.
|
The ``Layout`` object.
|
||||||
"""
|
"""
|
||||||
return obj.get_rule(self.name)
|
return cast("Layout | None", obj.get_rule(self.name))
|
||||||
|
|
||||||
def __set__(self, obj: StylesBase, layout: str | Layout | None):
|
def __set__(self, obj: StylesBase, layout: str | Layout | None):
|
||||||
"""
|
"""
|
||||||
@@ -648,7 +652,7 @@ class OffsetProperty:
|
|||||||
The ``ScalarOffset`` indicating the adjustment that
|
The ``ScalarOffset`` indicating the adjustment that
|
||||||
will be made to widget position prior to it being rendered.
|
will be made to widget position prior to it being rendered.
|
||||||
"""
|
"""
|
||||||
return obj.get_rule(self.name, NULL_SCALAR)
|
return cast("ScalarOffset", obj.get_rule(self.name, NULL_SCALAR))
|
||||||
|
|
||||||
def __set__(
|
def __set__(
|
||||||
self, obj: StylesBase, offset: tuple[int | str, int | str] | ScalarOffset | None
|
self, obj: StylesBase, offset: tuple[int | str, int | str] | ScalarOffset | None
|
||||||
@@ -734,7 +738,7 @@ class StringEnumProperty:
|
|||||||
Returns:
|
Returns:
|
||||||
The string property value.
|
The string property value.
|
||||||
"""
|
"""
|
||||||
return obj.get_rule(self.name, self._default)
|
return cast(str, obj.get_rule(self.name, self._default))
|
||||||
|
|
||||||
def _before_refresh(self, obj: StylesBase, value: str | None) -> None:
|
def _before_refresh(self, obj: StylesBase, value: str | None) -> None:
|
||||||
"""Do any housekeeping before asking for a layout refresh after a value change."""
|
"""Do any housekeeping before asking for a layout refresh after a value change."""
|
||||||
@@ -795,7 +799,7 @@ class NameProperty:
|
|||||||
Returns:
|
Returns:
|
||||||
The name.
|
The name.
|
||||||
"""
|
"""
|
||||||
return obj.get_rule(self.name, "")
|
return cast(str, obj.get_rule(self.name, ""))
|
||||||
|
|
||||||
def __set__(self, obj: StylesBase, name: str | None):
|
def __set__(self, obj: StylesBase, name: str | None):
|
||||||
"""Set the name property.
|
"""Set the name property.
|
||||||
@@ -929,7 +933,7 @@ class StyleFlagsProperty:
|
|||||||
Returns:
|
Returns:
|
||||||
The ``Style`` object.
|
The ``Style`` object.
|
||||||
"""
|
"""
|
||||||
return obj.get_rule(self.name, Style.null())
|
return cast(Style, obj.get_rule(self.name, Style.null()))
|
||||||
|
|
||||||
def __set__(self, obj: StylesBase, style_flags: Style | str | None):
|
def __set__(self, obj: StylesBase, style_flags: Style | str | None):
|
||||||
"""Set the style using a style flag string.
|
"""Set the style using a style flag string.
|
||||||
@@ -992,7 +996,7 @@ class TransitionsProperty:
|
|||||||
e.g. ``{"offset": Transition(...), ...}``. If no transitions have been set, an empty ``dict``
|
e.g. ``{"offset": Transition(...), ...}``. If no transitions have been set, an empty ``dict``
|
||||||
is returned.
|
is returned.
|
||||||
"""
|
"""
|
||||||
return obj.get_rule("transitions", {})
|
return cast("dict[str, Transition]", obj.get_rule("transitions", {}))
|
||||||
|
|
||||||
def __set__(self, obj: Styles, transitions: dict[str, Transition] | None) -> None:
|
def __set__(self, obj: Styles, transitions: dict[str, Transition] | None) -> None:
|
||||||
_rich_traceback_omit = True
|
_rich_traceback_omit = True
|
||||||
|
|||||||
@@ -113,7 +113,6 @@ class StylesBuilder:
|
|||||||
suggested_property_name=suggested_property_name,
|
suggested_property_name=suggested_property_name,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return
|
|
||||||
|
|
||||||
tokens = declaration.tokens
|
tokens = declaration.tokens
|
||||||
|
|
||||||
@@ -182,7 +181,13 @@ class StylesBuilder:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if len(tokens) != 1:
|
if len(tokens) != 1:
|
||||||
string_enum_help_text(name, valid_values=list(valid_values), context="css"),
|
self.error(
|
||||||
|
name,
|
||||||
|
tokens[0],
|
||||||
|
string_enum_help_text(
|
||||||
|
name, valid_values=list(valid_values), context="css"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
token = tokens[0]
|
token = tokens[0]
|
||||||
token_name, value, _, _, location, _ = token
|
token_name, value, _, _, location, _ = token
|
||||||
@@ -239,7 +244,7 @@ class StylesBuilder:
|
|||||||
return
|
return
|
||||||
if len(tokens) == 1:
|
if len(tokens) == 1:
|
||||||
try:
|
try:
|
||||||
self.styles._rules[name.replace("-", "_")] = Scalar.parse(
|
self.styles._rules[name.replace("-", "_")] = Scalar.parse( # type: ignore
|
||||||
tokens[0].value
|
tokens[0].value
|
||||||
)
|
)
|
||||||
except ScalarParseError:
|
except ScalarParseError:
|
||||||
@@ -390,7 +395,7 @@ class StylesBuilder:
|
|||||||
name, num_values_supplied=len(space), context="css"
|
name, num_values_supplied=len(space), context="css"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self.styles._rules[name] = Spacing.unpack(cast(SpacingDimensions, tuple(space)))
|
self.styles._rules[name] = Spacing.unpack(cast(SpacingDimensions, tuple(space))) # type: ignore
|
||||||
|
|
||||||
def _process_space_partial(self, name: str, tokens: list[Token]) -> None:
|
def _process_space_partial(self, name: str, tokens: list[Token]) -> None:
|
||||||
"""Process granular margin / padding declarations."""
|
"""Process granular margin / padding declarations."""
|
||||||
@@ -418,7 +423,7 @@ class StylesBuilder:
|
|||||||
spacing_list = list(current_spacing)
|
spacing_list = list(current_spacing)
|
||||||
spacing_list[_EDGE_SPACING_MAP[edge]] = space
|
spacing_list[_EDGE_SPACING_MAP[edge]] = space
|
||||||
|
|
||||||
self.styles._rules[style_name] = Spacing(*spacing_list)
|
self.styles._rules[style_name] = Spacing(*spacing_list) # type: ignore
|
||||||
|
|
||||||
process_padding = _process_space
|
process_padding = _process_space
|
||||||
process_margin = _process_space
|
process_margin = _process_space
|
||||||
@@ -444,7 +449,7 @@ class StylesBuilder:
|
|||||||
token_name, value, _, _, _, _ = token
|
token_name, value, _, _, _, _ = token
|
||||||
if token_name == "token":
|
if token_name == "token":
|
||||||
if value in VALID_BORDER:
|
if value in VALID_BORDER:
|
||||||
border_type = value
|
border_type = value # type: ignore
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
border_color = Color.parse(value)
|
border_color = Color.parse(value)
|
||||||
@@ -464,7 +469,7 @@ class StylesBuilder:
|
|||||||
|
|
||||||
def _process_border_edge(self, edge: str, name: str, tokens: list[Token]) -> None:
|
def _process_border_edge(self, edge: str, name: str, tokens: list[Token]) -> None:
|
||||||
border = self._parse_border(name, tokens)
|
border = self._parse_border(name, tokens)
|
||||||
self.styles._rules[f"border_{edge}"] = border
|
self.styles._rules[f"border_{edge}"] = border # type: ignore
|
||||||
|
|
||||||
def process_border(self, name: str, tokens: list[Token]) -> None:
|
def process_border(self, name: str, tokens: list[Token]) -> None:
|
||||||
border = self._parse_border(name, tokens)
|
border = self._parse_border(name, tokens)
|
||||||
@@ -486,7 +491,7 @@ class StylesBuilder:
|
|||||||
|
|
||||||
def _process_outline(self, edge: str, name: str, tokens: list[Token]) -> None:
|
def _process_outline(self, edge: str, name: str, tokens: list[Token]) -> None:
|
||||||
border = self._parse_border(name, tokens)
|
border = self._parse_border(name, tokens)
|
||||||
self.styles._rules[f"outline_{edge}"] = border
|
self.styles._rules[f"outline_{edge}"] = border # type: ignore
|
||||||
|
|
||||||
def process_outline(self, name: str, tokens: list[Token]) -> None:
|
def process_outline(self, name: str, tokens: list[Token]) -> None:
|
||||||
border = self._parse_border(name, tokens)
|
border = self._parse_border(name, tokens)
|
||||||
@@ -579,14 +584,14 @@ class StylesBuilder:
|
|||||||
color: Color | None = None
|
color: Color | None = None
|
||||||
alpha: float | None = None
|
alpha: float | None = None
|
||||||
|
|
||||||
self.styles._rules[f"auto_{name}"] = False
|
self.styles._rules[f"auto_{name}"] = False # type: ignore
|
||||||
for token in tokens:
|
for token in tokens:
|
||||||
if (
|
if (
|
||||||
"background" not in name
|
"background" not in name
|
||||||
and token.name == "token"
|
and token.name == "token"
|
||||||
and token.value == "auto"
|
and token.value == "auto"
|
||||||
):
|
):
|
||||||
self.styles._rules[f"auto_{name}"] = True
|
self.styles._rules[f"auto_{name}"] = True # type: ignore
|
||||||
elif token.name == "scalar":
|
elif token.name == "scalar":
|
||||||
alpha_scalar = Scalar.parse(token.value)
|
alpha_scalar = Scalar.parse(token.value)
|
||||||
if alpha_scalar.unit != Unit.PERCENT:
|
if alpha_scalar.unit != Unit.PERCENT:
|
||||||
@@ -608,7 +613,7 @@ class StylesBuilder:
|
|||||||
if color is not None or alpha is not None:
|
if color is not None or alpha is not None:
|
||||||
if alpha is not None:
|
if alpha is not None:
|
||||||
color = (color or Color(255, 255, 255)).with_alpha(alpha)
|
color = (color or Color(255, 255, 255)).with_alpha(alpha)
|
||||||
self.styles._rules[name] = color
|
self.styles._rules[name] = color # type: ignore
|
||||||
|
|
||||||
process_tint = process_color
|
process_tint = process_color
|
||||||
process_background = process_color
|
process_background = process_color
|
||||||
@@ -636,7 +641,7 @@ class StylesBuilder:
|
|||||||
)
|
)
|
||||||
|
|
||||||
style_definition = " ".join(token.value for token in tokens)
|
style_definition = " ".join(token.value for token in tokens)
|
||||||
self.styles._rules[name.replace("-", "_")] = style_definition
|
self.styles._rules[name.replace("-", "_")] = style_definition # type: ignore
|
||||||
|
|
||||||
process_link_style = process_text_style
|
process_link_style = process_text_style
|
||||||
process_link_hover_style = process_text_style
|
process_link_hover_style = process_text_style
|
||||||
@@ -653,7 +658,7 @@ class StylesBuilder:
|
|||||||
text_align_help_text(),
|
text_align_help_text(),
|
||||||
)
|
)
|
||||||
|
|
||||||
self.styles._rules["text_align"] = tokens[0].value
|
self.styles._rules["text_align"] = tokens[0].value # type: ignore
|
||||||
|
|
||||||
def process_dock(self, name: str, tokens: list[Token]) -> None:
|
def process_dock(self, name: str, tokens: list[Token]) -> None:
|
||||||
if not tokens:
|
if not tokens:
|
||||||
@@ -766,8 +771,8 @@ class StylesBuilder:
|
|||||||
align_error(name, token_horizontal)
|
align_error(name, token_horizontal)
|
||||||
|
|
||||||
name = name.replace("-", "_")
|
name = name.replace("-", "_")
|
||||||
self.styles._rules[f"{name}_horizontal"] = token_horizontal.value
|
self.styles._rules[f"{name}_horizontal"] = token_horizontal.value # type: ignore
|
||||||
self.styles._rules[f"{name}_vertical"] = token_vertical.value
|
self.styles._rules[f"{name}_vertical"] = token_vertical.value # type: ignore
|
||||||
|
|
||||||
def process_align_horizontal(self, name: str, tokens: list[Token]) -> None:
|
def process_align_horizontal(self, name: str, tokens: list[Token]) -> None:
|
||||||
try:
|
try:
|
||||||
@@ -779,7 +784,7 @@ class StylesBuilder:
|
|||||||
string_enum_help_text(name, VALID_ALIGN_HORIZONTAL, context="css"),
|
string_enum_help_text(name, VALID_ALIGN_HORIZONTAL, context="css"),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.styles._rules[name.replace("-", "_")] = value
|
self.styles._rules[name.replace("-", "_")] = value # type: ignore
|
||||||
|
|
||||||
def process_align_vertical(self, name: str, tokens: list[Token]) -> None:
|
def process_align_vertical(self, name: str, tokens: list[Token]) -> None:
|
||||||
try:
|
try:
|
||||||
@@ -791,7 +796,7 @@ class StylesBuilder:
|
|||||||
string_enum_help_text(name, VALID_ALIGN_VERTICAL, context="css"),
|
string_enum_help_text(name, VALID_ALIGN_VERTICAL, context="css"),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.styles._rules[name.replace("-", "_")] = value
|
self.styles._rules[name.replace("-", "_")] = value # type: ignore
|
||||||
|
|
||||||
process_content_align = process_align
|
process_content_align = process_align
|
||||||
process_content_align_horizontal = process_align_horizontal
|
process_content_align_horizontal = process_align_horizontal
|
||||||
@@ -807,7 +812,7 @@ class StylesBuilder:
|
|||||||
string_enum_help_text(name, VALID_SCROLLBAR_GUTTER, context="css"),
|
string_enum_help_text(name, VALID_SCROLLBAR_GUTTER, context="css"),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.styles._rules[name.replace("-", "_")] = value
|
self.styles._rules[name.replace("-", "_")] = value # type: ignore
|
||||||
|
|
||||||
def process_scrollbar_size(self, name: str, tokens: list[Token]) -> None:
|
def process_scrollbar_size(self, name: str, tokens: list[Token]) -> None:
|
||||||
def scrollbar_size_error(name: str, token: Token) -> None:
|
def scrollbar_size_error(name: str, token: Token) -> None:
|
||||||
@@ -876,7 +881,7 @@ class StylesBuilder:
|
|||||||
token,
|
token,
|
||||||
table_rows_or_columns_help_text(name, token.value, context="css"),
|
table_rows_or_columns_help_text(name, token.value, context="css"),
|
||||||
)
|
)
|
||||||
self.styles._rules[name.replace("-", "_")] = scalars
|
self.styles._rules[name.replace("-", "_")] = scalars # type: ignore
|
||||||
|
|
||||||
process_grid_rows = _process_grid_rows_or_columns
|
process_grid_rows = _process_grid_rows_or_columns
|
||||||
process_grid_columns = _process_grid_rows_or_columns
|
process_grid_columns = _process_grid_rows_or_columns
|
||||||
@@ -893,7 +898,7 @@ class StylesBuilder:
|
|||||||
value = int(token.value)
|
value = int(token.value)
|
||||||
if value == 0:
|
if value == 0:
|
||||||
self.error(name, token, integer_help_text(name))
|
self.error(name, token, integer_help_text(name))
|
||||||
self.styles._rules[name.replace("-", "_")] = value
|
self.styles._rules[name.replace("-", "_")] = value # type: ignore
|
||||||
|
|
||||||
process_grid_gutter_horizontal = _process_integer
|
process_grid_gutter_horizontal = _process_integer
|
||||||
process_grid_gutter_vertical = _process_integer
|
process_grid_gutter_vertical = _process_integer
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Iterable
|
|||||||
|
|
||||||
import rich.repr
|
import rich.repr
|
||||||
|
|
||||||
|
from ._help_renderables import HelpText
|
||||||
from .styles import Styles
|
from .styles import Styles
|
||||||
from .tokenize import Token
|
from .tokenize import Token
|
||||||
from .types import Specificity3
|
from .types import Specificity3
|
||||||
@@ -155,7 +156,7 @@ class SelectorSet:
|
|||||||
class RuleSet:
|
class RuleSet:
|
||||||
selector_set: list[SelectorSet] = field(default_factory=list)
|
selector_set: list[SelectorSet] = field(default_factory=list)
|
||||||
styles: Styles = field(default_factory=Styles)
|
styles: Styles = field(default_factory=Styles)
|
||||||
errors: list[tuple[Token, str]] = field(default_factory=list)
|
errors: list[tuple[Token, str | HelpText]] = field(default_factory=list)
|
||||||
|
|
||||||
is_default_rules: bool = False
|
is_default_rules: bool = False
|
||||||
tie_breaker: int = 0
|
tie_breaker: int = 0
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from pathlib import PurePath
|
|||||||
from typing import Iterable, Iterator, NoReturn
|
from typing import Iterable, Iterator, NoReturn
|
||||||
|
|
||||||
from ..suggestions import get_suggestion
|
from ..suggestions import get_suggestion
|
||||||
|
from ._help_renderables import HelpText
|
||||||
from ._styles_builder import DeclarationError, StylesBuilder
|
from ._styles_builder import DeclarationError, StylesBuilder
|
||||||
from .errors import UnresolvedVariableError
|
from .errors import UnresolvedVariableError
|
||||||
from .model import (
|
from .model import (
|
||||||
@@ -130,7 +131,7 @@ def parse_rule_set(
|
|||||||
|
|
||||||
declaration = Declaration(token, "")
|
declaration = Declaration(token, "")
|
||||||
|
|
||||||
errors: list[tuple[Token, str]] = []
|
errors: list[tuple[Token, str | HelpText]] = []
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
token = next(tokens)
|
token = next(tokens)
|
||||||
|
|||||||
@@ -367,8 +367,8 @@ class StylesBase(ABC):
|
|||||||
def auto_dimensions(self) -> bool:
|
def auto_dimensions(self) -> bool:
|
||||||
"""Check if width or height are set to 'auto'."""
|
"""Check if width or height are set to 'auto'."""
|
||||||
has_rule = self.has_rule
|
has_rule = self.has_rule
|
||||||
return (has_rule("width") and self.width.is_auto) or (
|
return (has_rule("width") and self.width.is_auto) or ( # type: ignore
|
||||||
has_rule("height") and self.height.is_auto
|
has_rule("height") and self.height.is_auto # type: ignore
|
||||||
)
|
)
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@@ -603,7 +603,7 @@ class Styles(StylesBase):
|
|||||||
Returns:
|
Returns:
|
||||||
``True`` if a rule was cleared, or ``False`` if it was already not set.
|
``True`` if a rule was cleared, or ``False`` if it was already not set.
|
||||||
"""
|
"""
|
||||||
changed = self._rules.pop(rule, None) is not None
|
changed = self._rules.pop(rule, None) is not None # type: ignore
|
||||||
if changed:
|
if changed:
|
||||||
self._updates += 1
|
self._updates += 1
|
||||||
return changed
|
return changed
|
||||||
@@ -622,12 +622,12 @@ class Styles(StylesBase):
|
|||||||
``True`` if the rule changed, otherwise ``False``.
|
``True`` if the rule changed, otherwise ``False``.
|
||||||
"""
|
"""
|
||||||
if value is None:
|
if value is None:
|
||||||
changed = self._rules.pop(rule, None) is not None
|
changed = self._rules.pop(rule, None) is not None # type: ignore
|
||||||
if changed:
|
if changed:
|
||||||
self._updates += 1
|
self._updates += 1
|
||||||
return changed
|
return changed
|
||||||
current = self._rules.get(rule)
|
current = self._rules.get(rule)
|
||||||
self._rules[rule] = value
|
self._rules[rule] = value # type: ignore
|
||||||
changed = current != value
|
changed = current != value
|
||||||
if changed:
|
if changed:
|
||||||
self._updates += 1
|
self._updates += 1
|
||||||
@@ -646,7 +646,7 @@ class Styles(StylesBase):
|
|||||||
def reset(self) -> None:
|
def reset(self) -> None:
|
||||||
"""Reset the rules to initial state."""
|
"""Reset the rules to initial state."""
|
||||||
self._updates += 1
|
self._updates += 1
|
||||||
self._rules.clear()
|
self._rules.clear() # type: ignore
|
||||||
|
|
||||||
def merge(self, other: Styles) -> None:
|
def merge(self, other: Styles) -> None:
|
||||||
"""Merge values from another Styles.
|
"""Merge values from another Styles.
|
||||||
@@ -736,25 +736,25 @@ class Styles(StylesBase):
|
|||||||
left = get_rule(f"{name}_left")
|
left = get_rule(f"{name}_left")
|
||||||
|
|
||||||
if top == right and right == bottom and bottom == left:
|
if top == right and right == bottom and bottom == left:
|
||||||
border_type, border_color = rules[f"{name}_top"]
|
border_type, border_color = rules[f"{name}_top"] # type: ignore
|
||||||
yield name, f"{border_type} {border_color.hex}"
|
yield name, f"{border_type} {border_color.hex}"
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check for edges
|
# Check for edges
|
||||||
if has_top:
|
if has_top:
|
||||||
border_type, border_color = rules[f"{name}_top"]
|
border_type, border_color = rules[f"{name}_top"] # type: ignore
|
||||||
yield f"{name}-top", f"{border_type} {border_color.hex}"
|
yield f"{name}-top", f"{border_type} {border_color.hex}"
|
||||||
|
|
||||||
if has_right:
|
if has_right:
|
||||||
border_type, border_color = rules[f"{name}_right"]
|
border_type, border_color = rules[f"{name}_right"] # type: ignore
|
||||||
yield f"{name}-right", f"{border_type} {border_color.hex}"
|
yield f"{name}-right", f"{border_type} {border_color.hex}"
|
||||||
|
|
||||||
if has_bottom:
|
if has_bottom:
|
||||||
border_type, border_color = rules[f"{name}_bottom"]
|
border_type, border_color = rules[f"{name}_bottom"] # type: ignore
|
||||||
yield f"{name}-bottom", f"{border_type} {border_color.hex}"
|
yield f"{name}-bottom", f"{border_type} {border_color.hex}"
|
||||||
|
|
||||||
if has_left:
|
if has_left:
|
||||||
border_type, border_color = rules[f"{name}_left"]
|
border_type, border_color = rules[f"{name}_left"] # type: ignore
|
||||||
yield f"{name}-left", f"{border_type} {border_color.hex}"
|
yield f"{name}-left", f"{border_type} {border_color.hex}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -770,15 +770,14 @@ class Styles(StylesBase):
|
|||||||
|
|
||||||
rules = self.get_rules()
|
rules = self.get_rules()
|
||||||
get_rule = rules.get
|
get_rule = rules.get
|
||||||
has_rule = rules.__contains__
|
|
||||||
|
|
||||||
if has_rule("display"):
|
if "display" in rules:
|
||||||
append_declaration("display", rules["display"])
|
append_declaration("display", rules["display"])
|
||||||
if has_rule("visibility"):
|
if "visibility" in rules:
|
||||||
append_declaration("visibility", rules["visibility"])
|
append_declaration("visibility", rules["visibility"])
|
||||||
if has_rule("padding"):
|
if "padding" in rules:
|
||||||
append_declaration("padding", rules["padding"].css)
|
append_declaration("padding", rules["padding"].css)
|
||||||
if has_rule("margin"):
|
if "margin" in rules:
|
||||||
append_declaration("margin", rules["margin"].css)
|
append_declaration("margin", rules["margin"].css)
|
||||||
|
|
||||||
for name, rule in self._get_border_css_lines(rules, "border"):
|
for name, rule in self._get_border_css_lines(rules, "border"):
|
||||||
@@ -787,90 +786,90 @@ class Styles(StylesBase):
|
|||||||
for name, rule in self._get_border_css_lines(rules, "outline"):
|
for name, rule in self._get_border_css_lines(rules, "outline"):
|
||||||
append_declaration(name, rule)
|
append_declaration(name, rule)
|
||||||
|
|
||||||
if has_rule("offset"):
|
if "offset" in rules:
|
||||||
x, y = self.offset
|
x, y = self.offset
|
||||||
append_declaration("offset", f"{x} {y}")
|
append_declaration("offset", f"{x} {y}")
|
||||||
if has_rule("dock"):
|
if "dock" in rules:
|
||||||
append_declaration("dock", rules["dock"])
|
append_declaration("dock", rules["dock"])
|
||||||
if has_rule("layers"):
|
if "layers" in rules:
|
||||||
append_declaration("layers", " ".join(self.layers))
|
append_declaration("layers", " ".join(self.layers))
|
||||||
if has_rule("layer"):
|
if "layer" in rules:
|
||||||
append_declaration("layer", self.layer)
|
append_declaration("layer", self.layer)
|
||||||
if has_rule("layout"):
|
if "layout" in rules:
|
||||||
assert self.layout is not None
|
assert self.layout is not None
|
||||||
append_declaration("layout", self.layout.name)
|
append_declaration("layout", self.layout.name)
|
||||||
|
|
||||||
if has_rule("color"):
|
if "color" in rules:
|
||||||
append_declaration("color", self.color.hex)
|
append_declaration("color", self.color.hex)
|
||||||
if has_rule("background"):
|
if "background" in rules:
|
||||||
append_declaration("background", self.background.hex)
|
append_declaration("background", self.background.hex)
|
||||||
if has_rule("text_style"):
|
if "text_style" in rules:
|
||||||
append_declaration("text-style", str(get_rule("text_style")))
|
append_declaration("text-style", str(get_rule("text_style")))
|
||||||
if has_rule("tint"):
|
if "tint" in rules:
|
||||||
append_declaration("tint", self.tint.css)
|
append_declaration("tint", self.tint.css)
|
||||||
|
|
||||||
if has_rule("overflow_x"):
|
if "overflow_x" in rules:
|
||||||
append_declaration("overflow-x", self.overflow_x)
|
append_declaration("overflow-x", self.overflow_x)
|
||||||
if has_rule("overflow_y"):
|
if "overflow_y" in rules:
|
||||||
append_declaration("overflow-y", self.overflow_y)
|
append_declaration("overflow-y", self.overflow_y)
|
||||||
|
|
||||||
if has_rule("scrollbar_color"):
|
if "scrollbar_color" in rules:
|
||||||
append_declaration("scrollbar-color", self.scrollbar_color.css)
|
append_declaration("scrollbar-color", self.scrollbar_color.css)
|
||||||
if has_rule("scrollbar_color_hover"):
|
if "scrollbar_color_hover" in rules:
|
||||||
append_declaration("scrollbar-color-hover", self.scrollbar_color_hover.css)
|
append_declaration("scrollbar-color-hover", self.scrollbar_color_hover.css)
|
||||||
if has_rule("scrollbar_color_active"):
|
if "scrollbar_color_active" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"scrollbar-color-active", self.scrollbar_color_active.css
|
"scrollbar-color-active", self.scrollbar_color_active.css
|
||||||
)
|
)
|
||||||
|
|
||||||
if has_rule("scrollbar_corner_color"):
|
if "scrollbar_corner_color" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"scrollbar-corner-color", self.scrollbar_corner_color.css
|
"scrollbar-corner-color", self.scrollbar_corner_color.css
|
||||||
)
|
)
|
||||||
|
|
||||||
if has_rule("scrollbar_background"):
|
if "scrollbar_background" in rules:
|
||||||
append_declaration("scrollbar-background", self.scrollbar_background.css)
|
append_declaration("scrollbar-background", self.scrollbar_background.css)
|
||||||
if has_rule("scrollbar_background_hover"):
|
if "scrollbar_background_hover" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"scrollbar-background-hover", self.scrollbar_background_hover.css
|
"scrollbar-background-hover", self.scrollbar_background_hover.css
|
||||||
)
|
)
|
||||||
if has_rule("scrollbar_background_active"):
|
if "scrollbar_background_active" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"scrollbar-background-active", self.scrollbar_background_active.css
|
"scrollbar-background-active", self.scrollbar_background_active.css
|
||||||
)
|
)
|
||||||
|
|
||||||
if has_rule("scrollbar_gutter"):
|
if "scrollbar_gutter" in rules:
|
||||||
append_declaration("scrollbar-gutter", self.scrollbar_gutter)
|
append_declaration("scrollbar-gutter", self.scrollbar_gutter)
|
||||||
if has_rule("scrollbar_size"):
|
if "scrollbar_size" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"scrollbar-size",
|
"scrollbar-size",
|
||||||
f"{self.scrollbar_size_horizontal} {self.scrollbar_size_vertical}",
|
f"{self.scrollbar_size_horizontal} {self.scrollbar_size_vertical}",
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if has_rule("scrollbar_size_horizontal"):
|
if "scrollbar_size_horizontal" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"scrollbar-size-horizontal", str(self.scrollbar_size_horizontal)
|
"scrollbar-size-horizontal", str(self.scrollbar_size_horizontal)
|
||||||
)
|
)
|
||||||
if has_rule("scrollbar_size_vertical"):
|
if "scrollbar_size_vertical" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"scrollbar-size-vertical", str(self.scrollbar_size_vertical)
|
"scrollbar-size-vertical", str(self.scrollbar_size_vertical)
|
||||||
)
|
)
|
||||||
|
|
||||||
if has_rule("box_sizing"):
|
if "box_sizing" in rules:
|
||||||
append_declaration("box-sizing", self.box_sizing)
|
append_declaration("box-sizing", self.box_sizing)
|
||||||
if has_rule("width"):
|
if "width" in rules:
|
||||||
append_declaration("width", str(self.width))
|
append_declaration("width", str(self.width))
|
||||||
if has_rule("height"):
|
if "height" in rules:
|
||||||
append_declaration("height", str(self.height))
|
append_declaration("height", str(self.height))
|
||||||
if has_rule("min_width"):
|
if "min_width" in rules:
|
||||||
append_declaration("min-width", str(self.min_width))
|
append_declaration("min-width", str(self.min_width))
|
||||||
if has_rule("min_height"):
|
if "min_height" in rules:
|
||||||
append_declaration("min-height", str(self.min_height))
|
append_declaration("min-height", str(self.min_height))
|
||||||
if has_rule("max_width"):
|
if "max_width" in rules:
|
||||||
append_declaration("max-width", str(self.min_width))
|
append_declaration("max-width", str(self.min_width))
|
||||||
if has_rule("max_height"):
|
if "max_height" in rules:
|
||||||
append_declaration("max-height", str(self.min_height))
|
append_declaration("max-height", str(self.min_height))
|
||||||
if has_rule("transitions"):
|
if "transitions" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"transition",
|
"transition",
|
||||||
", ".join(
|
", ".join(
|
||||||
@@ -879,74 +878,74 @@ class Styles(StylesBase):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
if has_rule("align_horizontal") and has_rule("align_vertical"):
|
if "align_horizontal" in rules and "align_vertical" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"align", f"{self.align_horizontal} {self.align_vertical}"
|
"align", f"{self.align_horizontal} {self.align_vertical}"
|
||||||
)
|
)
|
||||||
elif has_rule("align_horizontal"):
|
elif "align_horizontal" in rules:
|
||||||
append_declaration("align-horizontal", self.align_horizontal)
|
append_declaration("align-horizontal", self.align_horizontal)
|
||||||
elif has_rule("align_vertical"):
|
elif "align_vertical" in rules:
|
||||||
append_declaration("align-vertical", self.align_vertical)
|
append_declaration("align-vertical", self.align_vertical)
|
||||||
|
|
||||||
if has_rule("content_align_horizontal") and has_rule("content_align_vertical"):
|
if "content_align_horizontal" in rules and "content_align_vertical" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"content-align",
|
"content-align",
|
||||||
f"{self.content_align_horizontal} {self.content_align_vertical}",
|
f"{self.content_align_horizontal} {self.content_align_vertical}",
|
||||||
)
|
)
|
||||||
elif has_rule("content_align_horizontal"):
|
elif "content_align_horizontal" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"content-align-horizontal", self.content_align_horizontal
|
"content-align-horizontal", self.content_align_horizontal
|
||||||
)
|
)
|
||||||
elif has_rule("content_align_vertical"):
|
elif "content_align_vertical" in rules:
|
||||||
append_declaration("content-align-vertical", self.content_align_vertical)
|
append_declaration("content-align-vertical", self.content_align_vertical)
|
||||||
|
|
||||||
if has_rule("text_align"):
|
if "text_align" in rules:
|
||||||
append_declaration("text-align", self.text_align)
|
append_declaration("text-align", self.text_align)
|
||||||
|
|
||||||
if has_rule("opacity"):
|
if "opacity" in rules:
|
||||||
append_declaration("opacity", str(self.opacity))
|
append_declaration("opacity", str(self.opacity))
|
||||||
if has_rule("text_opacity"):
|
if "text_opacity" in rules:
|
||||||
append_declaration("text-opacity", str(self.text_opacity))
|
append_declaration("text-opacity", str(self.text_opacity))
|
||||||
|
|
||||||
if has_rule("grid_columns"):
|
if "grid_columns" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"grid-columns",
|
"grid-columns",
|
||||||
" ".join(str(scalar) for scalar in self.grid_columns or ()),
|
" ".join(str(scalar) for scalar in self.grid_columns or ()),
|
||||||
)
|
)
|
||||||
if has_rule("grid_rows"):
|
if "grid_rows" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"grid-rows",
|
"grid-rows",
|
||||||
" ".join(str(scalar) for scalar in self.grid_rows or ()),
|
" ".join(str(scalar) for scalar in self.grid_rows or ()),
|
||||||
)
|
)
|
||||||
if has_rule("grid_size_columns"):
|
if "grid_size_columns" in rules:
|
||||||
append_declaration("grid-size-columns", str(self.grid_size_columns))
|
append_declaration("grid-size-columns", str(self.grid_size_columns))
|
||||||
if has_rule("grid_size_rows"):
|
if "grid_size_rows" in rules:
|
||||||
append_declaration("grid-size-rows", str(self.grid_size_rows))
|
append_declaration("grid-size-rows", str(self.grid_size_rows))
|
||||||
|
|
||||||
if has_rule("grid_gutter_horizontal"):
|
if "grid_gutter_horizontal" in rules:
|
||||||
append_declaration(
|
append_declaration(
|
||||||
"grid-gutter-horizontal", str(self.grid_gutter_horizontal)
|
"grid-gutter-horizontal", str(self.grid_gutter_horizontal)
|
||||||
)
|
)
|
||||||
if has_rule("grid_gutter_vertical"):
|
if "grid_gutter_vertical" in rules:
|
||||||
append_declaration("grid-gutter-vertical", str(self.grid_gutter_vertical))
|
append_declaration("grid-gutter-vertical", str(self.grid_gutter_vertical))
|
||||||
|
|
||||||
if has_rule("row_span"):
|
if "row_span" in rules:
|
||||||
append_declaration("row-span", str(self.row_span))
|
append_declaration("row-span", str(self.row_span))
|
||||||
if has_rule("column_span"):
|
if "column_span" in rules:
|
||||||
append_declaration("column-span", str(self.column_span))
|
append_declaration("column-span", str(self.column_span))
|
||||||
|
|
||||||
if has_rule("link_color"):
|
if "link_color" in rules:
|
||||||
append_declaration("link-color", self.link_color.css)
|
append_declaration("link-color", self.link_color.css)
|
||||||
if has_rule("link_background"):
|
if "link_background" in rules:
|
||||||
append_declaration("link-background", self.link_background.css)
|
append_declaration("link-background", self.link_background.css)
|
||||||
if has_rule("link_style"):
|
if "link_style" in rules:
|
||||||
append_declaration("link-style", str(self.link_style))
|
append_declaration("link-style", str(self.link_style))
|
||||||
|
|
||||||
if has_rule("link_hover_color"):
|
if "link_hover_color" in rules:
|
||||||
append_declaration("link-hover-color", self.link_hover_color.css)
|
append_declaration("link-hover-color", self.link_hover_color.css)
|
||||||
if has_rule("link_hover_background"):
|
if "link_hover_background" in rules:
|
||||||
append_declaration("link-hover-background", self.link_hover_background.css)
|
append_declaration("link-hover-background", self.link_hover_background.css)
|
||||||
if has_rule("link_hover_style"):
|
if "link_hover_style" in rules:
|
||||||
append_declaration("link-hover-style", str(self.link_hover_style))
|
append_declaration("link-hover-style", str(self.link_hover_style))
|
||||||
|
|
||||||
lines.sort()
|
lines.sort()
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import os
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
from pathlib import Path, PurePath
|
from pathlib import Path, PurePath
|
||||||
from typing import Iterable, NamedTuple, cast
|
from typing import Iterable, NamedTuple, Sequence, cast
|
||||||
|
|
||||||
import rich.repr
|
import rich.repr
|
||||||
from rich.console import Console, ConsoleOptions, RenderableType, RenderResult
|
from rich.console import Console, ConsoleOptions, RenderableType, RenderResult
|
||||||
@@ -248,7 +248,7 @@ class Stylesheet:
|
|||||||
self.source[str(path)] = CssSource(css, False, 0)
|
self.source[str(path)] = CssSource(css, False, 0)
|
||||||
self._require_parse = True
|
self._require_parse = True
|
||||||
|
|
||||||
def read_all(self, paths: list[PurePath]) -> None:
|
def read_all(self, paths: Sequence[PurePath]) -> None:
|
||||||
"""Read multiple CSS files, in order.
|
"""Read multiple CSS files, in order.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
|||||||
@@ -132,10 +132,12 @@ class DOMNode(MessagePump):
|
|||||||
check_identifiers("class name", *_classes)
|
check_identifiers("class name", *_classes)
|
||||||
self._classes.update(_classes)
|
self._classes.update(_classes)
|
||||||
|
|
||||||
self.children = NodeList()
|
self.children: NodeList = NodeList()
|
||||||
self._css_styles: Styles = Styles(self)
|
self._css_styles: Styles = Styles(self)
|
||||||
self._inline_styles: Styles = Styles(self)
|
self._inline_styles: Styles = Styles(self)
|
||||||
self.styles = RenderStyles(self, self._css_styles, self._inline_styles)
|
self.styles: RenderStyles = RenderStyles(
|
||||||
|
self, self._css_styles, self._inline_styles
|
||||||
|
)
|
||||||
# A mapping of class names to Styles set in COMPONENT_CLASSES
|
# A mapping of class names to Styles set in COMPONENT_CLASSES
|
||||||
self._component_styles: dict[str, RenderStyles] = {}
|
self._component_styles: dict[str, RenderStyles] = {}
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ from ctypes import Structure, Union, byref, wintypes
|
|||||||
from ctypes.wintypes import BOOL, CHAR, DWORD, HANDLE, SHORT, UINT, WCHAR, WORD
|
from ctypes.wintypes import BOOL, CHAR, DWORD, HANDLE, SHORT, UINT, WCHAR, WORD
|
||||||
from typing import IO, Callable, List, Optional
|
from typing import IO, Callable, List, Optional
|
||||||
|
|
||||||
from .._types import EventTarget
|
from .._types import MessageTarget
|
||||||
from .._xterm_parser import XTermParser
|
from .._xterm_parser import XTermParser
|
||||||
from ..events import Event, Resize
|
from ..events import Event, Resize
|
||||||
from ..geometry import Size
|
from ..geometry import Size
|
||||||
|
|
||||||
KERNEL32 = ctypes.WinDLL("kernel32", use_last_error=True)
|
KERNEL32 = ctypes.WinDLL("kernel32", use_last_error=True) # type: ignore
|
||||||
|
|
||||||
# Console input modes
|
# Console input modes
|
||||||
ENABLE_ECHO_INPUT = 0x0004
|
ENABLE_ECHO_INPUT = 0x0004
|
||||||
@@ -130,7 +130,7 @@ def _set_console_mode(file: IO, mode: int) -> bool:
|
|||||||
Returns:
|
Returns:
|
||||||
True on success, otherwise False.
|
True on success, otherwise False.
|
||||||
"""
|
"""
|
||||||
windows_filehandle = msvcrt.get_osfhandle(file.fileno())
|
windows_filehandle = msvcrt.get_osfhandle(file.fileno()) # type: ignore
|
||||||
success = KERNEL32.SetConsoleMode(windows_filehandle, mode)
|
success = KERNEL32.SetConsoleMode(windows_filehandle, mode)
|
||||||
return success
|
return success
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ def _get_console_mode(file: IO) -> int:
|
|||||||
Returns:
|
Returns:
|
||||||
The current console mode.
|
The current console mode.
|
||||||
"""
|
"""
|
||||||
windows_filehandle = msvcrt.get_osfhandle(file.fileno())
|
windows_filehandle = msvcrt.get_osfhandle(file.fileno()) # type: ignore
|
||||||
mode = wintypes.DWORD()
|
mode = wintypes.DWORD()
|
||||||
KERNEL32.GetConsoleMode(windows_filehandle, ctypes.byref(mode))
|
KERNEL32.GetConsoleMode(windows_filehandle, ctypes.byref(mode))
|
||||||
return mode.value
|
return mode.value
|
||||||
@@ -211,7 +211,7 @@ class EventMonitor(threading.Thread):
|
|||||||
self,
|
self,
|
||||||
loop: AbstractEventLoop,
|
loop: AbstractEventLoop,
|
||||||
app,
|
app,
|
||||||
target: EventTarget,
|
target: MessageTarget,
|
||||||
exit_event: threading.Event,
|
exit_event: threading.Event,
|
||||||
process_event: Callable[[Event], None],
|
process_event: Callable[[Event], None],
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
from pathlib import PurePath
|
from pathlib import PurePath
|
||||||
from typing import Callable
|
from typing import Callable, Sequence
|
||||||
|
|
||||||
import rich.repr
|
import rich.repr
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ from ._callback import invoke
|
|||||||
class FileMonitor:
|
class FileMonitor:
|
||||||
"""Monitors files for changes and invokes a callback when it does."""
|
"""Monitors files for changes and invokes a callback when it does."""
|
||||||
|
|
||||||
def __init__(self, paths: list[PurePath], callback: Callable) -> None:
|
def __init__(self, paths: Sequence[PurePath], callback: Callable) -> None:
|
||||||
self.paths = paths
|
self.paths = paths
|
||||||
self.callback = callback
|
self.callback = callback
|
||||||
self._modified = self._get_last_modified_time()
|
self._modified = self._get_last_modified_time()
|
||||||
|
|||||||
@@ -30,14 +30,14 @@ class ScrollView(Widget):
|
|||||||
"""Not transparent, i.e. renders something."""
|
"""Not transparent, i.e. renders something."""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def watch_scroll_x(self, new_value: float) -> None:
|
def watch_scroll_x(self, old_value: float, new_value: float) -> None:
|
||||||
if self.show_horizontal_scrollbar:
|
if self.show_horizontal_scrollbar and round(old_value) != round(new_value):
|
||||||
self.horizontal_scrollbar.position = int(new_value)
|
self.horizontal_scrollbar.position = round(new_value)
|
||||||
self.refresh()
|
self.refresh()
|
||||||
|
|
||||||
def watch_scroll_y(self, new_value: float) -> None:
|
def watch_scroll_y(self, old_value: float, new_value: float) -> None:
|
||||||
if self.show_vertical_scrollbar:
|
if self.show_vertical_scrollbar and round(old_value) != round(new_value):
|
||||||
self.vertical_scrollbar.position = int(new_value)
|
self.vertical_scrollbar.position = round(new_value)
|
||||||
self.refresh()
|
self.refresh()
|
||||||
|
|
||||||
def on_mount(self):
|
def on_mount(self):
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ class _Styled:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, renderable: "RenderableType", style: Style, link_style: Style | None
|
self, renderable: "ConsoleRenderable", style: Style, link_style: Style | None
|
||||||
) -> None:
|
) -> None:
|
||||||
self.renderable = renderable
|
self.renderable = renderable
|
||||||
self.style = style
|
self.style = style
|
||||||
@@ -133,7 +133,7 @@ class _Styled:
|
|||||||
if style:
|
if style:
|
||||||
apply = style.__add__
|
apply = style.__add__
|
||||||
result_segments = (
|
result_segments = (
|
||||||
_Segment(text, apply(_style), control)
|
_Segment(text, apply(_style), None)
|
||||||
for text, _style, control in result_segments
|
for text, _style, control in result_segments
|
||||||
)
|
)
|
||||||
link_style = self.link_style
|
link_style = self.link_style
|
||||||
@@ -141,19 +141,22 @@ class _Styled:
|
|||||||
result_segments = (
|
result_segments = (
|
||||||
_Segment(
|
_Segment(
|
||||||
text,
|
text,
|
||||||
style
|
(
|
||||||
if style._meta is None
|
style
|
||||||
else (style + link_style if "@click" in style.meta else style),
|
if style._meta is None
|
||||||
|
else (style + link_style if "@click" in style.meta else style)
|
||||||
|
),
|
||||||
control,
|
control,
|
||||||
)
|
)
|
||||||
for text, style, control in result_segments
|
for text, style, control in result_segments
|
||||||
|
if style is not None
|
||||||
)
|
)
|
||||||
return result_segments
|
return result_segments
|
||||||
|
|
||||||
def __rich_measure__(
|
def __rich_measure__(
|
||||||
self, console: "Console", options: "ConsoleOptions"
|
self, console: "Console", options: "ConsoleOptions"
|
||||||
) -> Measurement:
|
) -> Measurement:
|
||||||
return self.renderable.__rich_measure__(console, options)
|
return Measurement.get(console, options, self.renderable)
|
||||||
|
|
||||||
|
|
||||||
class RenderCache(NamedTuple):
|
class RenderCache(NamedTuple):
|
||||||
@@ -1414,6 +1417,7 @@ class Widget(DOMNode):
|
|||||||
easing = DEFAULT_SCROLL_EASING
|
easing = DEFAULT_SCROLL_EASING
|
||||||
|
|
||||||
if maybe_scroll_x:
|
if maybe_scroll_x:
|
||||||
|
assert x is not None
|
||||||
self.scroll_target_x = x
|
self.scroll_target_x = x
|
||||||
if x != self.scroll_x:
|
if x != self.scroll_x:
|
||||||
self.animate(
|
self.animate(
|
||||||
@@ -1425,6 +1429,7 @@ class Widget(DOMNode):
|
|||||||
)
|
)
|
||||||
scrolled_x = True
|
scrolled_x = True
|
||||||
if maybe_scroll_y:
|
if maybe_scroll_y:
|
||||||
|
assert y is not None
|
||||||
self.scroll_target_y = y
|
self.scroll_target_y = y
|
||||||
if y != self.scroll_y:
|
if y != self.scroll_y:
|
||||||
self.animate(
|
self.animate(
|
||||||
@@ -1438,10 +1443,12 @@ class Widget(DOMNode):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
if maybe_scroll_x:
|
if maybe_scroll_x:
|
||||||
|
assert x is not None
|
||||||
scroll_x = self.scroll_x
|
scroll_x = self.scroll_x
|
||||||
self.scroll_target_x = self.scroll_x = x
|
self.scroll_target_x = self.scroll_x = x
|
||||||
scrolled_x = scroll_x != self.scroll_x
|
scrolled_x = scroll_x != self.scroll_x
|
||||||
if maybe_scroll_y:
|
if maybe_scroll_y:
|
||||||
|
assert y is not None
|
||||||
scroll_y = self.scroll_y
|
scroll_y = self.scroll_y
|
||||||
self.scroll_target_y = self.scroll_y = y
|
self.scroll_target_y = self.scroll_y = y
|
||||||
scrolled_y = scroll_y != self.scroll_y
|
scrolled_y = scroll_y != self.scroll_y
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import TYPE_CHECKING, ClassVar, Generic, NewType, TypeVar
|
from typing import TYPE_CHECKING, ClassVar, Generic, Iterable, NewType, TypeVar, cast
|
||||||
|
|
||||||
import rich.repr
|
import rich.repr
|
||||||
from rich.style import NULL_STYLE, Style
|
from rich.style import NULL_STYLE, Style
|
||||||
@@ -783,7 +783,7 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True):
|
|||||||
assert self._tree_lines_cached is not None
|
assert self._tree_lines_cached is not None
|
||||||
return self._tree_lines_cached
|
return self._tree_lines_cached
|
||||||
|
|
||||||
def _on_idle(self) -> None:
|
async def _on_idle(self, event: events.Idle) -> None:
|
||||||
"""Check tree needs a rebuild on idle."""
|
"""Check tree needs a rebuild on idle."""
|
||||||
# Property calls build if required
|
# Property calls build if required
|
||||||
self._tree_lines
|
self._tree_lines
|
||||||
@@ -891,6 +891,7 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True):
|
|||||||
Returns:
|
Returns:
|
||||||
Strings for space, vertical, terminator and cross.
|
Strings for space, vertical, terminator and cross.
|
||||||
"""
|
"""
|
||||||
|
lines: tuple[Iterable[str], Iterable[str], Iterable[str], Iterable[str]]
|
||||||
if self.show_guides:
|
if self.show_guides:
|
||||||
lines = self.LINES["default"]
|
lines = self.LINES["default"]
|
||||||
if style.bold:
|
if style.bold:
|
||||||
@@ -901,11 +902,11 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True):
|
|||||||
lines = (" ", " ", " ", " ")
|
lines = (" ", " ", " ", " ")
|
||||||
|
|
||||||
guide_depth = max(0, self.guide_depth - 2)
|
guide_depth = max(0, self.guide_depth - 2)
|
||||||
lines = tuple(
|
guide_lines = tuple(
|
||||||
f"{vertical}{horizontal * guide_depth} "
|
f"{characters[0]}{characters[1] * guide_depth} "
|
||||||
for vertical, horizontal in lines
|
for characters in lines
|
||||||
)
|
)
|
||||||
return lines
|
return cast("tuple[str, str, str, str]", guide_lines)
|
||||||
|
|
||||||
if is_hover:
|
if is_hover:
|
||||||
line_style = self.get_component_rich_style("tree--highlight-line")
|
line_style = self.get_component_rich_style("tree--highlight-line")
|
||||||
|
|||||||
Reference in New Issue
Block a user