yazi/core/src/manager/tabs.rs
2023-09-05 19:32:53 +08:00

105 lines
2 KiB
Rust

use config::{BOOT, MANAGER};
use shared::Url;
use super::Tab;
use crate::emit;
const MAX_TABS: usize = 9;
pub struct Tabs {
idx: usize,
items: Vec<Tab>,
}
impl Tabs {
pub fn make() -> Self {
let mut tab = Tab::from(Url::from(&BOOT.cwd));
tab.set_show_hidden(Some(MANAGER.show_hidden));
let mut tabs = Self { idx: usize::MAX, items: vec![tab] };
tabs.set_idx(0);
tabs
}
pub fn create(&mut self, url: &Url) -> bool {
if self.items.len() >= MAX_TABS {
return false;
}
let mut tab = Tab::from(url);
tab.set_show_hidden(Some(self.active().show_hidden));
self.items.insert(self.idx + 1, tab);
self.set_idx(self.idx + 1);
true
}
pub fn switch(&mut self, idx: isize, rel: bool) -> bool {
let idx = if rel { self.absolute(idx) } else { idx as usize };
if idx == self.idx || idx >= self.items.len() {
return false;
}
self.set_idx(idx);
true
}
pub fn swap(&mut self, rel: isize) -> bool {
let idx = self.absolute(rel);
if idx == self.idx {
return false;
}
self.items.swap(self.idx, idx);
self.set_idx(idx);
true
}
pub fn close(&mut self, idx: usize) -> bool {
let len = self.items.len();
if len < 2 || idx >= len {
return false;
}
self.items.remove(idx);
if idx <= self.idx {
self.set_idx(self.absolute(1));
}
true
}
#[inline]
fn absolute(&self, rel: isize) -> usize {
if rel > 0 {
(self.idx + rel as usize).min(self.items.len() - 1)
} else {
self.idx.saturating_sub(rel.unsigned_abs())
}
}
#[inline]
fn set_idx(&mut self, idx: usize) {
self.idx = idx;
self.active_mut().preview_reset_image();
emit!(Refresh);
}
}
impl Tabs {
#[inline]
pub fn idx(&self) -> usize { self.idx }
#[inline]
pub fn len(&self) -> usize { self.items.len() }
#[inline]
pub fn iter(&self) -> impl Iterator<Item = &Tab> { self.items.iter() }
#[inline]
pub fn active(&self) -> &Tab { &self.items[self.idx] }
#[inline]
pub(super) fn active_mut(&mut self) -> &mut Tab { &mut self.items[self.idx] }
}