Preliminary actions
This commit is contained in:
parent
d67ea79994
commit
911bfcfba3
6 changed files with 111 additions and 12 deletions
73
src/main.rs
73
src/main.rs
|
@ -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
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
23
src/roftl.rs
23
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<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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
mod ui;
|
||||
pub use ui::draw;
|
||||
pub use ui::redraw_quick;
|
||||
pub use ui::draw_actions;
|
||||
|
||||
mod painter;
|
||||
mod theme;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use log::debug;
|
||||
use pangocairo::pango::{self, AttrList, Attribute, FontDescription};
|
||||
|
||||
// (r,g,b,a)
|
||||
|
|
18
src/ui/ui.rs
18
src/ui/ui.rs
|
@ -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);
|
||||
});
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue