jag

showKey_rust

public

Shows what key you pressed last

Star0
Watch0
ssh://git@git.jaglekon.de:30/jag/showKey_rust.git
src/main.rsRust182 lines4.1 KB
1
use std::{
2
    io,
3
    time::{
4
        Duration,
5
        Instant,
6
    },
7
};
8
9
use crossterm::event::{
10
    self, 
11
    poll,
12
    KeyCode,
13
    KeyModifiers,
14
    KeyEvent,
15
    KeyEventKind,
16
    Event,
17
};
18
19
use ratatui::{
20
    buffer::Buffer,
21
    layout::{Rect, Constraint},
22
    text::{Line, Span},
23
    style::Stylize,
24
    symbols::border,
25
    DefaultTerminal,
26
    widgets::{Widget, Block},
27
    Frame,
28
};
29
30
#[derive(Debug, PartialEq, Eq)]
31
enum State {
32
    Run,
33
    Consider,
34
    Quit,
35
}
36
37
#[derive(Debug)]
38
pub struct ShowKey {
39
    state: State,
40
    current_key: Option<KeyEvent>,
41
    key_time: Option<Instant>,
42
}
43
44
impl Default for ShowKey {
45
    fn default() -> Self {
46
        Self {
47
            state: State::Run,
48
            current_key: None,
49
            key_time: None,
50
        }
51
    }
52
}
53
54
impl Widget for &ShowKey {
55
    fn render(self, area: Rect, buf: &mut Buffer) {
56
57
        let title = Line::from(" Show Key ".bold());
58
59
        let bottom = Line::from(" Exit <Esc Esc> ");
60
61
        let block = Block::bordered()
62
            .title(title.centered())
63
            .title_bottom(bottom.centered())
64
            .border_set(border::ROUNDED);
65
66
        let block_area = area.centered(
67
            Constraint::Length(25),
68
            Constraint::Length(7),
69
        );
70
71
        let pressed = Line::from(self
72
            .current_key.map(|key| vec![
73
                Span::from(match key.modifiers {
74
                    KeyModifiers::NONE => "".into(),
75
                    other => format!("{other} + "),
76
                }),
77
                Span::from(match key.code {
78
                    KeyCode::Char(c) => if c == ' ' {
79
                        "\" \"".into()
80
                    }  else {
81
                        c.to_lowercase().to_string()
82
                    },
83
                    KeyCode::F(f) => format!("F{f}"),
84
                    other => format!("{other}"),
85
                }),
86
            ]
87
88
89
            )
90
            .unwrap_or_default()
91
        );
92
93
        let pressed_area = block
94
            .inner(block_area)
95
            .centered(
96
                Constraint::Length(pressed.width() as u16),
97
                Constraint::Length(1),
98
            );
99
100
        block.render(block_area, buf);
101
        pressed.render(pressed_area, buf);
102
    }
103
}
104
105
impl ShowKey {
106
    fn run(&mut self, terminal: &mut DefaultTerminal) -> io::Result<()> {
107
            
108
        terminal.draw(|frame| self.draw(frame))?;
109
110
        while self.state != State::Quit {
111
            
112
            if poll(Duration::from_millis(100))? {
113
                self.handle_events()?;
114
            }
115
116
            match self.key_time {
117
                Some(time)  if time.elapsed() >= Duration::from_secs(1) => {
118
                    self.unset();
119
                    self.detime();
120
                },
121
                _ => {},
122
            }
123
            
124
            terminal.draw(|frame| self.draw(frame))?;
125
        }
126
        Ok(())
127
    }
128
129
    fn draw(&self, frame: &mut Frame) {
130
        frame.render_widget(self, frame.area());
131
    }
132
133
    fn handle_events(&mut self) -> io::Result<()> {
134
        match event::read()? {
135
            Event::Key(key_event) if key_event.kind == KeyEventKind::Press => {
136
                    self.key_time = Some(Instant::now());
137
                    self.handle_key_event(key_event);
138
                },
139
            _ => {},
140
        }
141
        Ok(())
142
    }
143
144
    fn handle_key_event(&mut self, key_event: KeyEvent) {
145
        
146
        self.current_key = Some(key_event);
147
148
        match key_event.code {
149
            KeyCode::Esc => self.deeper(),
150
            _ => self.higher(),
151
        }
152
    }
153
154
    fn unset(&mut self) {
155
        self.current_key = None;
156
    }
157
158
    fn detime(&mut self) {
159
        self.key_time = None;
160
    }
161
162
    fn deeper(&mut self) {
163
        match self.state {
164
            State::Run => self.state = State::Consider,
165
            State::Consider => self.state = State::Quit,
166
            State::Quit => {}
167
        }
168
    }
169
170
    fn higher(&mut self) {
171
        match self.state {
172
            State::Run => {}
173
            State::Consider => self.state = State::Run,
174
            State::Quit => self.state = State::Consider,
175
        }
176
    }
177
}
178
179
180
fn main() -> io::Result<()> {
181
    ratatui::run(|term| ShowKey::default().run(term))
182
}