ez_tui/components/concrete/
log_viewer.rs1use 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#[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 #[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}