Skip to main content

bee_tui/
components.rs

1use crossterm::event::{KeyEvent, MouseEvent};
2use ratatui::{
3    Frame,
4    layout::{Rect, Size},
5};
6use tokio::sync::mpsc::UnboundedSender;
7
8use crate::{action::Action, config::Config, tui::Event};
9
10pub mod api_health;
11pub mod health;
12pub mod log_pane;
13pub mod lottery;
14pub mod manifest;
15pub mod network;
16pub mod peers;
17pub mod pins;
18pub mod scroll;
19pub mod stamps;
20pub mod swap;
21pub mod tags;
22pub mod warmup;
23pub mod watchlist;
24
25/// `Component` is a trait that represents a visual and interactive element of the user interface.
26///
27/// Implementors of this trait can be registered with the main application loop and will be able to
28/// receive events, update state, and be rendered on the screen.
29pub trait Component {
30    /// Register an action handler that can send actions for processing if necessary.
31    ///
32    /// # Arguments
33    ///
34    /// * `tx` - An unbounded sender that can send actions.
35    ///
36    /// # Returns
37    ///
38    /// * [`color_eyre::Result<()>`] - An Ok result or an error.
39    fn register_action_handler(&mut self, tx: UnboundedSender<Action>) -> color_eyre::Result<()> {
40        let _ = tx; // to appease clippy
41        Ok(())
42    }
43    /// Register a configuration handler that provides configuration settings if necessary.
44    ///
45    /// # Arguments
46    ///
47    /// * `config` - Configuration settings.
48    ///
49    /// # Returns
50    ///
51    /// * [`color_eyre::Result<()>`] - An Ok result or an error.
52    fn register_config_handler(&mut self, config: Config) -> color_eyre::Result<()> {
53        let _ = config; // to appease clippy
54        Ok(())
55    }
56    /// Initialize the component with a specified area if necessary.
57    ///
58    /// # Arguments
59    ///
60    /// * `area` - Rectangular area to initialize the component within.
61    ///
62    /// # Returns
63    ///
64    /// * [`color_eyre::Result<()>`] - An Ok result or an error.
65    fn init(&mut self, area: Size) -> color_eyre::Result<()> {
66        let _ = area; // to appease clippy
67        Ok(())
68    }
69    /// Handle incoming events and produce actions if necessary.
70    ///
71    /// # Arguments
72    ///
73    /// * `event` - An optional event to be processed.
74    ///
75    /// # Returns
76    ///
77    /// * [`color_eyre::Result<Option<Action>>`] - An action to be processed or none.
78    fn handle_events(&mut self, event: Option<Event>) -> color_eyre::Result<Option<Action>> {
79        let action = match event {
80            Some(Event::Key(key_event)) => self.handle_key_event(key_event)?,
81            Some(Event::Mouse(mouse_event)) => self.handle_mouse_event(mouse_event)?,
82            _ => None,
83        };
84        Ok(action)
85    }
86    /// Handle key events and produce actions if necessary.
87    ///
88    /// # Arguments
89    ///
90    /// * `key` - A key event to be processed.
91    ///
92    /// # Returns
93    ///
94    /// * [`color_eyre::Result<Option<Action>>`] - An action to be processed or none.
95    fn handle_key_event(&mut self, key: KeyEvent) -> color_eyre::Result<Option<Action>> {
96        let _ = key; // to appease clippy
97        Ok(None)
98    }
99    /// Handle mouse events and produce actions if necessary.
100    ///
101    /// # Arguments
102    ///
103    /// * `mouse` - A mouse event to be processed.
104    ///
105    /// # Returns
106    ///
107    /// * [`color_eyre::Result<Option<Action>>`] - An action to be processed or none.
108    fn handle_mouse_event(&mut self, mouse: MouseEvent) -> color_eyre::Result<Option<Action>> {
109        let _ = mouse; // to appease clippy
110        Ok(None)
111    }
112    /// Update the state of the component based on a received action. (REQUIRED)
113    ///
114    /// # Arguments
115    ///
116    /// * `action` - An action that may modify the state of the component.
117    ///
118    /// # Returns
119    ///
120    /// * [`color_eyre::Result<Option<Action>>`] - An action to be processed or none.
121    fn update(&mut self, action: Action) -> color_eyre::Result<Option<Action>> {
122        let _ = action; // to appease clippy
123        Ok(None)
124    }
125    /// Render the component on the screen. (REQUIRED)
126    ///
127    /// # Arguments
128    ///
129    /// * `f` - A frame used for rendering.
130    /// * `area` - The area in which the component should be drawn.
131    ///
132    /// # Returns
133    ///
134    /// * [`color_eyre::Result<()>`] - An Ok result or an error.
135    fn draw(&mut self, frame: &mut Frame, area: Rect) -> color_eyre::Result<()>;
136
137    /// Downcast hook so the App can reach a concrete screen type
138    /// (e.g. to call `Manifest::load(reference)` from the command bar).
139    /// Default returns `None` so screens that don't need it can ignore
140    /// this method.
141    fn as_any_mut(&mut self) -> Option<&mut dyn std::any::Any> {
142        None
143    }
144}