diff --git a/examples/basic.css b/examples/basic.css index 72d825b07..f13f99b98 100644 --- a/examples/basic.css +++ b/examples/basic.css @@ -1,6 +1,6 @@ App > View { layout: dock; - docks: side=left/1 header=top footer=bottom; + docks: side=left/1; } #sidebar { @@ -16,24 +16,21 @@ App > View { #sidebar.-active { offset-x: 0; transition: offset 400ms in_out_cubic; - text: on red; } #header { text: on #173f5f; - dock: header; + height: 3; border: hkey white; } #footer { - dock: header; height: 3; border-top: hkey #0f2b41; text: #3a3009 on #f6d55c; } #content { - dock: header; text: bold on #20639b; } diff --git a/src/textual/_border.py b/src/textual/_border.py index 8395bd3d2..f81d1e23c 100644 --- a/src/textual/_border.py +++ b/src/textual/_border.py @@ -28,10 +28,12 @@ class Border: renderable: RenderableType, edge_styles: tuple[EdgeStyle, EdgeStyle, EdgeStyle, EdgeStyle], outline: bool = False, + style: StyleType = "", ): self.renderable = renderable self.edge_styles = edge_styles self.outline = outline + self.style = style ( (top, top_style), @@ -75,7 +77,13 @@ class Border: self, console: "Console", options: "ConsoleOptions" ) -> "RenderResult": top, right, bottom, left = self._sides + style = console.get_style(self.style) top_style, right_style, bottom_style, left_style = self._styles + if style: + top_style = style + top_style + right_style = style + right_style + bottom_style = style + bottom_style + left_style = style + left_style BOX = BORDER_STYLES has_left = left != "none" diff --git a/src/textual/_linux_driver.py b/src/textual/_linux_driver.py index 4010a4c38..7b846a9df 100644 --- a/src/textual/_linux_driver.py +++ b/src/textual/_linux_driver.py @@ -52,8 +52,8 @@ class LinuxDriver(Driver): write("\x1b[?1015h") # SET_VT200_HIGHLIGHT_MOUSE write("\x1b[?1006h") # SET_SGR_EXT_MODE_MOUSE - # write("\x1b[?1007h") - # self.console.file.flush() + write("\x1b[?1007h") + self.console.file.flush() # Note: E.g. lxterminal understands 1000h, but not the urxvt or sgr # extensions. @@ -64,7 +64,7 @@ class LinuxDriver(Driver): write("\x1b[?1003l") # write("\x1b[?1015l") write("\x1b[?1006l") - # self.console.file.flush() + self.console.file.flush() def start_application_mode(self): diff --git a/src/textual/app.py b/src/textual/app.py index 74f1c7455..297c1fb15 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -224,8 +224,7 @@ class App(DOMNode): asyncio.run(run_app()) async def _on_css_change(self) -> None: - self.log("CSS changed") - self.log("css_file", self.css_file) + if self.css_file is not None: stylesheet = Stylesheet() try: @@ -235,11 +234,10 @@ class App(DOMNode): self.log(error) self.console.bell() else: - self.log("reseting stylesheet") self.reset_styles() self.stylesheet = stylesheet self.stylesheet.update(self) - self.refresh(layout=True) + self.view.refresh(layout=True) def mount(self, *anon_widgets: Widget, **widgets: Widget) -> None: self.register(self.view, *anon_widgets, **widgets) diff --git a/src/textual/dom.py b/src/textual/dom.py index 68160d65e..9477d1679 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -5,6 +5,7 @@ from typing import Any, cast, Iterable, Iterator, TYPE_CHECKING from rich.highlighter import ReprHighlighter import rich.repr from rich.pretty import Pretty +from rich.style import Style from rich.tree import Tree from .css.styles import Styles @@ -50,7 +51,7 @@ class DOMNode(MessagePump): @property def parent(self) -> DOMNode: if self._parent is None: - raise NoParent(f"{self._parent} has no parent") + raise NoParent(f"{self} has no parent") assert isinstance(self._parent, DOMNode) return self._parent @@ -121,6 +122,19 @@ class DOMNode(MessagePump): node = node.parent return tuple(reversed(indexes)) + @property + def text_style(self) -> Style: + """Get the text style (added to parent style). + + Returns: + Style: Rich Style object. + """ + return ( + self.parent.text_style + self.styles.text + if self.has_parent + else self.styles.text + ) + @property def tree(self) -> Tree: highlighter = ReprHighlighter() @@ -141,7 +155,7 @@ class DOMNode(MessagePump): for node in self.walk_children(): node.styles = Styles(node=node) if isinstance(node, Widget): - node.clear_render_cache() + # node.clear_render_cache() node._repaint_required = True node._layout_required = True diff --git a/src/textual/widget.py b/src/textual/widget.py index f87a44f68..424f51265 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -65,12 +65,12 @@ class Widget(DOMNode): """ def __init__(self, name: str | None = None, id: str | None = None) -> None: - if name is None: - class_name = self.__class__.__name__ - Widget._counts.setdefault(class_name, 0) - Widget._counts[class_name] += 1 - _count = self._counts[class_name] - name = f"{class_name}{_count}" + # if name is None: + # class_name = self.__class__.__name__ + # Widget._counts.setdefault(class_name, 0) + # Widget._counts[class_name] += 1 + # _count = self._counts[class_name] + # name = f"{class_name}{_count}" self._size = Size(0, 0) self._repaint_required = False @@ -108,7 +108,10 @@ class Widget(DOMNode): def __rich_repr__(self) -> rich.repr.Result: yield "id", self.id, None - yield "name", self.name + if self.name: + yield "name", self.name + if self.classes: + yield "classes", self.classes def __rich__(self) -> RenderableType: renderable = self.render_styled() @@ -138,20 +141,27 @@ 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) + renderable = Padding( + renderable, styles.padding, style=renderable_text_style + ) if styles.has_border: - renderable = Border(renderable, styles.border) + renderable = Border(renderable, styles.border, style=renderable_text_style) if styles.has_margin: - renderable = Padding(renderable, styles.margin) + renderable = Padding(renderable, styles.margin, style=parent_text_style) if styles.has_outline: - renderable = Border(renderable, styles.outline, outline=True) - - if styles.text: - renderable = Styled(renderable, styles.text) + renderable = Border( + renderable, styles.outline, outline=True, style=parent_text_style + ) return renderable @@ -263,6 +273,7 @@ class Widget(DOMNode): elif repaint: self.clear_render_cache() self._repaint_required = True + self.log("refresh", repaint, layout) self.post_message_no_wait(events.Null(self)) def render(self) -> RenderableType: