mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
css render
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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):
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user