mirror of
https://github.com/imgurbot12/rmenu.git
synced 2025-02-12 13:15:07 +01:00
fix: pos-tracker is search-context aware, panic on no-action
This commit is contained in:
parent
c83febd10b
commit
25ee2f32c4
5 changed files with 32 additions and 19 deletions
|
@ -52,6 +52,10 @@ div.actions {
|
|||
padding-left: 5%;
|
||||
}
|
||||
|
||||
div.action-name {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
div.actions.active {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
|
@ -75,6 +75,7 @@ impl<'de> Deserialize<'de> for Keybind {
|
|||
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct KeyConfig {
|
||||
pub exec: Vec<Keybind>,
|
||||
pub exit: Vec<Keybind>,
|
||||
pub move_up: Vec<Keybind>,
|
||||
pub move_down: Vec<Keybind>,
|
||||
|
@ -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)],
|
||||
|
|
|
@ -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:?}");
|
||||
}
|
||||
|
|
|
@ -156,9 +156,17 @@ fn App(cx: Scope<App>) -> 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<App>) -> 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<App>) -> Element {
|
|||
};
|
||||
|
||||
// pre-render results into elements
|
||||
let searchfn = new_searchfn(&cx.props.config, &search);
|
||||
let results_rendered: Vec<Element> = results
|
||||
.iter()
|
||||
.filter(|entry| searchfn(entry))
|
||||
.enumerate()
|
||||
.map(|(index, entry)| {
|
||||
cx.render(rsx! {
|
||||
|
|
|
@ -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<usize>,
|
||||
subpos: &'a UseState<usize>,
|
||||
results: &'a Vec<Entry>,
|
||||
}
|
||||
|
||||
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<Entry>) -> 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();
|
||||
|
|
Loading…
Reference in a new issue