perch/src/model.rs

89 lines
2.5 KiB
Rust

use crate::*;
use crate::ratatui::style::Style;
mod column; pub use self::column::*;
mod entry; pub use self::entry::*;
/// The application state.
pub struct Taggart {
pub _root: PathBuf,
pub entries: Vec<Entry>,
pub cursor: usize,
pub offset: usize,
pub column: usize,
pub display: Measure<TuiOut>,
/// State of modal dialog of editing field
pub mode: Option<Mode>,
/// Count of changes to items
pub changes: usize,
/// Table columns to display
pub columns: Columns<
fn(&Entry)->Option<Arc<str>>,
fn(&mut Self, usize, &str),
fn(&Entry)->Option<Style>,
>,
}
#[derive(Debug)]
pub enum Mode {
Help { page: u8 },
Edit { value: Arc<str>, index: usize, },
Save { choice: u8, },
Quit { choice: u8, },
}
impl Taggart {
pub fn new (root: &impl AsRef<Path>, entries: Vec<Entry>) -> Usually<Self> {
Ok(Self {
_root: root.as_ref().into(),
cursor: 0,
offset: 0,
column: 2,
display: Measure::new(),
mode: None,
columns: Columns::default(),
entries,
changes: 0
})
}
/// Make sure cursor is always in view
pub(crate) fn clamp (&mut self, min: usize, max: usize) {
if self.cursor < min {
self.offset = self.cursor;
}
if self.cursor > max {
self.offset += self.cursor - max;
}
if self.offset > self.entries.len().saturating_sub(self.display.h()) {
self.offset = self.entries.len().saturating_sub(self.display.h())
}
if self.cursor >= self.entries.len() {
self.cursor = self.entries.len().saturating_sub(1)
}
if self.column + 1 > self.columns.0.len() {
self.column = self.columns.0.len().saturating_sub(1)
}
}
/// Count modified entries
pub(crate) fn count_changes (&mut self) -> usize {
let mut changes = 0;
for entry in self.entries.iter() {
if entry.is_modified() {
changes += 1;
}
}
self.changes = changes;
self.changes
}
/// Clear all modified tags.
pub(crate) fn clear_changes (&mut self) {
for entry in self.entries.iter_mut() {
if let Metadata::Music {
modified_tag, ..
} = &mut *entry.info.write().unwrap() {
*modified_tag = None;
}
}
self.changes = 0;
}
}