This commit is contained in:
sxyazi 2023-11-18 15:22:11 +08:00
parent cddd439bee
commit 8d4ee2a9b7
No known key found for this signature in database
2 changed files with 59 additions and 21 deletions

View file

@ -2,7 +2,7 @@ use std::ffi::OsString;
use anyhow::{Ok, Result};
use crossterm::event::KeyEvent;
use ratatui::prelude::Rect;
use ratatui::{backend::Backend, prelude::Rect};
use tokio::sync::oneshot;
use yazi_config::{keymap::{Exec, Key, KeymapLayer}, BOOT};
use yazi_core::{emit, files::FilesOp, input::InputMode, manager::Manager, Ctx, Event};
@ -33,7 +33,7 @@ impl App {
}
Event::Key(key) => app.dispatch_key(key),
Event::Paste(str) => app.dispatch_paste(str),
Event::Render(_) => app.dispatch_render(),
Event::Render(_) => app.dispatch_render()?,
Event::Resize(cols, rows) => app.dispatch_resize(cols, rows),
Event::Stop(state, tx) => app.dispatch_stop(state, tx),
Event::Call(exec, layer) => app.dispatch_call(exec, layer),
@ -76,18 +76,36 @@ impl App {
}
}
fn dispatch_render(&mut self) {
if let Some(term) = &mut self.term {
_ = term.draw(|f| {
yazi_plugin::scope(&self.cx, |_| {
f.render_widget(Root::new(&self.cx), f.size());
});
fn dispatch_render(&mut self) -> Result<()> {
let Some(term) = &mut self.term else {
return Ok(());
};
if let Some((x, y)) = self.cx.cursor() {
f.set_cursor(x, y);
}
let frame = term.draw(|f| {
yazi_plugin::scope(&self.cx, |_| {
f.render_widget(Root::new(&self.cx), f.size());
});
})?;
let mut patches = Vec::new();
// TODO: find a more efficient way to do this
for x in frame.area.left()..frame.area.right() {
for y in frame.area.top()..frame.area.bottom() {
let cell = frame.buffer.get(x, y);
if cell.skip {
patches.push((x, y, cell.clone()));
}
}
}
term.backend_mut().draw(patches.iter().map(|(x, y, cell)| (*x, *y, cell)))?;
if let Some((x, y)) = self.cx.cursor() {
term.show_cursor()?;
term.set_cursor(x, y)?;
}
term.backend_mut().flush()?;
Ok(())
}
fn dispatch_resize(&mut self, cols: u16, rows: u16) {

View file

@ -1,19 +1,39 @@
use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget};
use yazi_adaptor::ADAPTOR;
use yazi_config::MANAGER;
pub(crate) struct Clear;
#[inline]
const fn is_overlapping(a: &Rect, b: &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: &Rect, b: &Rect) -> Option<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(Rect { x, y, width, height })
}
impl Widget for Clear {
fn render(self, area: Rect, buf: &mut Buffer) {
// let stdout = BufWriter::new(stdout().lock());
// let s = " ".repeat(area.width as usize);
// _ = Term::move_lock(stdout, (0, 0), |stdout| {
// for y in area.top()..area.bottom() {
// Term::move_to(stdout, area.x, y)?;
// stdout.write_all(s.as_bytes())?;
// }
// Ok(())
// });
ratatui::widgets::Clear.render(area, buf);
let Some(r) = overlap(&area, &MANAGER.layout.image_rect()) else {
return;
};
ADAPTOR.image_hide(r).ok();
for x in r.left()..r.right() {
for y in r.top()..r.bottom() {
buf.get_mut(x, y).set_skip(true);
}
}
}
}