Tooltips wrap every line and grow with their text

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-06 08:34:08 +01:00
1 parent d8d11699fc
commit de2dbab592
1 file changed
+30 -5
+30 -5
View File
@@ -515,10 +515,21 @@ pub struct Ui {
hud_h: f32, hud_h: f32,
} }
// word wrap to `cols` characters: keeps line breaks, splits words longer than a line
pub fn wrap(s: &str, cols: usize) -> Vec<String> { pub fn wrap(s: &str, cols: usize) -> Vec<String> {
let cols = cols.max(1);
let mut out = Vec::new(); let mut out = Vec::new();
for para in s.split('\n') {
let mut line = String::new(); let mut line = String::new();
for word in s.split(' ') { for word in para.split(' ') {
let mut word: Vec<char> = word.chars().collect();
while word.len() > cols {
if !line.is_empty() {
out.push(std::mem::take(&mut line));
}
out.push(word.drain(..cols).collect());
}
let word: String = word.into_iter().collect();
let len = line.chars().count(); let len = line.chars().count();
if len > 0 && len + 1 + word.chars().count() > cols { if len > 0 && len + 1 + word.chars().count() > cols {
out.push(std::mem::take(&mut line)); out.push(std::mem::take(&mut line));
@@ -526,14 +537,27 @@ pub fn wrap(s: &str, cols: usize) -> Vec<String> {
if !line.is_empty() { if !line.is_empty() {
line.push(' '); line.push(' ');
} }
line.push_str(word); line.push_str(&word);
} }
if !line.is_empty() {
out.push(line); out.push(line);
} }
while out.last().map_or(false, |l| l.is_empty()) {
out.pop();
}
out out
} }
#[cfg(test)]
mod wrap_tests {
#[test]
fn wrap_keeps_every_line_inside() {
let l = super::wrap("Cost: 30 gold + 2 wood/tile over water, 60 gold over lava", 20);
assert!(l.len() >= 3 && l.iter().all(|x| x.chars().count() <= 20), "{:?}", l);
let l = super::wrap("a\nsuperlongwordwithoutanyspaces", 8);
assert_eq!(l[0], "a");
assert!(l.iter().all(|x| x.chars().count() <= 8), "{:?}", l);
}
}
fn mmss(t: f32) -> String { fn mmss(t: f32) -> String {
let t = t.max(0.0) as i32; let t = t.max(0.0) as i32;
@@ -1149,12 +1173,13 @@ impl Ui {
let ti = tool_info(t); let ti = tool_info(t);
let tcols = 34.min(cols as usize); let tcols = 34.min(cols as usize);
let mut lines: Vec<(String, Color)> = wrap(&ti.desc, tcols - 4).into_iter().map(|l| (l, TXT)).collect(); let mut lines: Vec<(String, Color)> = wrap(&ti.desc, tcols - 4).into_iter().map(|l| (l, TXT)).collect();
// every line wraps; the window grows with the lines
let cost = tool_cost(t, g); let cost = tool_cost(t, g);
if !cost.is_empty() { if !cost.is_empty() {
lines.push((trf("ui.cost", &[cost]), GOLD)); lines.extend(wrap(&trf("ui.cost", &[cost]), tcols - 4).into_iter().map(|l| (l, GOLD)));
} }
if !touch_ui() { if !touch_ui() {
lines.push((trf("ui.key", &[keys[i].clone()]), DIM)); lines.extend(wrap(&trf("ui.key", &[keys[i].clone()]), tcols - 4).into_iter().map(|l| (l, DIM)));
} }
let rows = lines.len() as i32 + 2; let rows = lines.len() as i32 + 2;
let anchor = if touch_ui() { sw * 0.5 } else { mx }; let anchor = if touch_ui() { sw * 0.5 } else { mx };