#![doc = include_str!("../README.md")]
pub mod draw;
pub mod viewer;
pub use draw::{Renderer, Style};
pub use viewer::{RowViewer, UiAction};
pub extern crate egui;
pub struct DataTable<R> {
rows: Vec<R>,
dirty_flag: bool,
ui: Option<Box<draw::state::UiState<R>>>,
}
impl<R: std::fmt::Debug> std::fmt::Debug for DataTable<R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Spreadsheet")
.field("rows", &self.rows)
.finish()
}
}
impl<R> Default for DataTable<R> {
fn default() -> Self {
Self {
rows: Default::default(),
ui: Default::default(),
dirty_flag: false,
}
}
}
impl<R> FromIterator<R> for DataTable<R> {
fn from_iter<T: IntoIterator<Item = R>>(iter: T) -> Self {
Self {
rows: iter.into_iter().collect(),
..Default::default()
}
}
}
impl<R> DataTable<R> {
pub fn new() -> Self {
Default::default()
}
pub fn take(&mut self) -> Vec<R> {
self.mark_dirty();
std::mem::take(&mut self.rows)
}
pub fn replace(&mut self, new: Vec<R>) -> Vec<R> {
self.mark_dirty();
std::mem::replace(&mut self.rows, new)
}
pub fn retain(&mut self, mut f: impl FnMut(&R) -> bool) {
let mut removed_any = false;
self.rows.retain(|row| {
let retain = f(row);
removed_any |= !retain;
retain
});
if removed_any {
self.mark_dirty();
}
}
pub fn is_dirty(&self) -> bool {
self.ui.as_ref().is_some_and(|ui| ui.cc_is_dirty())
}
#[deprecated(
since = "0.5.1",
note = "user-driven dirty flag clearance is redundant"
)]
pub fn clear_dirty_flag(&mut self) {
}
fn mark_dirty(&mut self) {
let Some(state) = self.ui.as_mut() else {
return;
};
state.force_mark_dirty();
}
pub fn has_user_modification(&self) -> bool {
self.dirty_flag
}
pub fn clear_user_modification_flag(&mut self) {
self.dirty_flag = false;
}
}
impl<R> Extend<R> for DataTable<R> {
fn extend<T: IntoIterator<Item = R>>(&mut self, iter: T) {
self.ui = None;
self.rows.extend(iter);
}
}
fn default<T: Default>() -> T {
T::default()
}
impl<R> std::ops::Deref for DataTable<R> {
type Target = Vec<R>;
fn deref(&self) -> &Self::Target {
&self.rows
}
}
impl<R> std::ops::DerefMut for DataTable<R> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.mark_dirty();
&mut self.rows
}
}
impl<R: Clone> Clone for DataTable<R> {
fn clone(&self) -> Self {
Self {
rows: self.rows.clone(),
ui: None,
dirty_flag: self.dirty_flag,
}
}
}