From d4c96f4b41d7c36e270e456838b69d0fd489e241 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Wed, 1 Jan 2025 22:13:40 +0100 Subject: [PATCH] border enclose; move file impls --- src/border.rs | 3 ++ src/file.rs | 65 ++++++++++++++++++++++++++++++++++ src/pool.rs | 97 ++++++++------------------------------------------- 3 files changed, 83 insertions(+), 82 deletions(-) diff --git a/src/border.rs b/src/border.rs index 0959d373..f8e7e8f9 100644 --- a/src/border.rs +++ b/src/border.rs @@ -30,6 +30,9 @@ pub trait BorderStyle: Send + Sync + Copy { fn wrap > (self, w: W) -> Bordered { Bordered(self, w) } + fn enclose > (self, w: W) -> impl Content { + Tui::bg(self.style().unwrap().bg.unwrap(), lay!(Fill::xy(Border(self)), w)) + } const NW: &'static str = ""; const N: &'static str = ""; const NE: &'static str = ""; diff --git a/src/file.rs b/src/file.rs index 5f2f1e1f..d4bd8b14 100644 --- a/src/file.rs +++ b/src/file.rs @@ -85,3 +85,68 @@ impl FileBrowser { Self::new(Some(self.path())) } } +command!(|self: FileBrowserCommand, state: PoolModel|{ + use PoolMode::*; + use FileBrowserCommand::*; + let mode = &mut state.mode; + match mode { + Some(Import(index, ref mut browser)) => match self { + Cancel => { *mode = None; }, + Chdir(cwd) => { *mode = Some(Import(*index, FileBrowser::new(Some(cwd))?)); }, + Select(index) => { browser.index = index; }, + Confirm => if browser.is_file() { + let index = *index; + let path = browser.path(); + *mode = None; + PhrasePoolCommand::Import(index, path).execute(state)?; + } else if browser.is_dir() { + *mode = Some(Import(*index, browser.chdir()?)); + }, + _ => todo!(), + }, + Some(Export(index, ref mut browser)) => match self { + Cancel => { *mode = None; }, + Chdir(cwd) => { *mode = Some(Export(*index, FileBrowser::new(Some(cwd))?)); }, + Select(index) => { browser.index = index; }, + _ => unreachable!() + }, + _ => unreachable!(), + }; + None +}); +input_to_command!(FileBrowserCommand:|state: PoolModel,from|{ + + use FileBrowserCommand::*; + use KeyCode::{Up, Down, Left, Right, Enter, Esc, Backspace, Char}; + if let Some(PoolMode::Import(_index, browser)) = &state.mode { + match from.event() { + key_pat!(Up) => Select(browser.index.overflowing_sub(1).0 + .min(browser.len().saturating_sub(1))), + key_pat!(Down) => Select(browser.index.saturating_add(1) + % browser.len()), + key_pat!(Right) => Chdir(browser.cwd.clone()), + key_pat!(Left) => Chdir(browser.cwd.clone()), + key_pat!(Enter) => Confirm, + key_pat!(Char(_)) => { todo!() }, + key_pat!(Backspace) => { todo!() }, + key_pat!(Esc) => Cancel, + _ => return None + } + } else if let Some(PoolMode::Export(_index, browser)) = &state.mode { + match from.event() { + key_pat!(Up) => Select(browser.index.overflowing_sub(1).0 + .min(browser.len())), + key_pat!(Down) => Select(browser.index.saturating_add(1) + % browser.len()), + key_pat!(Right) => Chdir(browser.cwd.clone()), + key_pat!(Left) => Chdir(browser.cwd.clone()), + key_pat!(Enter) => Confirm, + key_pat!(Char(_)) => { todo!() }, + key_pat!(Backspace) => { todo!() }, + key_pat!(Esc) => Cancel, + _ => return None + } + } else { + unreachable!() + } +}); diff --git a/src/pool.rs b/src/pool.rs index 5aa41a9e..07935891 100644 --- a/src/pool.rs +++ b/src/pool.rs @@ -206,23 +206,25 @@ impl PoolModel { } } pub struct PoolView<'a>(pub(crate) &'a PoolModel); -// TODO: Display phrases always in order of appearance render!(Tui: (self: PoolView<'a>) => { let PoolModel { phrases, mode, .. } = self.0; let color = self.0.phrase().read().unwrap().color; - let content = Tui::bg(Color::Black, Tui::map(||self.0.phrases().iter(), |clip, i|{ + Outer( + Style::default().fg(color.dark.rgb).bg(color.darkest.rgb) + ).enclose(Tui::bg(Color::Black, Tui::map(||self.0.phrases().iter(), |clip, i|{ let MidiClip { ref name, color, length, .. } = *clip.read().unwrap(); - let item_height = 1; - let item_offset = i as u16 * item_height; - let selected = i == self.0.phrase_index(); - let offset = |a|Push::y(item_offset, Align::n(Fixed::y(item_height, Fill::x(a)))); - offset(Tui::bg(if selected { color.light.rgb } else { color.base.rgb }, lay!( - Align::w(Tui::fg(color.lightest.rgb, Tui::bold(selected, format!(" {i:>3} {name}")))), - Align::e(Tui::fg(color.lightest.rgb, Tui::bold(selected, format!("{length} ")))), - Align::w(Tui::when(selected, Tui::bold(true, Tui::fg(TuiTheme::g(255), "▶")))), - Align::e(Tui::when(selected, Tui::bold(true, Tui::fg(TuiTheme::g(255), "◀")))), - )))/* - //format!(" {i} {name} {length} ")[> + let item_height = 1; + let item_offset = i as u16 * item_height; + let selected = i == self.0.phrase_index(); + let offset = |a|Push::y(item_offset, Align::n(Fixed::y(item_height, Fill::x(a)))); + offset(Tui::bg(if selected { color.light.rgb } else { color.base.rgb }, lay!( + Align::w(Tui::fg(color.lightest.rgb, Tui::bold(selected, format!(" {i:>3} {name}")))), + Align::e(Tui::fg(color.lightest.rgb, Tui::bold(selected, format!("{length} ")))), + Align::w(Tui::when(selected, Tui::bold(true, Tui::fg(TuiTheme::g(255), "▶")))), + Align::e(Tui::when(selected, Tui::bold(true, Tui::fg(TuiTheme::g(255), "◀")))), + ))) + }))) + /*//format!(" {i} {name} {length} ")[> //Push::y(i as u16 * 2, Fixed::y(2, Tui::bg(color.base.rgb, Fill::x( //format!(" {i} {name} {length} ")))))[>, name.clone()))))Bsp::s( @@ -240,9 +242,6 @@ render!(Tui: (self: PoolView<'a>) => { row2 }), ))))//lay!(clip, Tui::when(i == self.0.clip_index(), CORNERS)))*/ - })); - let border = Outer(Style::default().fg(color.dark.rgb).bg(color.darkest.rgb)); - let enclose = |x|Tui::bg(color.darkest.rgb, lay!(Fill::xy(border), x)); ////let with_files = |x|Tui::either(self.0.file_picker().is_some(), ////Thunk::new(||self.0.file_picker().unwrap()), ////Thunk::new(x)); @@ -253,7 +252,6 @@ render!(Tui: (self: PoolView<'a>) => { //length.focus = Some(focus); //} //} - enclose(content) //enclose(lay!( ////add(&Lozenge(Style::default().bg(border_bg).fg(border_color)))?; //Fill::xy(content), @@ -262,68 +260,3 @@ render!(Tui: (self: PoolView<'a>) => { //self.0.size.clone() //)) }); -command!(|self: FileBrowserCommand, state: PoolModel|{ - use PoolMode::*; - use FileBrowserCommand::*; - let mode = &mut state.mode; - match mode { - Some(Import(index, ref mut browser)) => match self { - Cancel => { *mode = None; }, - Chdir(cwd) => { *mode = Some(Import(*index, FileBrowser::new(Some(cwd))?)); }, - Select(index) => { browser.index = index; }, - Confirm => if browser.is_file() { - let index = *index; - let path = browser.path(); - *mode = None; - PhrasePoolCommand::Import(index, path).execute(state)?; - } else if browser.is_dir() { - *mode = Some(Import(*index, browser.chdir()?)); - }, - _ => todo!(), - }, - Some(Export(index, ref mut browser)) => match self { - Cancel => { *mode = None; }, - Chdir(cwd) => { *mode = Some(Export(*index, FileBrowser::new(Some(cwd))?)); }, - Select(index) => { browser.index = index; }, - _ => unreachable!() - }, - _ => unreachable!(), - }; - None -}); -input_to_command!(FileBrowserCommand:|state: PoolModel,from|{ - - use FileBrowserCommand::*; - use KeyCode::{Up, Down, Left, Right, Enter, Esc, Backspace, Char}; - if let Some(PoolMode::Import(_index, browser)) = &state.mode { - match from.event() { - key_pat!(Up) => Select(browser.index.overflowing_sub(1).0 - .min(browser.len().saturating_sub(1))), - key_pat!(Down) => Select(browser.index.saturating_add(1) - % browser.len()), - key_pat!(Right) => Chdir(browser.cwd.clone()), - key_pat!(Left) => Chdir(browser.cwd.clone()), - key_pat!(Enter) => Confirm, - key_pat!(Char(_)) => { todo!() }, - key_pat!(Backspace) => { todo!() }, - key_pat!(Esc) => Cancel, - _ => return None - } - } else if let Some(PoolMode::Export(_index, browser)) = &state.mode { - match from.event() { - key_pat!(Up) => Select(browser.index.overflowing_sub(1).0 - .min(browser.len())), - key_pat!(Down) => Select(browser.index.saturating_add(1) - % browser.len()), - key_pat!(Right) => Chdir(browser.cwd.clone()), - key_pat!(Left) => Chdir(browser.cwd.clone()), - key_pat!(Enter) => Confirm, - key_pat!(Char(_)) => { todo!() }, - key_pat!(Backspace) => { todo!() }, - key_pat!(Esc) => Cancel, - _ => return None - } - } else { - unreachable!() - } -});