yazi/app/src/context.rs
2023-08-19 11:10:26 +08:00

85 lines
2.2 KiB
Rust

use core::{input::Input, manager::Manager, select::Select, tasks::Tasks, which::Which, Position};
use config::keymap::KeymapLayer;
use crossterm::terminal::WindowSize;
use ratatui::prelude::Rect;
use shared::Term;
pub struct Ctx {
pub manager: Manager,
pub which: Which,
pub select: Select,
pub input: Input,
pub tasks: Tasks,
}
impl Ctx {
pub(super) fn new() -> Self {
Self {
manager: Manager::make(),
which: Default::default(),
select: Default::default(),
input: Default::default(),
tasks: Tasks::start(),
}
}
pub(super) fn area(&self, pos: &Position) -> Rect {
let WindowSize { columns, rows, .. } = Term::size();
let (x, y) = match pos {
Position::None => return Rect::default(),
Position::Top(Rect { mut x, mut y, width, height }) => {
x = x.min(columns.saturating_sub(*width));
y = y.min(rows.saturating_sub(*height));
((columns / 2).saturating_sub(width / 2) + x, y)
}
Position::Hovered(rect @ Rect { mut x, y, width, height }) => {
let Some(r) =
self.manager.hovered().and_then(|h| self.manager.current().rect_current(&h.path))
else {
return self.area(&Position::Top(*rect));
};
x = x.min(columns.saturating_sub(*width));
if y + height + r.y + r.height > rows {
(x + r.x, r.y.saturating_sub(height.saturating_sub(1)))
} else {
(x + r.x, y + r.y + r.height)
}
}
};
let (w, h) = pos.dimension().unwrap();
Rect { x, y, width: w.min(columns.saturating_sub(x)), height: h.min(rows.saturating_sub(y)) }
}
#[inline]
pub(super) fn cursor(&self) -> Option<(u16, u16)> {
if self.input.visible {
let Rect { x, y, .. } = self.area(&self.input.position);
return Some((x + 1 + self.input.cursor(), y + 1));
}
None
}
#[inline]
pub(super) fn layer(&self) -> KeymapLayer {
if self.which.visible {
KeymapLayer::Which
} else if self.input.visible {
KeymapLayer::Input
} else if self.select.visible {
KeymapLayer::Select
} else if self.tasks.visible {
KeymapLayer::Tasks
} else {
KeymapLayer::Manager
}
}
#[inline]
pub(super) fn image_layer(&self) -> bool {
!matches!(self.layer(), KeymapLayer::Which | KeymapLayer::Tasks)
}
}