From 25ee2f32c421a94b78e483e5b41b1ff6008d323d Mon Sep 17 00:00:00 2001 From: imgurbot12 Date: Fri, 21 Jul 2023 16:10:27 -0700 Subject: [PATCH] fix: pos-tracker is search-context aware, panic on no-action --- rmenu/public/default.css | 4 ++++ rmenu/src/config.rs | 2 ++ rmenu/src/exec.rs | 3 ++- rmenu/src/gui.rs | 21 ++++++++++++++++----- rmenu/src/state.rs | 21 ++++++++------------- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/rmenu/public/default.css b/rmenu/public/default.css index 9ca8818..cf14845 100644 --- a/rmenu/public/default.css +++ b/rmenu/public/default.css @@ -52,6 +52,10 @@ div.actions { padding-left: 5%; } +div.action-name { + width: 10%; +} + div.actions.active { display: flex; flex-direction: column; diff --git a/rmenu/src/config.rs b/rmenu/src/config.rs index 32fe84b..73be9a1 100644 --- a/rmenu/src/config.rs +++ b/rmenu/src/config.rs @@ -75,6 +75,7 @@ impl<'de> Deserialize<'de> for Keybind { #[derive(Debug, PartialEq, Deserialize)] pub struct KeyConfig { + pub exec: Vec, pub exit: Vec, pub move_up: Vec, pub move_down: Vec, @@ -87,6 +88,7 @@ pub struct KeyConfig { impl Default for KeyConfig { fn default() -> Self { return Self { + exec: vec![Keybind::new(Code::Enter)], exit: vec![Keybind::new(Code::Escape)], move_up: vec![Keybind::new(Code::ArrowUp)], move_down: vec![Keybind::new(Code::ArrowDown)], diff --git a/rmenu/src/exec.rs b/rmenu/src/exec.rs index 9defe1d..c481c51 100644 --- a/rmenu/src/exec.rs +++ b/rmenu/src/exec.rs @@ -9,5 +9,6 @@ pub fn execute(action: &Action) { Ok(args) => args, Err(err) => panic!("{:?} invalid command {err}", action.exec), }; - Command::new(&args[0]).args(&args[1..]).exec(); + let err = Command::new(&args[0]).args(&args[1..]).exec(); + panic!("Command Error: {err:?}"); } diff --git a/rmenu/src/gui.rs b/rmenu/src/gui.rs index 7c8b5e0..38d83bf 100644 --- a/rmenu/src/gui.rs +++ b/rmenu/src/gui.rs @@ -156,9 +156,17 @@ fn App(cx: Scope) -> Element { std::process::exit(0); } + // retrieve results and filter based on search + let searchfn = new_searchfn(&cx.props.config, &search); + let results: Vec<&Entry> = cx + .props + .entries + .iter() + .filter(|entry| searchfn(entry)) + .collect(); + // retrieve results build and build position-tracker - let results = &cx.props.entries; - let tracker = PosTracker::new(cx, results); + let tracker = PosTracker::new(cx, results.clone()); let (pos, subpos) = tracker.position(); log::debug!("pos: {pos}, {subpos}"); @@ -168,7 +176,12 @@ fn App(cx: Scope) -> Element { let key = &evt.code(); let mods = &evt.modifiers(); log::debug!("key: {key:?} mods: {mods:?}"); - if matches(&keybinds.exit, mods, key) { + if matches(&keybinds.exec, mods, key) { + match tracker.action() { + Some(action) => execute(action), + None => panic!("No Action Configured"), + } + } else if matches(&keybinds.exit, mods, key) { quit.set(true); } else if matches(&keybinds.move_up, mods, key) { tracker.shift_up(); @@ -184,10 +197,8 @@ fn App(cx: Scope) -> Element { }; // pre-render results into elements - let searchfn = new_searchfn(&cx.props.config, &search); let results_rendered: Vec = results .iter() - .filter(|entry| searchfn(entry)) .enumerate() .map(|(index, entry)| { cx.render(rsx! { diff --git a/rmenu/src/state.rs b/rmenu/src/state.rs index c610683..c9cac12 100644 --- a/rmenu/src/state.rs +++ b/rmenu/src/state.rs @@ -1,6 +1,6 @@ //! GUI Application State Trackers and Utilities use dioxus::prelude::{use_state, Scope, UseState}; -use rmenu_plugin::Entry; +use rmenu_plugin::{Action, Entry}; use crate::App; @@ -8,21 +8,11 @@ use crate::App; pub struct PosTracker<'a> { pos: &'a UseState, subpos: &'a UseState, - results: &'a Vec, -} - -impl<'a> Clone for PosTracker<'a> { - fn clone(&self) -> Self { - Self { - pos: self.pos, - subpos: self.subpos, - results: self.results, - } - } + results: Vec<&'a Entry>, } impl<'a> PosTracker<'a> { - pub fn new(cx: Scope<'a, App>, results: &'a Vec) -> Self { + pub fn new(cx: Scope<'a, App>, results: Vec<&'a Entry>) -> Self { let pos = use_state(cx, || 0); let subpos = use_state(cx, || 0); Self { @@ -46,6 +36,11 @@ impl<'a> PosTracker<'a> { pub fn position(&self) -> (usize, usize) { (self.pos.get().clone(), self.subpos.get().clone()) } + /// Get Action Linked To The Current Position + pub fn action(&self) -> Option<&Action> { + let (pos, subpos) = self.position(); + self.results[pos].actions.get(subpos) + } /// Move Position To SubMenu if it Exists pub fn open_menu(&self) { let index = *self.pos.get();