mirror of
https://codeberg.org/unspeaker/perch.git
synced 2025-12-06 09:36:42 +01:00
pass whole state to setter, to emit tasks
This commit is contained in:
parent
d26c46d6e1
commit
859da8e5d1
5 changed files with 85 additions and 48 deletions
16
src/keys.rs
16
src/keys.rs
|
|
@ -78,19 +78,27 @@ impl Taggart {
|
||||||
{
|
{
|
||||||
let value = (column.getter)(&self.entries[self.cursor]);
|
let value = (column.getter)(&self.entries[self.cursor]);
|
||||||
let value = format!("{}", value.unwrap_or_default());
|
let value = format!("{}", value.unwrap_or_default());
|
||||||
self.mode = Some(Mode::Edit { index: value.len(), value });
|
self.mode = Some(Mode::Edit {
|
||||||
|
index: value.len(),
|
||||||
|
value: value.into(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn edit_cancel (&mut self) {
|
pub fn edit_cancel (&mut self) {
|
||||||
self.mode = None;
|
self.mode = None;
|
||||||
}
|
}
|
||||||
pub fn edit_confirm (&mut self) {
|
pub fn edit_confirm (&mut self) {
|
||||||
if let Some(Mode::Edit { value, .. }) = &self.mode
|
let value = if let Some(Mode::Edit { value, .. }) = &self.mode {
|
||||||
|
Some(value.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
if let Some(value) = value
|
||||||
&& let Some(column) = self.columns.0.get(self.column)
|
&& let Some(column) = self.columns.0.get(self.column)
|
||||||
&& let Some(setter) = &column.setter
|
&& let Some(setter) = &column.setter
|
||||||
&& self.entries.get_mut(self.cursor).is_some()
|
&& self.entries.get_mut(self.cursor).is_some()
|
||||||
{
|
{
|
||||||
setter(self.entries.as_mut_slice(), self.cursor, value);
|
setter(self, self.cursor, value.as_ref());
|
||||||
self.mode = None;
|
self.mode = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +106,7 @@ impl Taggart {
|
||||||
if let Some(Mode::Edit { value, index }) = &self.mode {
|
if let Some(Mode::Edit { value, index }) = &self.mode {
|
||||||
self.mode = Some(Mode::Edit {
|
self.mode = Some(Mode::Edit {
|
||||||
index: *index + 1,
|
index: *index + 1,
|
||||||
value: format!("{value}{c}")
|
value: format!("{value}{c}").into()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ pub struct Taggart {
|
||||||
pub cursor: usize,
|
pub cursor: usize,
|
||||||
pub offset: usize,
|
pub offset: usize,
|
||||||
pub column: usize,
|
pub column: usize,
|
||||||
pub columns: Columns<fn(&Entry)->Option<Arc<str>>, fn(&mut [Entry], usize, &str)>,
|
pub columns: Columns<fn(&Entry)->Option<Arc<str>>, fn(&mut Self, usize, &str)>,
|
||||||
pub display: Measure<TuiOut>,
|
pub display: Measure<TuiOut>,
|
||||||
pub tasks: Vec<Task>,
|
pub tasks: Vec<Task>,
|
||||||
pub mode: Option<Mode>,
|
pub mode: Option<Mode>,
|
||||||
|
|
@ -22,7 +22,7 @@ pub struct Taggart {
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
Help,
|
Help,
|
||||||
Edit {
|
Edit {
|
||||||
value: String,
|
value: Arc<str>,
|
||||||
index: usize,
|
index: usize,
|
||||||
},
|
},
|
||||||
Apply {
|
Apply {
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,21 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub struct Columns<G, S>(pub Vec<Column<G, S>>);
|
|
||||||
|
|
||||||
pub struct Column<G, S> {
|
pub struct Column<G, S> {
|
||||||
pub title: Arc<str>,
|
pub title: Arc<str>,
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
pub getter: G,
|
pub getter: G,
|
||||||
pub setter: Option<S>,
|
pub setter: Option<S>,
|
||||||
//pub styler: Option<U>,
|
//pub styler: Option<U>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Column<fn(&T)->Option<Arc<str>>, fn(&mut [T], usize, &str)> {
|
type Getter<T> = fn(&T)->Option<Arc<str>>;
|
||||||
|
type Setter<T> = fn(&mut T, usize, &str);
|
||||||
|
|
||||||
|
impl<G, S> Column<Getter<G>, Setter<S>> {
|
||||||
pub fn new (
|
pub fn new (
|
||||||
title: &impl AsRef<str>,
|
title: &impl AsRef<str>,
|
||||||
width: usize,
|
width: usize,
|
||||||
getter: fn(&T)->Option<Arc<str>>,
|
getter: Getter<G>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
width,
|
width,
|
||||||
|
|
@ -23,37 +24,49 @@ impl<T> Column<fn(&T)->Option<Arc<str>>, fn(&mut [T], usize, &str)> {
|
||||||
setter: None,
|
setter: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn setter (mut self, setter: fn(&mut [T], usize, &str)) -> Self {
|
fn setter (mut self, setter: Setter<S>) -> Self {
|
||||||
self.setter = Some(setter);
|
self.setter = Some(setter);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! setter {
|
macro_rules! setter {
|
||||||
($method:ident) => {
|
($name:ident) => {{
|
||||||
|entries: &mut [Entry], index: usize, value: &str|{
|
fn $name (
|
||||||
if let Some(entries) = entries_under(entries, index) {
|
state: &mut Taggart,
|
||||||
|
index: usize,
|
||||||
|
value: &str
|
||||||
|
) {
|
||||||
|
if let Some(entries) = entries_under(&mut state.entries, index) {
|
||||||
for entry in entries.iter() {
|
for entry in entries.iter() {
|
||||||
entry.write().unwrap().$method(&value);
|
entry.write().unwrap().$name(&value);
|
||||||
}
|
}
|
||||||
} else if let Some(entry) = entries.get_mut(index) {
|
} else if let Some(entry) = state.entries.get_mut(index) {
|
||||||
entry.$method(&value)
|
entry.$name(&value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
$name
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Columns<fn(&Entry)->Option<Arc<str>>, fn(&mut [Entry], usize, &str)> {
|
pub struct Columns<G, S>(pub Vec<Column<G, S>>);
|
||||||
|
|
||||||
|
impl Default for Columns<fn(&Entry)->Option<Arc<str>>, fn(&mut Taggart, usize, &str)> {
|
||||||
fn default () -> Self {
|
fn default () -> Self {
|
||||||
Self(vec![
|
Self(vec![
|
||||||
Column::new(&"Hash", 8, |entry: &Entry|entry.hash()),
|
Column::new(&"Hash", 8, |entry: &Entry|entry.hash()),
|
||||||
Column::new(&"Size", 8, |entry: &Entry|entry.size()),
|
Column::new(&"Size", 8, |entry: &Entry|entry.size()),
|
||||||
Column::new(&"File", 80, |entry: &Entry|entry.name()),
|
Column::new(&"File", 80, |entry: &Entry|entry.name()),
|
||||||
Column::new(&"Artist", 30, |entry: &Entry|entry.artist()).setter(setter!(set_artist)),
|
Column::new(&"Artist", 30, |entry: &Entry|entry.artist())
|
||||||
Column::new(&"Year", 5, |entry: &Entry|entry.year()).setter(setter!(set_year)),
|
.setter(setter!(set_artist)),
|
||||||
Column::new(&"Release", 30, |entry: &Entry|entry.album()).setter(setter!(set_album)),
|
Column::new(&"Year", 5, |entry: &Entry|entry.year())
|
||||||
Column::new(&"Track", 5, |entry: &Entry|entry.track()).setter(setter!(set_track)),
|
.setter(setter!(set_year)),
|
||||||
Column::new(&"Title", 80, |entry: &Entry|entry.title()).setter(setter!(set_title)),
|
Column::new(&"Release", 30, |entry: &Entry|entry.album())
|
||||||
|
.setter(setter!(set_album)),
|
||||||
|
Column::new(&"Track", 5, |entry: &Entry|entry.track())
|
||||||
|
.setter(setter!(set_track)),
|
||||||
|
Column::new(&"Title", 80, |entry: &Entry|entry.title())
|
||||||
|
.setter(setter!(set_title)),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,19 +68,19 @@ impl Entry {
|
||||||
pub fn track (&self) -> Option<Arc<str>> {
|
pub fn track (&self) -> Option<Arc<str>> {
|
||||||
self.info.read().unwrap().track()
|
self.info.read().unwrap().track()
|
||||||
}
|
}
|
||||||
pub fn set_artist (&self, value: &impl AsRef<str> ) {
|
pub fn set_artist (&self, value: &impl AsRef<str>) -> Option<Task> {
|
||||||
self.info.write().unwrap().set_artist(value)
|
self.info.write().unwrap().set_artist(value)
|
||||||
}
|
}
|
||||||
pub fn set_year (&self, value: &impl AsRef<str> ) {
|
pub fn set_year (&self, value: &impl AsRef<str>) -> Option<Task> {
|
||||||
self.info.write().unwrap().set_year(value)
|
self.info.write().unwrap().set_year(value)
|
||||||
}
|
}
|
||||||
pub fn set_album (&self, value: &impl AsRef<str> ) {
|
pub fn set_album (&self, value: &impl AsRef<str>) -> Option<Task> {
|
||||||
self.info.write().unwrap().set_album(value)
|
self.info.write().unwrap().set_album(value)
|
||||||
}
|
}
|
||||||
pub fn set_title (&self, value: &impl AsRef<str> ) {
|
pub fn set_title (&self, value: &impl AsRef<str>) -> Option<Task> {
|
||||||
self.info.write().unwrap().set_title(value)
|
self.info.write().unwrap().set_title(value)
|
||||||
}
|
}
|
||||||
pub fn set_track (&self, value: &impl AsRef<str> ) {
|
pub fn set_track (&self, value: &impl AsRef<str>) -> Option<Task> {
|
||||||
self.info.write().unwrap().set_track(value)
|
self.info.write().unwrap().set_track(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -159,42 +159,58 @@ impl Metadata {
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn set_artist (&mut self, value: &impl AsRef<str> ) {
|
pub fn set_artist (&mut self, value: &impl AsRef<str>) -> Option<Task> {
|
||||||
match self {
|
match self {
|
||||||
Metadata::Music { artist, .. } => *artist = Some(value.as_ref().into()),
|
Metadata::Music { artist, .. } => {
|
||||||
_ => {}
|
*artist = Some(value.as_ref().into());
|
||||||
|
//todo!("emit task");
|
||||||
|
None
|
||||||
|
},
|
||||||
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn set_year (&mut self, value: &impl AsRef<str> ) {
|
pub fn set_year (&mut self, value: &impl AsRef<str> ) -> Option<Task> {
|
||||||
match self {
|
match self {
|
||||||
Metadata::Music { year, .. } => {
|
Metadata::Music { year, .. } => {
|
||||||
if let Ok(value) = value.as_ref().trim().parse::<u32>() {
|
if let Ok(value) = value.as_ref().trim().parse::<u32>() {
|
||||||
*year = Some(value)
|
*year = Some(value);
|
||||||
}
|
}
|
||||||
|
//todo!("emit task");
|
||||||
|
None
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn set_album (&mut self, value: &impl AsRef<str> ) {
|
pub fn set_album (&mut self, value: &impl AsRef<str>) -> Option<Task> {
|
||||||
match self {
|
match self {
|
||||||
Metadata::Music { album, .. } => *album = Some(value.as_ref().into()),
|
Metadata::Music { album, .. } => {
|
||||||
_ => {}
|
*album = Some(value.as_ref().into());
|
||||||
|
//todo!("emit task");
|
||||||
|
None
|
||||||
|
},
|
||||||
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn set_title (&mut self, value: &impl AsRef<str> ) {
|
pub fn set_title (&mut self, value: &impl AsRef<str>) -> Option<Task> {
|
||||||
match self {
|
match self {
|
||||||
Metadata::Music { title, .. } => *title = Some(value.as_ref().into()),
|
Metadata::Music { title, .. } => {
|
||||||
_ => {}
|
*title = Some(value.as_ref().into());
|
||||||
|
//todo!("emit task");
|
||||||
|
None
|
||||||
|
},
|
||||||
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn set_track (&mut self, value: &impl AsRef<str>) {
|
pub fn set_track (&mut self, value: &impl AsRef<str>) -> Option<Task> {
|
||||||
match self {
|
match self {
|
||||||
Metadata::Music { track, .. } => {
|
Metadata::Music { track, .. } => {
|
||||||
if let Ok(value) = value.as_ref().trim().parse::<u32>() {
|
if let Ok(value) = value.as_ref().trim().parse::<u32>() {
|
||||||
*track = Some(value)
|
*track = Some(value);
|
||||||
}
|
}
|
||||||
|
//todo!("emit task");
|
||||||
|
None
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue