Preliminary actions

This commit is contained in:
Armin Friedl 2021-11-01 21:25:48 +01:00
parent d67ea79994
commit 911bfcfba3
6 changed files with 111 additions and 12 deletions

View file

@ -21,9 +21,9 @@ fn main() -> Result<(), Box<dyn Error>> {
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<dyn Error>> {
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<T>(mut self, event_loop: EventLoop<T>) -> !
@ -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
},
}
}
}

View file

@ -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<Entry>;
fn action(&self, entry: &Entry, action: Action);
fn actions(&self) -> Vec<String>
{ vec![] }
}
pub trait Matcher: Send + Sync {
fn try_match(&self, haystack: &str, needle: &str) -> Option<(f64, Vec<usize>)>;
}
@ -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<String> {
let (_entry, source) = self.find_selection(selection_id);
source.actions()
}
fn find_selection(&self, selection_id: usize) -> (&Entry, &Box<dyn Source>)
{
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)
}
}

View file

@ -8,7 +8,7 @@ impl TestSource {
pub fn new(s: &str) -> Box<TestSource> {
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<String> {
["Primary", "Secondary", "Ternary"]
.iter().map(|s| (*s).into()).collect()
}
}

View file

@ -1,6 +1,7 @@
mod ui;
pub use ui::draw;
pub use ui::redraw_quick;
pub use ui::draw_actions;
mod painter;
mod theme;

View file

@ -1,4 +1,3 @@
use log::debug;
use pangocairo::pango::{self, AttrList, Attribute, FontDescription};
// (r,g,b,a)

View file

@ -113,3 +113,21 @@ pub fn redraw_quick(window: &Window, result: Vec<(&Entry, Vec<usize>)>, 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<String>)
{
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);
});
}