mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
@@ -2,6 +2,7 @@
|
||||
|
||||
App > View {
|
||||
docks: side=left/1;
|
||||
text: on #20639b;
|
||||
}
|
||||
|
||||
Widget:hover {
|
||||
@@ -28,6 +29,10 @@ Widget:hover {
|
||||
border: hkey;
|
||||
}
|
||||
|
||||
#header.-visible {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#content {
|
||||
text: white on #20639b;
|
||||
border-bottom: hkey #0f2b41;
|
||||
|
||||
@@ -8,6 +8,7 @@ class BasicApp(App):
|
||||
def on_load(self):
|
||||
"""Bind keys here."""
|
||||
self.bind("tab", "toggle_class('#sidebar', '-active')")
|
||||
self.bind("a", "toggle_class('#header', '-visible')")
|
||||
|
||||
def on_mount(self):
|
||||
"""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:
|
||||
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(
|
||||
self, specificity: Specificity3
|
||||
) -> list[tuple[str, Specificity4, Any]]:
|
||||
|
||||
@@ -113,8 +113,14 @@ class Stylesheet:
|
||||
rule_attributes = defaultdict(list)
|
||||
|
||||
_check_rule = self._check_rule
|
||||
|
||||
node.styles.reset()
|
||||
|
||||
# Get the default node CSS rules
|
||||
for key, default_specificity, value in node._default_rules:
|
||||
rule_attributes[key].append((default_specificity, value))
|
||||
|
||||
# Apply styles on top of the default node CSS rules
|
||||
for rule in self.rules:
|
||||
for specificity in _check_rule(rule, node):
|
||||
for key, rule_specificity, value in rule.styles.extract_rules(
|
||||
@@ -123,13 +129,6 @@ class Stylesheet:
|
||||
rule_attributes[key].append((rule_specificity, value))
|
||||
|
||||
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 = [
|
||||
(name, max(specificity_rules, key=get_first_item)[1])
|
||||
for name, specificity_rules in rule_attributes.items()
|
||||
|
||||
@@ -14,11 +14,13 @@ from typing import (
|
||||
import rich.repr
|
||||
from rich import box
|
||||
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.padding import Padding
|
||||
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.text import Text, TextType
|
||||
|
||||
@@ -27,6 +29,7 @@ from . import errors
|
||||
from ._animator import BoundAnimator
|
||||
from ._border import Border, BORDER_STYLES
|
||||
from ._callback import invoke
|
||||
from .blank import Blank
|
||||
from .dom import DOMNode
|
||||
from ._context import active_app
|
||||
from .geometry import Size, Spacing, SpacingDimensions
|
||||
@@ -158,28 +161,36 @@ class Widget(DOMNode):
|
||||
|
||||
renderable = self.render()
|
||||
styles = self.styles
|
||||
|
||||
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:
|
||||
renderable = Padding(
|
||||
renderable, styles.padding, style=renderable_text_style
|
||||
)
|
||||
if styles.visibility == "hidden":
|
||||
renderable = Blank(parent_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:
|
||||
renderable = Border(renderable, styles.border, style=renderable_text_style)
|
||||
if styles.has_padding:
|
||||
renderable = Padding(
|
||||
renderable, styles.padding, style=renderable_text_style
|
||||
)
|
||||
|
||||
if styles.has_margin:
|
||||
renderable = Padding(renderable, styles.margin, style=parent_text_style)
|
||||
if styles.has_border:
|
||||
renderable = Border(
|
||||
renderable, styles.border, style=renderable_text_style
|
||||
)
|
||||
|
||||
if styles.has_outline:
|
||||
renderable = Border(
|
||||
renderable, styles.outline, outline=True, style=renderable_text_style
|
||||
)
|
||||
if styles.has_margin:
|
||||
renderable = Padding(renderable, styles.margin, style=parent_text_style)
|
||||
|
||||
if styles.has_outline:
|
||||
renderable = Border(
|
||||
renderable,
|
||||
styles.outline,
|
||||
outline=True,
|
||||
style=renderable_text_style,
|
||||
)
|
||||
|
||||
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