This commit is contained in:
2026-06-11 22:40:50 -05:00
parent 7f41f704ef
commit 8e79b30583
2 changed files with 49 additions and 12 deletions
+17 -5
View File
@@ -95,12 +95,20 @@ impl Widget for SpeechBubblesWidget<'_> {
.fg(Color::Rgb(160, 160, 220))
.bg(Color::Rgb(20, 20, 40));
// Pass 1: collect placements in the same bottom-first order.
let mut placements: Vec<(u16, u16, Vec<&str>, Rect)> = Vec::new();
for (obj_sx, obj_sy, bubble) in items {
let lines: Vec<&str> = bubble.text.split('\n').collect();
let Some(r) = Self::place_bubble(area, obj_sx, obj_sy, &lines, &mut placed) else { continue };
placements.push((obj_sx, obj_sy, lines, r));
}
// Pass 2: draw top-most bubbles first so lower boxes naturally cover extended tails.
for (obj_sx, obj_sy, lines, r) in placements.iter().rev() {
let (obj_sx, obj_sy) = (*obj_sx, *obj_sy);
// Render the bordered box (top border + one row per line + bottom border).
let box_rect = Rect { height: r.height - 1, ..r };
let box_rect = Rect { height: r.height - 1, ..*r };
let block = Block::bordered()
.border_style(border_style)
.style(bubble_style);
@@ -114,15 +122,19 @@ impl Widget for SpeechBubblesWidget<'_> {
.collect();
Paragraph::new(para_lines).render(text_rect, buf);
// Overwrite the tail-join cell on the bottom border, then draw the tail itself.
// These are the only two cells that ratatui's Block can't produce for us.
// Overwrite the tail-join cell on the bottom border, then draw the full tail
// from below the box down to the source object. Lower bubbles are drawn after
// us (pass 2 iterates top-first), so their boxes naturally cover any tail chars
// that pass through them — no explicit occlusion check needed.
let tail_col = obj_sx.clamp(r.x + 1, r.x + r.width - 2);
let border_bottom = r.y + r.height - 2;
if let Some(cell) = buf.cell_mut((tail_col, border_bottom)) {
cell.set_char('┬').set_style(border_style);
}
if let Some(cell) = buf.cell_mut((tail_col, border_bottom + 1)) {
cell.set_char('│').set_style(border_style);
for y in (border_bottom + 1)..obj_sy {
if let Some(cell) = buf.cell_mut((tail_col, y)) {
cell.set_char('│').set_style(border_style);
}
}
}
}