87 lines
2.5 KiB
Rust
87 lines
2.5 KiB
Rust
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));
|
|
}
|
|
}
|
|
}
|
|
}
|