mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-24 08:11:04 +00:00
76 lines
1.9 KiB
Rust
76 lines
1.9 KiB
Rust
use std::sync::atomic::{AtomicBool, Ordering};
|
|
|
|
use mlua::{Lua, Table, UserData};
|
|
use yazi_adapter::ADAPTOR;
|
|
|
|
use super::Area;
|
|
|
|
pub static COLLISION: AtomicBool = AtomicBool::new(false);
|
|
|
|
#[derive(Clone, Copy, Debug, Default)]
|
|
pub struct Clear {
|
|
pub area: Area,
|
|
}
|
|
|
|
impl Clear {
|
|
pub fn compose(lua: &Lua) -> mlua::Result<Table> {
|
|
let new = lua.create_function(|_, (_, area): (Table, Area)| Ok(Clear { area }))?;
|
|
|
|
let clear = lua.create_table()?;
|
|
clear.set_metatable(Some(lua.create_table_from([("__call", new)])?));
|
|
|
|
Ok(clear)
|
|
}
|
|
|
|
pub(super) fn render(
|
|
self,
|
|
buf: &mut ratatui::buffer::Buffer,
|
|
trans: impl FnOnce(yazi_config::popup::Position) -> ratatui::layout::Rect,
|
|
) {
|
|
<Self as ratatui::widgets::Widget>::render(Default::default(), self.area.transform(trans), buf);
|
|
}
|
|
}
|
|
|
|
impl ratatui::widgets::Widget for Clear {
|
|
fn render(self, area: ratatui::layout::Rect, buf: &mut ratatui::prelude::Buffer)
|
|
where
|
|
Self: Sized,
|
|
{
|
|
ratatui::widgets::Clear.render(area, buf);
|
|
|
|
let Some(r) = ADAPTOR.shown_load().and_then(|r| overlap(area, r)) else {
|
|
return;
|
|
};
|
|
|
|
ADAPTOR.image_erase(r).ok();
|
|
COLLISION.store(true, Ordering::Relaxed);
|
|
for y in r.top()..r.bottom() {
|
|
for x in r.left()..r.right() {
|
|
buf[(x, y)].set_skip(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl UserData for Clear {
|
|
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
|
crate::impl_area_method!(methods);
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
const fn is_overlapping(a: ratatui::layout::Rect, b: ratatui::layout::Rect) -> bool {
|
|
a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y
|
|
}
|
|
|
|
fn overlap(a: ratatui::layout::Rect, b: ratatui::layout::Rect) -> Option<ratatui::layout::Rect> {
|
|
if !is_overlapping(a, b) {
|
|
return None;
|
|
}
|
|
|
|
let x = a.x.max(b.x);
|
|
let y = a.y.max(b.y);
|
|
let width = (a.x + a.width).min(b.x + b.width) - x;
|
|
let height = (a.y + a.height).min(b.y + b.height) - y;
|
|
Some(ratatui::layout::Rect { x, y, width, height })
|
|
}
|