fix for update region

This commit is contained in:
Will McGugan
2022-11-23 23:13:58 +08:00
parent f84313dac7
commit 68d7440474
5 changed files with 52 additions and 19 deletions

View File

@@ -384,6 +384,9 @@ class Compositor:
spatial_map, arranged_widgets, spacing = widget._arrange( spatial_map, arranged_widgets, spacing = widget._arrange(
child_region.size child_region.size
) )
total_region = total_region.union(
spatial_map.total_region.grow(spacing)
)
placements = spatial_map.get_placements( placements = spatial_map.get_placements(
child_region.reset_offset.translate(widget.scroll_offset) child_region.reset_offset.translate(widget.scroll_offset)
@@ -402,16 +405,11 @@ class Compositor:
get_layer_index = layers_to_index.get get_layer_index = layers_to_index.get
# Add all the widgets # Add all the widgets
for sub_region, margin, sub_widget, z, fixed in reversed( for sub_region, _, sub_widget, z, fixed in reversed(placements):
placements
):
# Combine regions with children to calculate the "virtual size" # Combine regions with children to calculate the "virtual size"
if fixed: if fixed:
widget_region = sub_region + placement_offset widget_region = sub_region + placement_offset
else: else:
total_region = total_region.union(
sub_region.grow(spacing + margin)
)
widget_region = sub_region + placement_scroll_offset widget_region = sub_region + placement_scroll_offset
widget_order = order + ( widget_order = order + (

View File

@@ -3,10 +3,10 @@ from __future__ import annotations
from collections import defaultdict from collections import defaultdict
from itertools import product from itertools import product
from operator import attrgetter from operator import attrgetter
from typing import Iterable, Mapping, Sequence from typing import Iterable, Sequence
from ._layout import WidgetPlacement from ._layout import WidgetPlacement
from .geometry import Region from .geometry import Region, Spacing
from ._partition import partition from ._partition import partition
@@ -26,10 +26,12 @@ class SpatialMap:
def __init__( def __init__(
self, self,
placements: Sequence[WidgetPlacement], placements: Sequence[WidgetPlacement],
*,
block_width: int = 80, block_width: int = 80,
block_height: int = 80, block_height: int = 80,
) -> None: ) -> None:
self._placements = placements self._placements = placements
self._total_region = Region()
self._block_width = block_width self._block_width = block_width
self._block_height = block_height self._block_height = block_height
self._fixed: list[WidgetPlacement] = [] self._fixed: list[WidgetPlacement] = []
@@ -37,6 +39,8 @@ class SpatialMap:
self.placement_map = self._build_placements(placements) self.placement_map = self._build_placements(placements)
print("SPATIAL", len(placements))
def __iter__(self) -> Iterable[WidgetPlacement]: def __iter__(self) -> Iterable[WidgetPlacement]:
yield from self._placements yield from self._placements
@@ -57,6 +61,14 @@ class SpatialMap:
block_width = self._block_width block_width = self._block_width
block_height = self._block_height block_height = self._block_height
self.total_region = Region.from_union(
[
placement.region.grow(placement.margin)
for placement in placements
if not placement.fixed
]
)
placements, self._fixed = partition(attrgetter("fixed"), placements) placements, self._fixed = partition(attrgetter("fixed"), placements)
for placement in placements: for placement in placements:

View File

@@ -1,5 +1,7 @@
from __future__ import annotations from __future__ import annotations
from functools import lru_cache
from sys import intern
from typing import TYPE_CHECKING, Callable, Iterable, List from typing import TYPE_CHECKING, Callable, Iterable, List
from rich.segment import Segment from rich.segment import Segment
@@ -52,6 +54,20 @@ def style_links(
return segments return segments
@lru_cache(1024 * 8)
def make_blank(width, style: Style) -> Segment:
"""Make a blank segment.
Args:
width (_type_): Width of blank.
style (Style): Style of blank.
Returns:
Segment: A single segment
"""
return Segment(intern(" " * width), style)
class StylesCache: class StylesCache:
"""Responsible for rendering CSS Styles and keeping a cache of rendered lines. """Responsible for rendering CSS Styles and keeping a cache of rendered lines.
@@ -319,20 +335,20 @@ class StylesCache:
right_style = from_color(color=(background + border_right_color).rich_color) right_style = from_color(color=(background + border_right_color).rich_color)
right = get_box(border_right, inner, outer, right_style)[1][2] right = get_box(border_right, inner, outer, right_style)[1][2]
if border_left and border_right: if border_left and border_right:
line = [left, Segment(" " * (width - 2), background_style), right] line = [left, make_blank(width - 2, background_style), right]
elif border_left: elif border_left:
line = [left, Segment(" " * (width - 1), background_style)] line = [left, make_blank(width - 1, background_style)]
elif border_right: elif border_right:
line = [Segment(" " * (width - 1), background_style), right] line = [make_blank(width, background_style), right]
else: else:
line = [Segment(" " * width, background_style)] line = [make_blank(width, background_style)]
else: else:
# Content with border and padding (C) # Content with border and padding (C)
content_y = y - gutter.top content_y = y - gutter.top
if content_y < content_height: if content_y < content_height:
line = render_content_line(y - gutter.top) line = render_content_line(y - gutter.top)
else: else:
line = [Segment(" " * content_width, inner)] line = [make_blank(content_width, inner)]
if inner: if inner:
line = Segment.apply_style(line, inner) line = Segment.apply_style(line, inner)
line = line_pad(line, pad_left, pad_right, inner) line = line_pad(line, pad_left, pad_right, inner)

View File

@@ -305,7 +305,7 @@ class BoxProperty:
current_value: tuple[str, Color] = cast( current_value: tuple[str, Color] = cast(
"tuple[str, Color]", obj.get_rule(self.name) "tuple[str, Color]", obj.get_rule(self.name)
) )
has_edge = current_value and current_value[0] has_edge = bool(current_value and current_value[0])
new_edge = bool(_type) new_edge = bool(_type)
if obj.set_rule(self.name, new_value): if obj.set_rule(self.name, new_value):
obj.refresh(layout=has_edge != new_edge) obj.refresh(layout=has_edge != new_edge)

View File

@@ -594,8 +594,10 @@ class Styles(StylesBase):
Returns: Returns:
bool: ``True`` if a rule was cleared, or ``False`` if it was already not set. bool: ``True`` if a rule was cleared, or ``False`` if it was already not set.
""" """
self._updates += 1 changed = self._rules.pop(rule, None) is not None
return self._rules.pop(rule, None) is not None if changed:
self._updates += 1
return changed
def get_rules(self) -> RulesMap: def get_rules(self) -> RulesMap:
return self._rules.copy() return self._rules.copy()
@@ -610,12 +612,17 @@ class Styles(StylesBase):
Returns: Returns:
bool: ``True`` if the rule changed, otherwise ``False``. bool: ``True`` if the rule changed, otherwise ``False``.
""" """
self._updates += 1
if value is None: if value is None:
return self._rules.pop(rule, None) is not None changed = self._rules.pop(rule, None) is not None
if changed:
self._updates += 1
return changed
current = self._rules.get(rule) current = self._rules.get(rule)
self._rules[rule] = value self._rules[rule] = value
return current != value changed = current != value
if changed:
self._updates += 1
return changed
def get_rule(self, rule: str, default: object = None) -> object: def get_rule(self, rule: str, default: object = None) -> object:
return self._rules.get(rule, default) return self._rules.get(rule, default)