use std::ops;
use egui::Rect;
use crate::{Error, Result, TabIndex};
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct LeafNode<Tab> {
pub rect: Rect,
pub viewport: Rect,
pub tabs: Vec<Tab>,
pub active: TabIndex,
pub scroll: f32,
pub collapsed: bool,
}
impl<Tab> LeafNode<Tab> {
pub const fn new(tabs: Vec<Tab>) -> Self {
LeafNode {
rect: Rect::NOTHING,
viewport: Rect::NOTHING,
tabs,
active: TabIndex(0),
scroll: 0.0,
collapsed: false,
}
}
#[inline]
pub fn set_active_tab(&mut self, active_tab: impl Into<TabIndex>) -> Result {
let index = active_tab.into();
if index.0 < self.len() {
self.active = index;
Ok(())
} else {
Err(Error::InvalidTab)
}
}
#[inline]
pub fn set_rect(&mut self, new_rect: Rect) {
self.rect = new_rect;
}
pub fn len(&self) -> usize {
self.tabs.len()
}
pub fn is_empty(&self) -> bool {
self.tabs.is_empty()
}
pub fn rect(&self) -> Rect {
self.rect
}
#[inline]
pub fn tabs(&self) -> &[Tab] {
&self.tabs
}
#[inline]
pub fn tabs_mut(&mut self) -> &mut [Tab] {
&mut self.tabs
}
#[track_caller]
#[inline]
pub fn append_tab(&mut self, tab: Tab) {
self.active = TabIndex(self.tabs.len());
self.tabs.push(tab);
}
#[track_caller]
#[inline]
pub fn insert_tab(&mut self, tab_index: impl Into<TabIndex>, tab: Tab) {
let tab_index = tab_index.into();
self.tabs.insert(tab_index.0, tab);
self.active = tab_index;
}
#[inline]
pub fn remove_tab(&mut self, tab_index: impl Into<TabIndex>) -> Option<Tab> {
let index = tab_index.into();
if index <= self.active {
self.active.0 = self.active.0.saturating_sub(1);
}
Some(self.tabs.remove(index.0))
}
pub fn retain_tabs<F>(&mut self, predicate: F)
where
F: FnMut(&mut Tab) -> bool,
{
self.tabs.retain_mut(predicate);
}
#[inline]
pub fn active_focused(&mut self) -> Option<(Rect, &mut Tab)> {
self.tabs
.get_mut(self.active.0)
.map(|tab| (self.viewport, tab))
}
}
impl<Tab> ops::Index<TabIndex> for LeafNode<Tab> {
type Output = Tab;
fn index(&self, index: TabIndex) -> &Tab {
&self.tabs[index.0]
}
}
impl<Tab> ops::IndexMut<TabIndex> for LeafNode<Tab> {
fn index_mut(&mut self, index: TabIndex) -> &mut Tab {
&mut self.tabs[index.0]
}
}