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