Skip to content

Commit e28b54b

Browse files
committed
TUI: reuse retained text measurements
1 parent 2695304 commit e28b54b

2 files changed

Lines changed: 24 additions & 10 deletions

File tree

crates/warpui_core/src/elements/tui/text.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ pub struct TuiText {
5656
style: TuiStyle,
5757
wrap: bool,
5858
overflow: TuiTextOverflow,
59+
measurement: Option<(u16, TuiSize)>,
5960
size: Option<TuiSize>,
6061
origin: Option<TuiScreenPoint>,
6162
}
@@ -75,6 +76,7 @@ impl TuiText {
7576
style: TuiStyle::default(),
7677
wrap: true,
7778
overflow: TuiTextOverflow::default(),
79+
measurement: None,
7880
size: None,
7981
origin: None,
8082
}
@@ -262,18 +264,27 @@ impl TuiElement for TuiText {
262264
_ctx: &mut TuiLayoutContext,
263265
_app: &AppContext,
264266
) -> TuiSize {
265-
let size = if self.is_empty() {
266-
constraint.clamp(TuiSize::ZERO)
267+
let width = constraint.max.width;
268+
let natural_size = if self.is_empty() {
269+
TuiSize::ZERO
270+
} else if let Some((_, size)) = self
271+
.measurement
272+
.filter(|(measured_width, _)| *measured_width == width)
273+
{
274+
size
267275
} else {
268276
let paragraph = self.paragraph(constraint.max.width);
269277
let height =
270278
u16::try_from(paragraph.line_count(constraint.max.width)).unwrap_or(u16::MAX);
271279
let content_width = u16::try_from(paragraph.line_width()).unwrap_or(u16::MAX);
272-
TuiSize::new(
273-
constraint.constrain_width(content_width),
274-
constraint.constrain_height(height),
275-
)
280+
let size = TuiSize::new(content_width, height);
281+
self.measurement = Some((width, size));
282+
size
276283
};
284+
let size = TuiSize::new(
285+
constraint.constrain_width(natural_size.width),
286+
constraint.constrain_height(natural_size.height),
287+
);
277288
self.size = Some(size);
278289
size
279290
}

crates/warpui_core/src/elements/tui/viewported_list.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ where
147147
let Some(resolved) = self.state.resolved_viewport() else {
148148
return;
149149
};
150+
let selection_is_valid = selection.validate_width(size.width);
151+
let selection_range = selection_is_valid.then(|| selection.range()).flatten();
152+
if selection_range.is_none() && !self.trim_selection_line_ends {
153+
self.selection_snapshot.borrow_mut().take();
154+
return;
155+
}
150156
let visible_height = size.height.saturating_sub(resolved.screen_offset).min(
151157
resolved
152158
.content_height
@@ -171,10 +177,7 @@ where
171177
.collect::<Vec<_>>()
172178
});
173179
*self.selection_snapshot.borrow_mut() = Some((resolved, snapshot));
174-
if !selection.validate_width(size.width) {
175-
return;
176-
}
177-
let Some(range) = selection.range() else {
180+
let Some(range) = selection_range else {
178181
return;
179182
};
180183
let viewport_bottom = resolved.window.scroll_top.saturating_add(usize::from(

0 commit comments

Comments
 (0)