@@ -36,6 +36,11 @@ class MapRegion(NamedTuple):
3636 order : tuple [int , int ]
3737
3838
39+ class ReflowResult (NamedTuple ):
40+ hidden : set [Widget ]
41+ shown : set [Widget ]
42+
43+
3944class LayoutUpdate :
4045 def __init__ (self , lines : Lines , x : int , y : int ) -> None :
4146 self .lines = lines
@@ -70,10 +75,16 @@ def reset(self) -> None:
7075 self .renders .clear ()
7176 self ._cuts = None
7277
73- def reflow (self , width : int , height : int ) -> None :
78+ def reflow (self , width : int , height : int ) -> ReflowResult :
7479 self .reset ()
7580
7681 map = self .generate_map (width , height )
82+
83+ old_widgets = set (self ._layout_map .keys ())
84+ new_widgets = set (map .keys ())
85+ shown_widgets = new_widgets - old_widgets
86+ hidden_widgets = old_widgets - new_widgets
87+
7788 self ._layout_map = map
7889 self .width = width
7990 self .height = height
@@ -84,6 +95,7 @@ def reflow(self, width: int, height: int) -> None:
8495 new_renders [widget ] = (region , self .renders [widget ][1 ])
8596
8697 self .renders = new_renders
98+ return ReflowResult (hidden_widgets , shown_widgets )
8799
88100 @abstractmethod
89101 def generate_map (
@@ -150,37 +162,6 @@ def cuts(self) -> list[list[int]]:
150162 self ._cuts = [sorted (cut_set ) for cut_set in cuts_sets ]
151163 return self ._cuts
152164
153- @classmethod
154- def _compare_lines (cls , lines1 : Lines , lines2 : Lines ) -> Iterable [list [Segment ]]:
155- """Compares two renders and produce 'diff'"""
156- delta_line : list [Segment ] = [Control .home ().segment ]
157- add_delta_segment = delta_line .append
158- move_to_column = Control .move_to_column
159-
160- for y , (line1 , line2 ) in enumerate (zip (lines1 , lines2 )):
161- if line1 == line2 :
162- continue
163-
164- add_delta_segment (Control .move_to (0 , y ).segment )
165- start_skip : int | None = None
166- x1 = 0
167- x2 = 0
168- for segment1 , segment2 in zip (line1 , line2 ):
169- if x1 == x2 and segment1 == segment2 :
170- if start_skip is None :
171- start_skip = x1
172- else :
173- if start_skip is not None :
174- add_delta_segment (move_to_column (x2 ).segment )
175- start_skip = None
176- add_delta_segment (segment2 )
177- x1 += segment1 .cell_length
178- x2 += segment2 .cell_length
179-
180- if delta_line :
181- yield delta_line [:]
182- del delta_line [:]
183-
184165 def _get_renders (self , console : Console ) -> Iterable [tuple [Region , Lines ]]:
185166 width = self .width
186167 height = self .height
@@ -213,11 +194,13 @@ def render(widget: Widget, width: int, height: int) -> Lines:
213194 new_region = region .clip (width , height )
214195 delta_x = new_region .x - region .x
215196 delta_y = new_region .y - region .y
216- # region = new_region
217- lines = lines [delta_y : delta_y + region .height ]
197+ region = new_region
198+
199+ splits = [delta_x , delta_x + region .width ]
200+ divide = Segment .divide
218201 lines = [
219- list (Segment . divide (line , [ delta_x , delta_x + region . width ] ))[1 ]
220- for line in lines
202+ list (divide (line , splits ))[1 ]
203+ for line in lines [ delta_y : delta_y + region . height ]
221204 ]
222205 self .renders [widget ] = (region , lines )
223206 yield region , lines
@@ -279,9 +262,8 @@ def render(
279262 if final_cuts == [region .x , region .x + region .width ]:
280263 cut_segments = [line ]
281264 else :
282- _ , * cut_segments = divide (
283- line , [cut - region .x for cut in final_cuts ]
284- )
265+ relative_cuts = [cut - region .x for cut in final_cuts ]
266+ _ , * cut_segments = divide (line , relative_cuts )
285267 for cut , segments in zip (final_cuts , cut_segments ):
286268 if chops [y ][cut ] is None :
287269 chops [y ][cut ] = segments
0 commit comments