fix refresh lines

This commit is contained in:
Will McGugan
2024-02-05 21:16:26 +00:00
parent e91699f56c
commit fa8c0e8f95
8 changed files with 42 additions and 15 deletions

View File

@@ -161,10 +161,12 @@ for widget in self.query("Button"):
Here are the other loop-free methods on query objects:
- [set_class][textual.css.query.DOMQuery.set_class] Sets a CSS class (or classes) on matched widgets.
- [add_class][textual.css.query.DOMQuery.add_class] Adds a CSS class (or classes) to matched widgets.
- [remove_class][textual.css.query.DOMQuery.remove_class] Removes a CSS class (or classes) from matched widgets.
- [toggle_class][textual.css.query.DOMQuery.toggle_class] Sets a CSS class (or classes) if it is not set, or removes the class (or classes) if they are set on the matched widgets.
- [remove][textual.css.query.DOMQuery.remove] Removes matched widgets from the DOM.
- [blur][textual.css.query.DOMQuery.focus] Blurs (removes focus) from matching widgets.
- [focus][textual.css.query.DOMQuery.focus] Focuses the first matching widgets.
- [refresh][textual.css.query.DOMQuery.refresh] Refreshes matched widgets.
- [remove_class][textual.css.query.DOMQuery.remove_class] Removes a CSS class (or classes) from matched widgets.
- [remove][textual.css.query.DOMQuery.remove] Removes matched widgets from the DOM.
- [set_class][textual.css.query.DOMQuery.set_class] Sets a CSS class (or classes) on matched widgets.
- [set][textual.css.query.DOMQuery.set] Sets common attributes on a widget.
- [toggle_class][textual.css.query.DOMQuery.toggle_class] Sets a CSS class (or classes) if it is not set, or removes the class (or classes) if they are set on the matched widgets.

View File

@@ -424,8 +424,9 @@ class App(Generic[ReturnType], DOMNode):
environ = dict(os.environ)
no_color = environ.pop("NO_COLOR", None)
if no_color is not None:
from .filter import Monochrome
from .filter import ANSIToTruecolor, Monochrome
self._filters.append(ANSIToTruecolor(terminal_theme.DIMMED_MONOKAI))
self._filters.append(Monochrome())
for filter_name in constants.FILTERS.split(","):

View File

@@ -223,7 +223,7 @@ class DOMQuery(Generic[QueryType]):
)
return first
else:
raise NoMatches(f"No nodes match {self!r}")
raise NoMatches(f"No nodes match {self!r} on {self.node!r}")
@overload
def only_one(self) -> QueryType: ...
@@ -293,7 +293,7 @@ class DOMQuery(Generic[QueryType]):
The matching Widget.
"""
if not self.nodes:
raise NoMatches(f"No nodes match {self!r}")
raise NoMatches(f"No nodes match {self!r} on dom{self.node!r}")
last = self.nodes[-1]
if expect_type is not None and not isinstance(last, expect_type):
raise WrongType(

View File

@@ -290,6 +290,7 @@ class DOMNode(MessagePump):
def setter(value: object) -> None:
"""Set bound data."""
_rich_traceback_omit = True
Reactive._initialize_object(self)
setattr(self, variable_name, value)
@@ -1405,6 +1406,13 @@ class DOMNode(MessagePump):
def refresh(self, *, repaint: bool = True, layout: bool = False) -> Self:
return self
async def action_toggle(self, value_name: str) -> None:
value = getattr(self, value_name)
setattr(self, value_name, not value)
async def action_toggle(self, attribute_name: str) -> None:
"""Toggle an attribute on the node.
Assumes the attribute is a bool.
Args:
attribute_name: Name of the attribute.
"""
value = getattr(self, attribute_name)
setattr(self, attribute_name, not value)

View File

@@ -2,11 +2,13 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Iterable
from rich import terminal_theme
from rich.console import Console, ConsoleOptions, RenderResult
from rich.segment import Segment
from rich.style import Style
from ..color import Color
from ..filter import ANSIToTruecolor
if TYPE_CHECKING:
from ..screen import Screen
@@ -49,12 +51,17 @@ class BackgroundScreen:
_Segment = Segment
NULL_STYLE = Style()
truecolor_style = ANSIToTruecolor(terminal_theme.DIMMED_MONOKAI).truecolor_style
for segment in segments:
text, style, control = segment
if control:
yield segment
else:
style = NULL_STYLE if style is None else style.clear_meta_and_links()
style = (
NULL_STYLE
if style is None
else truecolor_style(style.clear_meta_and_links())
)
yield _Segment(
text,
(

View File

@@ -2,11 +2,13 @@ from __future__ import annotations
from typing import Iterable
from rich import terminal_theme
from rich.console import Console, ConsoleOptions, RenderableType, RenderResult
from rich.segment import Segment
from rich.style import Style
from ..color import Color
from ..filter import ANSIToTruecolor
class Tint:
@@ -43,13 +45,15 @@ class Tint:
style_from_color = Style.from_color
_Segment = Segment
ansi_filter = ANSIToTruecolor(terminal_theme.DIMMED_MONOKAI)
NULL_STYLE = Style()
for segment in segments:
text, style, control = segment
if control:
yield segment
else:
style = style or NULL_STYLE
style = ansi_filter.truecolor_style(style) or NULL_STYLE
yield _Segment(
text,
(

View File

@@ -152,7 +152,7 @@ class ScrollView(ScrollableContainer):
"""
width = self.virtual_size.width
scroll_x, scroll_y = self.scroll_offset
self.refresh(Region(0, y - scroll_y, width, 1))
self.refresh(Region(0, y - scroll_y, max(width, self.size.width), 1))
def refresh_lines(self, y_start: int, line_count: int = 1) -> None:
"""Refresh one or more lines.
@@ -164,5 +164,7 @@ class ScrollView(ScrollableContainer):
width = self.virtual_size.width
scroll_x, scroll_y = self.scroll_offset
refresh_region = Region(0, y_start - scroll_y, width, line_count)
refresh_region = Region(
0, y_start - scroll_y, max(width, self.size.width), line_count
)
self.refresh(refresh_region)

View File

@@ -324,6 +324,9 @@ class TabbedContent(Widget):
@property
def active_pane(self) -> TabPane | None:
"""The currently active pane, or `None` if no pane is active."""
active = self.active
if not active:
return None
return self.get_pane(self.active)
def validate_active(self, active: str) -> str: