Skip to content

Commit a1c8cb8

Browse files
committed
Add Viewer::Tree node/line caches and fix scrolling
1 parent 75ae6a7 commit a1c8cb8

File tree

1 file changed

+42
-6
lines changed

1 file changed

+42
-6
lines changed

lib/Terminal/Widgets/Viewer/Tree.rakumod

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)