1use cursive_core as cursive;
2
3use cursive::{
4 event::{Event, EventResult, Key},
5 view::ViewWrapper,
6 View,
7};
8
9pub struct HjklToDirectionWrapperView<T> {
11 view: T,
12}
13
14impl<T> HjklToDirectionWrapperView<T> {
15 pub fn new(view: T) -> Self {
16 Self { view }
17 }
18
19 cursive::inner_getters!(self.view: T);
20}
21
22impl<T> ViewWrapper for HjklToDirectionWrapperView<T>
23where
24 T: View,
25{
26 cursive::wrap_impl!(self.view: T);
27
28 fn wrap_on_event(&mut self, ev: Event) -> EventResult {
29 let ev_result = self.view.on_event(ev.clone());
30 if !matches!(&ev_result, EventResult::Ignored) {
31 return ev_result;
32 }
33
34 type EventCtor = fn(Key) -> Event;
37 let (ch, ctor) = match &ev {
38 Event::Char(c) => (
39 c,
40 if c.is_ascii_uppercase() {
41 Event::Shift
42 } else {
43 Event::Key
44 } as EventCtor,
45 ),
46 Event::CtrlChar(c) => (
47 c,
48 if c.is_ascii_uppercase() {
49 Event::CtrlShift
50 } else {
51 Event::Ctrl
52 } as EventCtor,
53 ),
54 Event::AltChar(c) => (
55 c,
56 if c.is_ascii_uppercase() {
57 Event::AltShift
58 } else {
59 Event::Alt
60 } as EventCtor,
61 ),
62 _ => return EventResult::Ignored,
63 };
64
65 let dir = match ch {
66 'h' => Key::Left,
67 'j' => Key::Down,
68 'k' => Key::Up,
69 'l' => Key::Right,
70 _ => return EventResult::Ignored,
71 };
72 let the_cooler_event = ctor(dir);
73 self.view.on_event(the_cooler_event)
74 }
75}
76
77#[cursive_core::blueprint(HjklToDirectionWrapperView::new(view))]
78struct Blueprint {
79 view: cursive_core::views::BoxedView,
80}
81
82cursive_core::manual_blueprint!(with hjkl_to_direction, |_config, _context| {
83 Ok(|view| HjklToDirectionWrapperView::new(view))
84});