tui_logger/widget/
inner.rs

1use std::sync::Arc;
2
3use log::LevelFilter;
4use parking_lot::Mutex;
5
6use crate::{set_level_for_target, LevelConfig};
7
8#[derive(Clone, Copy, Debug)]
9pub(crate) struct LinePointer {
10    pub event_index: usize, // into event buffer
11    pub subline: usize,
12}
13
14/// This struct contains the shared state of a TuiLoggerWidget and a TuiLoggerTargetWidget.
15#[derive(Default)]
16pub struct TuiWidgetState {
17    inner: Arc<Mutex<TuiWidgetInnerState>>,
18}
19impl TuiWidgetState {
20    /// Create a new TuiWidgetState
21    pub fn new() -> TuiWidgetState {
22        TuiWidgetState {
23            inner: Arc::new(Mutex::new(TuiWidgetInnerState::new())),
24        }
25    }
26    pub fn set_default_display_level(self, levelfilter: LevelFilter) -> TuiWidgetState {
27        self.inner
28            .lock()
29            .config
30            .set_default_display_level(levelfilter);
31        self
32    }
33    pub fn set_level_for_target(self, target: &str, levelfilter: LevelFilter) -> TuiWidgetState {
34        self.inner.lock().config.set(target, levelfilter);
35        self
36    }
37    pub fn transition(&self, event: TuiWidgetEvent) {
38        self.inner.lock().transition(event);
39    }
40    pub fn clone_state(&self) -> Arc<Mutex<TuiWidgetInnerState>> {
41        self.inner.clone()
42    }
43}
44
45#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
46pub enum TuiWidgetEvent {
47    SpaceKey,
48    UpKey,
49    DownKey,
50    LeftKey,
51    RightKey,
52    PlusKey,
53    MinusKey,
54    HideKey,
55    FocusKey,
56    PrevPageKey,
57    NextPageKey,
58    EscapeKey,
59}
60
61#[derive(Default)]
62pub struct TuiWidgetInnerState {
63    pub(crate) config: LevelConfig,
64    pub(crate) nr_items: usize,
65    pub(crate) selected: usize,
66    pub(crate) opt_line_pointer_center: Option<LinePointer>,
67    pub(crate) opt_line_pointer_next_page: Option<LinePointer>,
68    pub(crate) opt_line_pointer_prev_page: Option<LinePointer>,
69    pub(crate) opt_selected_target: Option<String>,
70    pub(crate) opt_selected_visibility_more: Option<LevelFilter>,
71    pub(crate) opt_selected_visibility_less: Option<LevelFilter>,
72    pub(crate) opt_selected_recording_more: Option<LevelFilter>,
73    pub(crate) opt_selected_recording_less: Option<LevelFilter>,
74    pub(crate) offset: usize,
75    pub(crate) hide_off: bool,
76    pub(crate) hide_target: bool,
77    pub(crate) focus_selected: bool,
78}
79impl TuiWidgetInnerState {
80    pub fn new() -> TuiWidgetInnerState {
81        TuiWidgetInnerState::default()
82    }
83    fn transition(&mut self, event: TuiWidgetEvent) {
84        use TuiWidgetEvent::*;
85        match event {
86            SpaceKey => {
87                self.hide_off ^= true;
88            }
89            HideKey => {
90                self.hide_target ^= true;
91            }
92            FocusKey => {
93                self.focus_selected ^= true;
94            }
95            UpKey => {
96                if !self.hide_target && self.selected > 0 {
97                    self.selected -= 1;
98                }
99            }
100            DownKey => {
101                if !self.hide_target && self.selected + 1 < self.nr_items {
102                    self.selected += 1;
103                }
104            }
105            LeftKey => {
106                if let Some(selected_target) = self.opt_selected_target.take() {
107                    if let Some(selected_visibility_less) = self.opt_selected_visibility_less.take()
108                    {
109                        self.config.set(&selected_target, selected_visibility_less);
110                    }
111                }
112            }
113            RightKey => {
114                if let Some(selected_target) = self.opt_selected_target.take() {
115                    if let Some(selected_visibility_more) = self.opt_selected_visibility_more.take()
116                    {
117                        self.config.set(&selected_target, selected_visibility_more);
118                    }
119                }
120            }
121            PlusKey => {
122                if let Some(selected_target) = self.opt_selected_target.take() {
123                    if let Some(selected_recording_more) = self.opt_selected_recording_more.take() {
124                        set_level_for_target(&selected_target, selected_recording_more);
125                    }
126                }
127            }
128            MinusKey => {
129                if let Some(selected_target) = self.opt_selected_target.take() {
130                    if let Some(selected_recording_less) = self.opt_selected_recording_less.take() {
131                        set_level_for_target(&selected_target, selected_recording_less);
132                    }
133                }
134            }
135            PrevPageKey => self.opt_line_pointer_center = self.opt_line_pointer_prev_page,
136            NextPageKey => self.opt_line_pointer_center = self.opt_line_pointer_next_page,
137            EscapeKey => self.opt_line_pointer_center = None,
138        }
139    }
140}