use ratatui::{ buffer::Buffer, layout::Rect, style::{Color, Modifier, Style}, widgets::Widget, }; use crate::model::Model; use crate::ui::app::AppMode; use crate::view::Axis; 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), } } pub struct TileBar<'a> { pub model: &'a Model, pub mode: &'a AppMode, pub tile_cat_idx: usize, } impl<'a> TileBar<'a> { pub fn new(model: &'a Model, mode: &'a AppMode, tile_cat_idx: usize) -> Self { Self { model, mode, tile_cat_idx, } } } impl<'a> Widget for TileBar<'a> { fn render(self, area: Rect, buf: &mut Buffer) { let view = self.model.active_view(); let selected_cat_idx = if matches!(self.mode, AppMode::TileSelect) { Some(self.tile_cat_idx) } else { None }; let mut x = area.x + 1; buf.set_string(area.x, area.y, " Tiles: ", Style::default().fg(Color::Gray)); x += 8; let cat_names: Vec<&str> = self.model.category_names(); for (i, cat_name) in cat_names.iter().enumerate() { let (axis_symbol, axis_color) = axis_display(view.axis_of(cat_name)); let label = format!(" [{cat_name} {axis_symbol}] "); let is_selected = selected_cat_idx == Some(i); let style = if is_selected { Style::default() .fg(Color::Black) .bg(Color::Cyan) .add_modifier(Modifier::BOLD) } else { Style::default().fg(axis_color) }; if x + label.len() as u16 > area.x + area.width { break; } buf.set_string(x, area.y, &label, style); x += label.len() as u16; } // Hint if matches!(self.mode, AppMode::TileSelect) { let hint = " [Enter] cycle axis [r/c/p] set axis [←→] select [Esc] cancel"; if x + hint.len() as u16 <= area.x + area.width { buf.set_string(x, area.y, hint, Style::default().fg(Color::DarkGray)); } } else { let hint = " Ctrl+↑↓←→ to move tiles"; if x + hint.len() as u16 <= area.x + area.width { buf.set_string(x, area.y, hint, Style::default().fg(Color::DarkGray)); } } } }