@@ -60,19 +60,54 @@ class Terminal::Widgets::Viewer::Tree
6060 has DisplayParent $ . display-root is built(False );
6161 has & . process-click ;
6262
63+ has @ ! flat-node-cache ;
64+ has @ ! flat-line-cache ;
65+ has $ ! max-line-width ;
66+
67+ # Auto-cache flattened nodes and displayable lines
68+ method flat-node-cache () {
69+ @ ! flat-node-cache ||= self . flattened-nodes($ ! display-root );
70+ }
71+ method flat-line-cache () {
72+ @ ! flat-line-cache ||= self . node-lines($ ! display-root );
73+ }
74+ method max-line-width () {
75+ $ ! max-line-width ||= do {
76+ # my $locale = self.terminal.locale;
77+ # self.flat-line-cache.map({ $locale.width($_) }).max
78+
79+ # XXXX: HACK while refactoring content model
80+ use Text::MiscUtils::Layout;
81+ self . flat-line-cache. map ({ . map ({ duospace-width(. text) }). sum }). max
82+ }
83+ }
84+ method clear-caches () {
85+ @ ! flat-node-cache = Empty;
86+ @ ! flat-line-cache = Empty;
87+ $ ! max-line-width = 0 ;
88+ }
89+
90+ # Fix x-max and y-max based on current display state
91+ method fix-scroll-maxes () {
92+ self . set-x-max(self . max-line-width);
93+ self . set-y-max($ . display-root . branch-size);
94+ . note for $ . x-max , $ . y-max ;
95+ }
96+
6397 # Keep root and display-root in sync
6498 method set-root (VTree::Node: D $ ! root ) { self ! remap-root }
6599 method ! remap-root () {
66100 $ ! display-root = DisplayParent. new (data => $ ! root , depth => 0 );
101+ self . clear-caches;
67102 }
68103
69104 # | Provide a span line chunk for SpanBuffer display
70105 method span-line-chunk (UInt : D $ start , UInt : D $ wanted ) {
71- my @ lines = self . node-lines( $ ! display-root ) ;
72- my $ count = @ lines . elems ;
73- my $ end = $ start + $ wanted - 1 ;
106+ my @ lines : = self . flat-line-cache ;
107+ my $ count = @ lines . elems ;
108+ my $ end = $ start + $ wanted - 1 ;
74109
75- self . set-y-max( $ count ) ;
110+ self . fix-scroll-maxes ;
76111
77112 $ count > $ end ?? @ lines [$ start .. $ end ]
78113 !! @ lines [$ start .. * ]
@@ -119,7 +154,7 @@ class Terminal::Widgets::Viewer::Tree
119154 }
120155
121156 method line-to-display-node ($ line ) {
122- self . flattened-nodes( $ . display-root ) [$ line ]
157+ self . flat-node-cache [$ line ]
123158 }
124159
125160 multi method handle-event (Terminal::Widgets::Events::MouseEvent: D
@@ -137,7 +172,8 @@ class Terminal::Widgets::Viewer::Tree
137172
138173 if $ node ~~ DisplayParent {
139174 $ node . toggle-expanded;
140- self . set-y-max($ . display-root . branch-size);
175+ self . clear-caches;
176+ self . fix-scroll-maxes;
141177 self . refresh-for-scroll;
142178 }
143179
0 commit comments