fix for styles

This commit is contained in:
Will McGugan
2022-02-07 11:38:43 +00:00
parent bb254bda76
commit 0d2cca9b41
7 changed files with 51 additions and 26 deletions

View File

@@ -18,7 +18,9 @@ class BasicApp(App):
sidebar=Widget(),
)
self.app.panic(repr(self.view.styles))
# # self.app.panic(self["#sidebar"].styles.has_rule("border"))
# self.app.panic(repr(self["#sidebar"]._inline_styles.border))
BasicApp.run(css_file="basic.css", watch_css=True, log="textual.log")

View File

@@ -10,7 +10,7 @@ when setting and getting.
from __future__ import annotations
from typing import Iterable, Iterator, NamedTuple, Sequence, TYPE_CHECKING
from typing import Iterable, NamedTuple, Sequence, TYPE_CHECKING
import rich.repr
from rich.color import Color
@@ -176,7 +176,7 @@ class Edges(NamedTuple):
left: tuple[BoxType, Style]
def __rich_repr__(self) -> rich.repr.Result:
_, top, right, bottom, left = self
top, right, bottom, left = self
if top[0]:
yield "top", top
if right[0]:
@@ -192,7 +192,7 @@ class Edges(NamedTuple):
Returns:
tuple[int, int, int, int]: Spacing for top, right, bottom, and left.
"""
_, top, right, bottom, left = self
top, right, bottom, left = self
return (
1 if top[0] else 0,
1 if right[0] else 0,
@@ -596,7 +596,7 @@ class NameProperty:
"""Descriptor for getting and setting name properties."""
def __set_name__(self, owner: Styles, name: str) -> None:
self._name = name
self.name = name
def __get__(self, obj: Styles, objtype: type[Styles] | None) -> str:
"""Get the name property
@@ -608,7 +608,7 @@ class NameProperty:
Returns:
str: The name
"""
return obj.get(self.name, "")
return obj._rules.get(self.name, "")
def __set__(self, obj: Styles, name: str | None):
"""Set the name property
@@ -631,7 +631,7 @@ class NameProperty:
class NameListProperty:
def __set_name__(self, owner: Styles, name: str) -> None:
self._name = name
self.name = name
def __get__(
self, obj: Styles, objtype: type[Styles] | None = None

View File

@@ -120,17 +120,32 @@ class Styles:
"""Check if a rule has been set."""
if rule in RULE_NAMES and rule in self._rules:
return True
has_rule = self._rules.__contains__
if rule == "text":
return (
has_rule("text_color")
or has_rule("text_bgcolor")
or has_rule("text_style")
return bool(
{"text_color", "text_background", "text_style"}.intersection(
self._rules.keys()
)
)
if rule == "border" and any(self.border):
return True
if rule == "border":
return bool(
{
"border_top",
"border_right",
"border_bottom",
"border_left",
}.intersection(self._rules.keys())
)
if rule == "outline" and any(self.outline):
return True
return bool(
{
"outline_top",
"outline_right",
"outline_bottom",
"outline_left",
}.intersection(self._rules.keys())
)
return False
def get_rules(self) -> RulesMap:
@@ -243,7 +258,7 @@ class Styles:
return rules
def apply_rules(self, rules: RulesMap, animate: bool = False):
if animate or self.node is None:
if not animate or self.node is None:
self._rules.update(rules)
else:
styles = self

View File

@@ -3,7 +3,7 @@ from __future__ import annotations
from collections import defaultdict
from operator import itemgetter
import os
from typing import Iterable
from typing import cast, Iterable
import rich.repr
from rich.highlighter import ReprHighlighter
@@ -16,6 +16,7 @@ from .errors import StylesheetError
from .match import _check_selectors
from .model import RuleSet
from .parse import parse
from .styles import RulesMap
from .types import Specificity3, Specificity4
from ..dom import DOMNode
from .. import log
@@ -148,10 +149,13 @@ class Stylesheet:
# For each rule declared for this node, keep only the most specific one
get_first_item = itemgetter(0)
node_rules = {
name: max(specificity_rules, key=get_first_item)[1]
for name, specificity_rules in rule_attributes.items()
}
node_rules = cast(
RulesMap,
{
name: max(specificity_rules, key=get_first_item)[1]
for name, specificity_rules in rule_attributes.items()
},
)
node._css_styles.apply_rules(node_rules)

View File

@@ -484,6 +484,9 @@ class Spacing(NamedTuple):
bottom: int = 0
left: int = 0
def __bool__(self) -> bool:
return self == (0, 0, 0, 0)
@property
def width(self) -> int:
"""Total space in width."""

View File

@@ -43,7 +43,7 @@ class View(Widget):
self.app.refresh()
@property
def layout(self) -> Layout:
def layout(self) -> Layout | None:
"""Convenience property for accessing ``self.styles.layout``.
Returns: The Layout associated with this view
@@ -87,7 +87,7 @@ class View(Widget):
return self.app.is_mounted(widget)
def render(self) -> RenderableType:
return self.layout
return self.layout or ""
def get_offset(self, widget: Widget) -> Offset:
return self.layout.get_offset(widget)

View File

@@ -154,6 +154,7 @@ class Widget(DOMNode):
"""
renderable = self.render()
styles = self.styles
parent_text_style = self.parent.text_style
@@ -163,15 +164,15 @@ class Widget(DOMNode):
if renderable_text_style:
renderable = Styled(renderable, renderable_text_style)
if any(styles.padding):
if styles.padding:
renderable = Padding(
renderable, styles.padding, style=renderable_text_style
)
if any(styles.border):
if styles.border:
renderable = Border(renderable, styles.border, style=renderable_text_style)
if any(styles.outline):
if styles.outline:
renderable = Border(
renderable,
styles.outline,