mirror of
https://codeberg.org/unspeaker/perch.git
synced 2025-12-06 09:36:42 +01:00
89 lines
2.5 KiB
Rust
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;
|
|
}
|
|
}
|