refactor(ui): improve TileBar rendering and width calculation

Update TileBar to use UnicodeWidthStr for accurate text width calculation and
improve axis display.

- Use `unicode_width::UnicodeWidthStr` for calculating label and hint widths
- Move `axis_display` to a static method on `TileBar`
- Update axis symbols for better visual clarity (e.g., '|', '-', '=', '.')
- Clear the tile bar area before rendering to prevent stale characters

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
This commit is contained in:
Edward Langley
2026-04-06 23:18:40 -07:00
parent e0171c758f
commit def4f0b7df

View File

@ -32,10 +32,26 @@ impl<'a> TileBar<'a> {
tile_cat_idx, tile_cat_idx,
} }
} }
fn axis_display(axis: Axis) -> (&'static str, Color) {
match axis {
Axis::Row => ("|", Color::Green),
Axis::Column => ("-", Color::Blue),
Axis::Page => ("=", Color::Magenta),
Axis::None => (".", Color::DarkGray),
}
}
} }
impl<'a> Widget for TileBar<'a> { impl<'a> Widget for TileBar<'a> {
fn render(self, area: Rect, buf: &mut Buffer) { fn render(self, area: Rect, buf: &mut Buffer) {
// Clear the line to avoid stale characters from previous renders
buf.set_string(
area.x,
area.y,
" ".repeat(area.width as usize),
Style::default(),
);
let view = self.model.active_view(); let view = self.model.active_view();
let selected_cat_idx = if matches!(self.mode, AppMode::TileSelect) { let selected_cat_idx = if matches!(self.mode, AppMode::TileSelect) {
@ -50,7 +66,7 @@ impl<'a> Widget for TileBar<'a> {
let cat_names: Vec<&str> = self.model.category_names(); let cat_names: Vec<&str> = self.model.category_names();
for (i, cat_name) in cat_names.iter().enumerate() { for (i, cat_name) in cat_names.iter().enumerate() {
let (axis_symbol, axis_color) = axis_display(view.axis_of(cat_name)); let (axis_symbol, axis_color) = TileBar::axis_display(view.axis_of(cat_name));
let label = format!(" [{cat_name} {axis_symbol}] "); let label = format!(" [{cat_name} {axis_symbol}] ");
let is_selected = selected_cat_idx == Some(i); let is_selected = selected_cat_idx == Some(i);
@ -63,22 +79,23 @@ impl<'a> Widget for TileBar<'a> {
Style::default().fg(axis_color) Style::default().fg(axis_color)
}; };
if x + label.len() as u16 > area.x + area.width { let label_w = label.width() as u16;
if x + label_w > area.x + area.width {
break; break;
} }
buf.set_string(x, area.y, &label, style); buf.set_string(x, area.y, &label, style);
x += label.len() as u16; x += label_w;
} }
// Hint // Hint
if matches!(self.mode, AppMode::TileSelect) { if matches!(self.mode, AppMode::TileSelect) {
let hint = " [Enter] cycle axis [r/c/p] set axis [←→] select [Esc] cancel"; let hint = " [Enter] cycle axis [r/c/p] set axis [←→] select [Esc] cancel";
if x + hint.len() as u16 <= area.x + area.width { if x + hint.width() as u16 <= area.x + area.width {
buf.set_string(x, area.y, hint, Style::default().fg(Color::DarkGray)); buf.set_string(x, area.y, hint, Style::default().fg(Color::DarkGray));
} }
} else { } else {
let hint = " Ctrl+↑↓←→ to move tiles"; let hint = " Ctrl+↑↓←→ to move tiles";
if x + hint.len() as u16 <= area.x + area.width { if x + hint.width() as u16 <= area.x + area.width {
buf.set_string(x, area.y, hint, Style::default().fg(Color::DarkGray)); buf.set_string(x, area.y, hint, Style::default().fg(Color::DarkGray));
} }
} }