Feat: early mouse support
This commit is contained in:
@@ -28,7 +28,7 @@ pub use file_browser::FileBrowserModal;
|
||||
pub use hint_bar::hint_line;
|
||||
pub use list_select::ListSelect;
|
||||
pub use modal::ModalFrame;
|
||||
pub use nav_minimap::{NavMinimap, NavTile};
|
||||
pub use nav_minimap::{hit_test_tile, minimap_area, NavMinimap, NavTile};
|
||||
pub use props_form::render_props_form;
|
||||
pub use sample_browser::{SampleBrowser, TreeLine, TreeLineKind};
|
||||
pub use scope::{Orientation, Scope};
|
||||
|
||||
@@ -4,6 +4,42 @@ use ratatui::style::Style;
|
||||
use ratatui::widgets::{Clear, Paragraph};
|
||||
use ratatui::Frame;
|
||||
|
||||
const TILE_W: u16 = 12;
|
||||
const TILE_H: u16 = 3;
|
||||
const GAP: u16 = 1;
|
||||
const PAD: u16 = 2;
|
||||
const GRID_COLS: u16 = 3;
|
||||
const GRID_ROWS: u16 = 2;
|
||||
|
||||
/// Compute the centered minimap area for a 3x2 grid.
|
||||
pub fn minimap_area(term: Rect) -> Rect {
|
||||
let content_w = TILE_W * GRID_COLS + GAP * (GRID_COLS - 1);
|
||||
let content_h = TILE_H * GRID_ROWS + GAP * (GRID_ROWS - 1);
|
||||
let modal_w = content_w + PAD * 2;
|
||||
let modal_h = content_h + PAD * 2;
|
||||
let x = term.x + (term.width.saturating_sub(modal_w)) / 2;
|
||||
let y = term.y + (term.height.saturating_sub(modal_h)) / 2;
|
||||
Rect::new(x, y, modal_w, modal_h)
|
||||
}
|
||||
|
||||
/// Hit-test: returns `(grid_col, grid_row)` if the click lands on a tile.
|
||||
pub fn hit_test_tile(col: u16, row: u16, term: Rect) -> Option<(i8, i8)> {
|
||||
let area = minimap_area(term);
|
||||
let inner_x = area.x + PAD;
|
||||
let inner_y = area.y + PAD;
|
||||
|
||||
for grid_row in 0..GRID_ROWS {
|
||||
for grid_col in 0..GRID_COLS {
|
||||
let tx = inner_x + grid_col * (TILE_W + GAP);
|
||||
let ty = inner_y + grid_row * (TILE_H + GAP);
|
||||
if col >= tx && col < tx + TILE_W && row >= ty && row < ty + TILE_H {
|
||||
return Some((grid_col as i8, grid_row as i8));
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// A tile in the navigation grid
|
||||
pub struct NavTile {
|
||||
pub col: i8,
|
||||
@@ -27,25 +63,7 @@ impl<'a> NavMinimap<'a> {
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute grid bounds from tiles
|
||||
let max_col = self.tiles.iter().map(|t| t.col).max().unwrap_or(0);
|
||||
let max_row = self.tiles.iter().map(|t| t.row).max().unwrap_or(0);
|
||||
let cols = (max_col + 1) as u16;
|
||||
let rows = (max_row + 1) as u16;
|
||||
|
||||
let tile_w: u16 = 12;
|
||||
let tile_h: u16 = 3;
|
||||
let gap: u16 = 1;
|
||||
let pad: u16 = 2;
|
||||
|
||||
let content_w = tile_w * cols + gap * (cols.saturating_sub(1));
|
||||
let content_h = tile_h * rows + gap * (rows.saturating_sub(1));
|
||||
let modal_w = content_w + pad * 2;
|
||||
let modal_h = content_h + pad * 2;
|
||||
|
||||
let x = term.x + (term.width.saturating_sub(modal_w)) / 2;
|
||||
let y = term.y + (term.height.saturating_sub(modal_h)) / 2;
|
||||
let area = Rect::new(x, y, modal_w, modal_h);
|
||||
let area = minimap_area(term);
|
||||
|
||||
frame.render_widget(Clear, area);
|
||||
|
||||
@@ -60,13 +78,13 @@ impl<'a> NavMinimap<'a> {
|
||||
);
|
||||
}
|
||||
|
||||
let inner_x = area.x + pad;
|
||||
let inner_y = area.y + pad;
|
||||
let inner_x = area.x + PAD;
|
||||
let inner_y = area.y + PAD;
|
||||
|
||||
for tile in self.tiles {
|
||||
let tile_x = inner_x + (tile.col as u16) * (tile_w + gap);
|
||||
let tile_y = inner_y + (tile.row as u16) * (tile_h + gap);
|
||||
let tile_area = Rect::new(tile_x, tile_y, tile_w, tile_h);
|
||||
let tile_x = inner_x + (tile.col as u16) * (TILE_W + GAP);
|
||||
let tile_y = inner_y + (tile.row as u16) * (TILE_H + GAP);
|
||||
let tile_area = Rect::new(tile_x, tile_y, TILE_W, TILE_H);
|
||||
let is_selected = (tile.col, tile.row) == self.selected;
|
||||
self.render_tile(frame, tile_area, tile.name, is_selected);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user