mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
App > View {
|
App > View {
|
||||||
docks: side=left/1;
|
docks: side=left/1;
|
||||||
|
text: on #20639b;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget:hover {
|
Widget:hover {
|
||||||
@@ -28,6 +29,10 @@ Widget:hover {
|
|||||||
border: hkey;
|
border: hkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#header.-visible {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
#content {
|
#content {
|
||||||
text: white on #20639b;
|
text: white on #20639b;
|
||||||
border-bottom: hkey #0f2b41;
|
border-bottom: hkey #0f2b41;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ class BasicApp(App):
|
|||||||
def on_load(self):
|
def on_load(self):
|
||||||
"""Bind keys here."""
|
"""Bind keys here."""
|
||||||
self.bind("tab", "toggle_class('#sidebar', '-active')")
|
self.bind("tab", "toggle_class('#sidebar', '-active')")
|
||||||
|
self.bind("a", "toggle_class('#header', '-visible')")
|
||||||
|
|
||||||
def on_mount(self):
|
def on_mount(self):
|
||||||
"""Build layout here."""
|
"""Build layout here."""
|
||||||
|
|||||||
32
src/textual/blank.py
Normal file
32
src/textual/blank.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from rich.console import Console, ConsoleOptions
|
||||||
|
from rich.segment import Segment
|
||||||
|
from rich.style import StyleType
|
||||||
|
|
||||||
|
|
||||||
|
class Blank:
|
||||||
|
"""
|
||||||
|
Render an empty rectangle.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
style (StyleType): Style to apply to the box.
|
||||||
|
width (int, optional): Width of the box in number of cells. Will expand to fit parent if ``None``.
|
||||||
|
height (int, optional): Height of the box in number of cells. Will expand to fit parent if ``None``.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, style: StyleType, width: int | None = None, height: int | None = None
|
||||||
|
):
|
||||||
|
self.style = style
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
|
||||||
|
def __rich_console__(self, console: Console, console_options: ConsoleOptions):
|
||||||
|
render_width = self.width or console_options.max_width
|
||||||
|
render_height = (
|
||||||
|
self.height or console_options.height or console_options.max_height
|
||||||
|
)
|
||||||
|
style = console.get_style(self.style)
|
||||||
|
for _ in range(render_height):
|
||||||
|
yield Segment(" " * render_width + "\n", style)
|
||||||
@@ -235,6 +235,13 @@ class Styles:
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def reset(self) -> None:
|
||||||
|
"""
|
||||||
|
Reset internal style rules to ``None``, reverting to default styles.
|
||||||
|
"""
|
||||||
|
for rule_name in INTERNAL_RULE_NAMES:
|
||||||
|
setattr(self, rule_name, None)
|
||||||
|
|
||||||
def extract_rules(
|
def extract_rules(
|
||||||
self, specificity: Specificity3
|
self, specificity: Specificity3
|
||||||
) -> list[tuple[str, Specificity4, Any]]:
|
) -> list[tuple[str, Specificity4, Any]]:
|
||||||
|
|||||||
@@ -113,8 +113,14 @@ class Stylesheet:
|
|||||||
rule_attributes = defaultdict(list)
|
rule_attributes = defaultdict(list)
|
||||||
|
|
||||||
_check_rule = self._check_rule
|
_check_rule = self._check_rule
|
||||||
|
|
||||||
|
node.styles.reset()
|
||||||
|
|
||||||
|
# Get the default node CSS rules
|
||||||
for key, default_specificity, value in node._default_rules:
|
for key, default_specificity, value in node._default_rules:
|
||||||
rule_attributes[key].append((default_specificity, value))
|
rule_attributes[key].append((default_specificity, value))
|
||||||
|
|
||||||
|
# Apply styles on top of the default node CSS rules
|
||||||
for rule in self.rules:
|
for rule in self.rules:
|
||||||
for specificity in _check_rule(rule, node):
|
for specificity in _check_rule(rule, node):
|
||||||
for key, rule_specificity, value in rule.styles.extract_rules(
|
for key, rule_specificity, value in rule.styles.extract_rules(
|
||||||
@@ -123,13 +129,6 @@ class Stylesheet:
|
|||||||
rule_attributes[key].append((rule_specificity, value))
|
rule_attributes[key].append((rule_specificity, value))
|
||||||
|
|
||||||
get_first_item = itemgetter(0)
|
get_first_item = itemgetter(0)
|
||||||
|
|
||||||
log("")
|
|
||||||
log(node)
|
|
||||||
for key, attributes in rule_attributes.items():
|
|
||||||
log(key, key in node.styles.important)
|
|
||||||
log("\t", attributes)
|
|
||||||
|
|
||||||
node_rules = [
|
node_rules = [
|
||||||
(name, max(specificity_rules, key=get_first_item)[1])
|
(name, max(specificity_rules, key=get_first_item)[1])
|
||||||
for name, specificity_rules in rule_attributes.items()
|
for name, specificity_rules in rule_attributes.items()
|
||||||
|
|||||||
@@ -14,11 +14,13 @@ from typing import (
|
|||||||
import rich.repr
|
import rich.repr
|
||||||
from rich import box
|
from rich import box
|
||||||
from rich.align import Align
|
from rich.align import Align
|
||||||
from rich.console import Console, RenderableType
|
from rich.console import Console, RenderableType, ConsoleOptions
|
||||||
|
from rich.measure import Measurement
|
||||||
from rich.panel import Panel
|
from rich.panel import Panel
|
||||||
from rich.padding import Padding
|
from rich.padding import Padding
|
||||||
from rich.pretty import Pretty
|
from rich.pretty import Pretty
|
||||||
from rich.style import Style
|
from rich.segment import Segment
|
||||||
|
from rich.style import Style, StyleType
|
||||||
from rich.styled import Styled
|
from rich.styled import Styled
|
||||||
from rich.text import Text, TextType
|
from rich.text import Text, TextType
|
||||||
|
|
||||||
@@ -27,6 +29,7 @@ from . import errors
|
|||||||
from ._animator import BoundAnimator
|
from ._animator import BoundAnimator
|
||||||
from ._border import Border, BORDER_STYLES
|
from ._border import Border, BORDER_STYLES
|
||||||
from ._callback import invoke
|
from ._callback import invoke
|
||||||
|
from .blank import Blank
|
||||||
from .dom import DOMNode
|
from .dom import DOMNode
|
||||||
from ._context import active_app
|
from ._context import active_app
|
||||||
from .geometry import Size, Spacing, SpacingDimensions
|
from .geometry import Size, Spacing, SpacingDimensions
|
||||||
@@ -158,28 +161,36 @@ class Widget(DOMNode):
|
|||||||
|
|
||||||
renderable = self.render()
|
renderable = self.render()
|
||||||
styles = self.styles
|
styles = self.styles
|
||||||
|
|
||||||
parent_text_style = self.parent.text_style
|
parent_text_style = self.parent.text_style
|
||||||
text_style = styles.text
|
|
||||||
renderable_text_style = parent_text_style + text_style
|
|
||||||
if renderable_text_style:
|
|
||||||
renderable = Styled(renderable, renderable_text_style)
|
|
||||||
|
|
||||||
if styles.has_padding:
|
if styles.visibility == "hidden":
|
||||||
renderable = Padding(
|
renderable = Blank(parent_text_style)
|
||||||
renderable, styles.padding, style=renderable_text_style
|
else:
|
||||||
)
|
text_style = styles.text
|
||||||
|
renderable_text_style = parent_text_style + text_style
|
||||||
|
if renderable_text_style:
|
||||||
|
renderable = Styled(renderable, renderable_text_style)
|
||||||
|
|
||||||
if styles.has_border:
|
if styles.has_padding:
|
||||||
renderable = Border(renderable, styles.border, style=renderable_text_style)
|
renderable = Padding(
|
||||||
|
renderable, styles.padding, style=renderable_text_style
|
||||||
|
)
|
||||||
|
|
||||||
if styles.has_margin:
|
if styles.has_border:
|
||||||
renderable = Padding(renderable, styles.margin, style=parent_text_style)
|
renderable = Border(
|
||||||
|
renderable, styles.border, style=renderable_text_style
|
||||||
|
)
|
||||||
|
|
||||||
if styles.has_outline:
|
if styles.has_margin:
|
||||||
renderable = Border(
|
renderable = Padding(renderable, styles.margin, style=parent_text_style)
|
||||||
renderable, styles.outline, outline=True, style=renderable_text_style
|
|
||||||
)
|
if styles.has_outline:
|
||||||
|
renderable = Border(
|
||||||
|
renderable,
|
||||||
|
styles.outline,
|
||||||
|
outline=True,
|
||||||
|
style=renderable_text_style,
|
||||||
|
)
|
||||||
|
|
||||||
return renderable
|
return renderable
|
||||||
|
|
||||||
|
|||||||
11
tests/test_styles.py
Normal file
11
tests/test_styles.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from rich.style import Style
|
||||||
|
|
||||||
|
from textual.css.styles import Styles
|
||||||
|
|
||||||
|
|
||||||
|
def test_styles_reset():
|
||||||
|
styles = Styles()
|
||||||
|
styles.text_style = "not bold"
|
||||||
|
assert styles.text_style == Style(bold=False)
|
||||||
|
styles.reset()
|
||||||
|
assert styles.text_style is Style.null()
|
||||||
Reference in New Issue
Block a user