Skip to main content

ez_tui/components/concrete/
log_viewer.rs

1use crate::inputs::legend::Legend;
2use crate::{
3    AttrValue, Attribute, Component, EzArgs, EzCptIds, EzEvent, EzMsg, EzState, LogsMock, Matcher,
4    MockProps, State,
5};
6use crossterm::event::KeyCode;
7use eztui_derive::DecoratedMockComponent;
8use ratatui::layout::Alignment;
9use std::fmt::Debug;
10use std::marker::PhantomData;
11use tui_logger::TuiWidgetEvent;
12
13/// An implementation of [`Component`] for the [`LogsMock`] component.
14/// **This component initializes `tui_logger` and so it should be instantiated only once.**
15//FEAT: This does only the basics. I should add some features via events. But for this I need a way to register events... Probably adding an enum in the lib under a feature flag with a Event::StdLib(...)
16#[derive(DecoratedMockComponent, Debug)]
17pub struct LogsViewer<CA, CM>
18where
19    CA: EzArgs,
20    CM: EzMsg,
21{
22    component: LogsMock,
23    phantom_args: PhantomData<CA>,
24    phantom_msg: PhantomData<CM>,
25}
26
27impl<CA, CM> Default for LogsViewer<CA, CM>
28where
29    CA: EzArgs,
30    CM: EzMsg,
31{
32    fn default() -> Self {
33        Self::new()
34    }
35}
36
37impl<CA, CM> LogsViewer<CA, CM>
38where
39    CA: EzArgs,
40    CM: EzMsg,
41{
42    /// Create a new [`LogsViewer`] component with the given [`CommonArg`].
43    #[must_use]
44    pub fn new() -> Self {
45        let mut mock = LogsMock::new();
46        if let Some(props) = mock.props_mut() {
47            props.set(
48                Attribute::Title,
49                AttrValue::Title(("Logs".to_string(), Alignment::Center)),
50            );
51        }
52        Self {
53            component: mock,
54            phantom_args: PhantomData,
55            phantom_msg: PhantomData,
56        }
57    }
58}
59impl<CID, CA, CS, CM> Component<CID, CA, CS, CM> for LogsViewer<CA, CM>
60where
61    CID: EzCptIds,
62    CID: EzCptIds,
63    CA: EzArgs,
64    CS: EzState,
65    CM: EzMsg,
66{
67    fn on_event(&mut self, ev: EzEvent<CID, CM>, _: &mut State<CS>) -> Vec<EzEvent<CID, CM>> {
68        if let EzEvent::Keyboard(kv) = ev {
69            match kv.code {
70                KeyCode::Char(' ') => self.component.state.transition(TuiWidgetEvent::SpaceKey),
71                KeyCode::Esc => self.component.state.transition(TuiWidgetEvent::EscapeKey),
72                KeyCode::PageUp => self.component.state.transition(TuiWidgetEvent::PrevPageKey),
73                KeyCode::PageDown => self.component.state.transition(TuiWidgetEvent::NextPageKey),
74                KeyCode::Up => self.component.state.transition(TuiWidgetEvent::UpKey),
75                KeyCode::Down => self.component.state.transition(TuiWidgetEvent::DownKey),
76                KeyCode::Left => self.component.state.transition(TuiWidgetEvent::LeftKey),
77                KeyCode::Right => self.component.state.transition(TuiWidgetEvent::RightKey),
78                KeyCode::Char('+') => self.component.state.transition(TuiWidgetEvent::PlusKey),
79                KeyCode::Char('-') => self.component.state.transition(TuiWidgetEvent::MinusKey),
80                KeyCode::Char('h') => self.component.state.transition(TuiWidgetEvent::HideKey),
81                KeyCode::Char('f') => self.component.state.transition(TuiWidgetEvent::FocusKey),
82                _ => (),
83            }
84        }
85        vec![]
86    }
87    fn focusable(&self) -> bool {
88        true
89    }
90
91    fn legend(&self) -> Option<Legend> {
92        Legend::new(
93            "Logs".into(),
94            vec![
95                Matcher::new(vec![KeyCode::Char(' ').into()], "SpaceKey".into()),
96                Matcher::new(vec![KeyCode::Esc.into()], "EscapeKey".into()),
97                Matcher::new(vec![KeyCode::PageUp.into()], "PageKey".into()),
98                Matcher::new(vec![KeyCode::PageDown.into()], "PageKey".into()),
99                Matcher::new(vec![KeyCode::Up.into()], "UpKey".into()),
100                Matcher::new(vec![KeyCode::Down.into()], "DownKey".into()),
101                Matcher::new(vec![KeyCode::Left.into()], "LeftKey".into()),
102                Matcher::new(vec![KeyCode::Right.into()], "RightKey".into()),
103                Matcher::new(vec![KeyCode::Char('+').into()], "PlusKey".into()),
104                Matcher::new(vec![KeyCode::Char('-').into()], "MinusKey".into()),
105                Matcher::new(vec![KeyCode::Char('h').into()], "hide".into()),
106                Matcher::new(vec![KeyCode::Char('f').into()], "FocusKey".into()),
107            ],
108        )
109        .into()
110    }
111}