Skip to main content

ez_tui/components/concrete/forms/inputs/
check_input.rs

1use crate::components::concrete::forms::inputs::core::{FormFieldValue, InputCpt};
2use crate::{
3    AttrValue, Attribute, Component, EzArgs, EzCptIds, EzEvent, EzMsg, EzState, FormField,
4    FormFieldType, MockComponent, MockProps, Props, State, Theme,
5};
6use crossterm::event::KeyCode;
7use eztui_derive::MockProps;
8use ratatui::buffer::Buffer;
9use ratatui::layout::{Alignment, Rect};
10use ratatui::prelude::Widget;
11use ratatui::widgets::{BorderType, Paragraph};
12use std::fmt::Debug;
13
14/// A component drawing a [`FormField`] of type [`FormFieldType::CheckBox`].
15#[derive(Debug, MockProps)]
16pub struct CheckboxInputCpt<FID>
17where
18    FID: EzCptIds,
19{
20    props: Props,
21    #[allow(dead_code)]
22    // I need a phantom if i remove this. So it's better keeping it as i need it in the constructor
23    field: FormField<FID>,
24    value: bool,
25}
26
27impl<FID> CheckboxInputCpt<FID>
28where
29    FID: EzCptIds,
30{
31    /// Create a new [`CheckboxInputCpt`] component with a given form.
32    #[must_use]
33    pub(crate) fn new(field: FormField<FID>) -> Self {
34        assert_eq!(field.field_type(), &FormFieldType::CheckBox {});
35        let mut props = Props::default();
36        props.set(
37            Attribute::Title,
38            AttrValue::Title((field.name(), Alignment::Left)),
39        );
40        Self {
41            props,
42            field,
43            value: false,
44        }
45    }
46}
47
48impl<FID, CID, CA, CS, CM> InputCpt<CID, CA, CS, CM> for CheckboxInputCpt<FID>
49where
50    FID: EzCptIds,
51    CID: EzCptIds,
52    CA: EzArgs,
53    CS: EzState,
54    CM: EzMsg,
55{
56    fn get_value(&self) -> FormFieldValue {
57        FormFieldValue::Bool(self.value)
58    }
59}
60impl<FID> MockComponent for CheckboxInputCpt<FID>
61where
62    FID: EzCptIds,
63{
64    fn draw(&mut self, area: Rect, buf: &mut Buffer, theme: &Theme) {
65        Paragraph::new(self.value.to_string())
66            .block(theme.block(self.props()).border_type(BorderType::Double))
67            .render(area, buf);
68    }
69}
70
71impl<FID, CID, CA, CS, CM> Component<CID, CA, CS, CM> for CheckboxInputCpt<FID>
72where
73    FID: EzCptIds,
74    CID: EzCptIds,
75    CA: EzArgs,
76    CS: EzState,
77    CM: EzMsg,
78{
79    fn on_event(
80        &mut self,
81        event: EzEvent<CID, CM>,
82        _state: &mut State<CS>,
83    ) -> Vec<EzEvent<CID, CM>> {
84        if let EzEvent::Keyboard(kev) = event {
85            if let KeyCode::Char(' ') = kev.code {
86                self.value = !self.value;
87            }
88        }
89        vec![]
90    }
91
92    fn focusable(&self) -> bool {
93        true
94    }
95}