itools_tui/components/
button.rs1use crate::{event::Event, layout::Rect, render::Frame, style::Style};
4use crossterm::event::KeyCode;
5
6pub struct Button {
8 label: String,
10 style: Style,
12 active_style: Style,
14 is_pressed: bool,
16 on_press: Option<Box<dyn Fn()>>,
18}
19
20impl Button {
21 pub fn new(label: &str) -> Self {
23 Self {
24 label: label.to_string(),
25 style: Style::new(),
26 active_style: Style::new().reversed(),
27 is_pressed: false,
28 on_press: None,
29 }
30 }
31
32 pub fn style(mut self, style: Style) -> Self {
34 self.style = style;
35 self
36 }
37
38 pub fn active_style(mut self, style: Style) -> Self {
40 self.active_style = style;
41 self
42 }
43
44 pub fn on_press<F: Fn() + 'static>(mut self, f: F) -> Self {
46 self.on_press = Some(Box::new(f));
47 self
48 }
49
50 pub fn press(&mut self) {
52 self.is_pressed = true;
53 if let Some(callback) = &self.on_press {
54 callback();
55 }
56 }
57}
58
59impl super::Component for Button {
60 fn render(&self, frame: &mut Frame, area: Rect) {
61 let style = if self.is_pressed { self.active_style.clone() } else { self.style.clone() };
62
63 frame.render_button(&self.label, area, style);
64 }
65
66 fn handle_event(&mut self, event: &Event) -> bool {
67 match event {
68 Event::Key(key_event) => {
69 if key_event.code == KeyCode::Enter {
70 self.press();
71 true
72 }
73 else {
74 false
75 }
76 }
77 _ => false,
78 }
79 }
80}