detect invisible updates

This commit is contained in:
Will McGugan
2022-03-08 11:44:43 +00:00
parent 0a33ebed30
commit 2b08484932
6 changed files with 61 additions and 22 deletions

View File

@@ -1,11 +1,13 @@
#uber1 {
/* border: heavy green; */
layout: vertical;
layout: horizontal;
text: on green;
}
.list-item {
height: 8;
/* height: 8; */
margin: 1 2;
}

View File

@@ -3,7 +3,7 @@ from __future__ import annotations
from itertools import chain
from operator import attrgetter, itemgetter
import sys
from typing import Iterator, Iterable, NamedTuple, TYPE_CHECKING
from typing import cast, Callable, Iterator, Iterable, NamedTuple, TYPE_CHECKING
import rich.repr
from rich.console import Console, ConsoleOptions, RenderResult
@@ -207,6 +207,10 @@ class Compositor:
placements, arranged_widgets = widget.layout.arrange(
widget, region.size, scroll
)
for placement in placements:
log(placement=placement)
log(arranged=arranged_widgets)
widgets.update(arranged_widgets)
placements = sorted(placements, key=attrgetter("order"))
@@ -222,8 +226,8 @@ class Compositor:
return total_region.size
virtual_size = add_widget(root, size.region, (), size.region)
for widget, placement in map.items():
log("*", widget, placement)
# for widget, placement in map.items():
# log("*", widget, placement)
return map, virtual_size, widgets
async def mount_all(self, screen: Screen) -> None:
@@ -315,7 +319,9 @@ class Compositor:
for region, order, clip in self.map.values():
region = region.intersection(clip)
log(clipped=region, bool=bool(region and (region in screen_region)))
if region and (region in screen_region):
log(1)
region_cuts = (region.x, region.x + region.width)
for cut in cuts[region.y : region.y + region.height]:
cut.extend(region_cuts)
@@ -400,8 +406,11 @@ class Compositor:
# Maps each cut on to a list of segments
cuts = self.cuts
fromkeys = cast(
Callable[[list[int]], dict[int, list[Segment] | None]], dict.fromkeys
)
chops: list[dict[int, list[Segment] | None]] = [
{cut: None for cut in cut_set} for cut_set in cuts
fromkeys(cut_set) for cut_set in cuts
]
# TODO: Provide an option to update the background
@@ -462,9 +471,10 @@ class Compositor:
if not region.size:
return None
widget.clear_render_cache()
update_region = region.intersection(clip)
if not update_region:
return None
widget.clear_render_cache()
update_lines = self.render(console, crop=update_region).lines
update = LayoutUpdate(update_lines, update_region)
return update

View File

@@ -513,7 +513,11 @@ class App(DOMNode):
try:
if sync_available:
console.file.write("\x1bP=1s\x1b\\")
console.print(ScreenRenderable(Control.home(), self.screen.render()))
console.print(
ScreenRenderable(
Control.home(), self.screen.render(), Control.home()
),
)
if sync_available:
console.file.write("\x1bP=2s\x1b\\")
console.file.flush()

View File

@@ -20,20 +20,43 @@ class HorizontalLayout(Layout):
self, parent: Widget, size: Size, scroll: Offset
) -> tuple[list[WidgetPlacement], set[Widget]]:
# placements: list[WidgetPlacement] = []
# add_placement = placements.append
# x = y = 0
# app = parent.app
# for widget in parent.children:
# styles = widget.styles
# render_width, render_height = size
# if styles.has_rule("height"):
# render_height = int(styles.height.resolve_dimension(size, app.size))
# if styles.has_rule("width"):
# render_width = int(styles.width.resolve_dimension(size, app.size))
# region = Region(x, y, render_width, render_height)
# add_placement(WidgetPlacement(region, widget, order=0))
# x += render_width
# return placements, set(parent.children)
placements: list[WidgetPlacement] = []
add_placement = placements.append
x = y = 0
app = parent.app
x = max_width = max_height = 0
parent_size = parent.size
for widget in parent.children:
styles = widget.styles
render_width, render_height = size
if styles.has_rule("height"):
render_height = int(styles.height.resolve_dimension(size, app.size))
if styles.has_rule("width"):
render_width = int(styles.width.resolve_dimension(size, app.size))
region = Region(x, y, render_width, render_height)
add_placement(WidgetPlacement(region, widget, order=0))
x += render_width
(content_width, content_height), margin = widget.styles.get_box_model(
size, parent_size
)
region = Region(margin.left + x, margin.top, content_width, content_height)
max_height = max(max_height, content_height + margin.height)
add_placement(WidgetPlacement(region, widget, 0))
x += region.x_max
max_width = x + margin.right
total_region = Region(0, 0, max_width, max_height)
add_placement(WidgetPlacement(total_region, None, 0))
return placements, set(parent.children)

View File

@@ -41,6 +41,4 @@ class VerticalLayout(Layout):
total_region = Region(0, 0, max_width, max_height)
add_placement(WidgetPlacement(total_region, None, 0))
for placement in placements:
log(placement)
return placements, set(parent.children)

View File

@@ -267,7 +267,9 @@ class Widget(DOMNode):
# Default displays a pretty repr in the center of the screen
return Align.center(self.css_identifier_styled, vertical="middle")
label = f"{self.css_identifier_styled} {self.size}"
return Align.center(label, vertical="middle")
async def action(self, action: str, *params) -> None:
await self.app.action(action, self)