From 911bfcfba3e043aa382c2ad700251f0089eccc61 Mon Sep 17 00:00:00 2001 From: Armin Friedl Date: Mon, 1 Nov 2021 21:25:48 +0100 Subject: [PATCH] Preliminary actions --- src/main.rs | 73 +++++++++++++++++++++++++++++++++++++++++---- src/roftl.rs | 23 +++++++++++--- src/sources/test.rs | 7 ++++- src/ui/mod.rs | 1 + src/ui/theme.rs | 1 - src/ui/ui.rs | 18 +++++++++++ 6 files changed, 111 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index 456ff73..2f6ebc7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,9 +21,9 @@ fn main() -> Result<(), Box> { debug!{"Set up roftl"}; let mut roftl = roftl::Roftl::new() .add_source(sources::TestSource::new("ts1")) - .add_source(sources::Window::new()) - .add_source(sources::Apps::new()) - .add_source(sources::ShellHost::new()) + // .add_source(sources::Window::new()) + // .add_source(sources::Apps::new()) + // .add_source(sources::ShellHost::new()) .with_matcher(FuseMatcher::new()); debug!{"Source roftl sources"} @@ -47,10 +47,16 @@ fn main() -> Result<(), Box> { roftl_loop.run(event_loop); } +enum Mode { + Selection, + Actions +} + struct RoftlLoop { input_buffer: String, input_changed: bool, selection: usize, + mode: Mode, roftl: Roftl, window: Window, } @@ -58,7 +64,9 @@ struct RoftlLoop { impl RoftlLoop { fn new(roftl: Roftl, window: Window) -> Self { - RoftlLoop{input_buffer: String::default(), input_changed: true, selection: 0, roftl, window} + RoftlLoop{input_buffer: String::default(), input_changed: true, selection: 0, + mode: Mode::Selection, + roftl, window} } fn run(mut self, event_loop: EventLoop) -> ! @@ -74,11 +82,19 @@ impl RoftlLoop { } Event::WindowEvent{event: ReceivedCharacter(character), window_id} - if window_id == self.window.id() => + if window_id == self.window.id() + && matches!(self.mode, Mode::Selection) => { *flow = self.process_character(character); } + Event::WindowEvent{event: ReceivedCharacter(character), window_id} + if window_id == self.window.id() + && matches!(self.mode, Mode::Actions) => + { + *flow = self.process_action(character); + } + Event::WindowEvent{event: winit::event::WindowEvent::KeyboardInput{input, ..}, window_id} if window_id == self.window.id() => { @@ -86,7 +102,8 @@ impl RoftlLoop { } Event::RedrawRequested(window_id) - if window_id == self.window.id() => + if window_id == self.window.id() + && matches!{self.mode, Mode::Selection} => { if self.input_changed { trace!{"Redrawing with input {}", self.input_buffer} @@ -115,6 +132,15 @@ impl RoftlLoop { self.input_changed = false; } + Event::RedrawRequested(window_id) + if window_id == self.window.id() + && matches!{self.mode, Mode::Actions} => + { + let actions = self.roftl.actions(self.selection); + debug!{"Actions for current selection: {:?}", actions} + ui::draw_actions(&self.window, actions); + } + _ => () } }); @@ -179,6 +205,17 @@ impl RoftlLoop { ControlFlow::Wait } + // Ctrl+a + c if c == char::from(0x01) => { + debug!{"Received actions"} + match self.mode { + Mode::Selection => { self.mode = Mode::Actions; self.input_changed = true }, + Mode::Actions => { self.mode = Mode::Selection; self.input_changed = true } + } + self.window.request_redraw(); + ControlFlow::Wait + } + c if c.is_control() => { debug!{"Got unknown control character {:#x}", u32::from(c)} ControlFlow::Wait @@ -194,6 +231,30 @@ impl RoftlLoop { } } + fn process_action(&mut self, character: char) -> ControlFlow { + match character { + '0' => { + trace!{"Retrieved action selection 0. Trigger primary action"} + self.roftl.action(self.selection, roftl::Action::Primary); + ControlFlow::Exit + }, + '1' => { + trace!{"Retrieved action selection 1. Trigger secondary action"} + self.roftl.action(self.selection, roftl::Action::Secondary); + ControlFlow::Exit + }, + '2' => { + trace!{"Retrieved action selection 2. Trigger ternary action"} + self.roftl.action(self.selection, roftl::Action::Ternary); + ControlFlow::Exit + }, + _ => { + trace!{"Retrieved unknown action selection"} + ControlFlow::Wait + }, + } + } + } diff --git a/src/roftl.rs b/src/roftl.rs index 3fb62f0..2309e41 100644 --- a/src/roftl.rs +++ b/src/roftl.rs @@ -17,14 +17,19 @@ pub struct Entry { #[derive(Debug)] pub enum Action { Primary, + Secondary, + Ternary } pub trait Source: Send + Sync { fn name(&self) -> &'static str; fn entries(&mut self) -> Vec; fn action(&self, entry: &Entry, action: Action); + fn actions(&self) -> Vec + { vec![] } } + pub trait Matcher: Send + Sync { fn try_match(&self, haystack: &str, needle: &str) -> Option<(f64, Vec)>; } @@ -96,16 +101,26 @@ impl Roftl { } pub fn action(&self, selection_id: usize, action: Action) { + let (entry, source) = self.find_selection(selection_id); + source.action(entry, action); + } + + pub fn actions(&self, selection_id: usize) -> Vec { + let (_entry, source) = self.find_selection(selection_id); + source.actions() + } + + fn find_selection(&self, selection_id: usize) -> (&Entry, &Box) + { let entry_id = self.narrow_map[selection_id]; let entry = &self.entries[entry_id]; debug!{"Got entry {:?} for id {} ", entry, entry_id}; - let source = self - .sources + let source = self.sources .iter() - .find(|&s| s.name().eq(entry.source)) + .find(|s| s.name().eq(entry.source)) .unwrap(); - source.action(&entry, action); + (entry, source) } } diff --git a/src/sources/test.rs b/src/sources/test.rs index 653e363..20722f6 100644 --- a/src/sources/test.rs +++ b/src/sources/test.rs @@ -8,7 +8,7 @@ impl TestSource { pub fn new(s: &str) -> Box { let mut ts = Box::new(TestSource { entries: vec![] }); - (1..1).for_each(|i| { + (0..1).for_each(|i| { ts.add_entry( format! {"Test {} {}", i, s}, format! {"Test {} description", i}, @@ -41,5 +41,10 @@ impl Source for TestSource { fn action(&self, entry: &Entry, action: Action) { println!("Doing action {:?} for entry {}", action, entry.name) } + + fn actions(&self) -> Vec { + ["Primary", "Secondary", "Ternary"] + .iter().map(|s| (*s).into()).collect() + } } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index ba82a3f..d2f8c91 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,6 +1,7 @@ mod ui; pub use ui::draw; pub use ui::redraw_quick; +pub use ui::draw_actions; mod painter; mod theme; diff --git a/src/ui/theme.rs b/src/ui/theme.rs index 098b33c..08aaf53 100644 --- a/src/ui/theme.rs +++ b/src/ui/theme.rs @@ -1,4 +1,3 @@ -use log::debug; use pangocairo::pango::{self, AttrList, Attribute, FontDescription}; // (r,g,b,a) diff --git a/src/ui/ui.rs b/src/ui/ui.rs index 6610f27..3d2bd15 100644 --- a/src/ui/ui.rs +++ b/src/ui/ui.rs @@ -113,3 +113,21 @@ pub fn redraw_quick(window: &Window, result: Vec<(&Entry, Vec)>, selectio if i == selection { painter.result_box(0, 1+(i as u32), &e.source, &e.name, &r.1, true) } }); } + +pub fn draw_actions(window: &Window, actions: Vec) +{ + let context = make_context(&window); + + context.scale(30.0, 30.0); + + let painter = painter::Painter::new(&context); + + painter.background(); + painter.divider(0, 1); + + actions.iter().enumerate() + .for_each(|(i, r)| { + painter.result_box(0, 1+(i as u32), &usize::to_string(&i), r, &[], false); + }); + +}