Skip to main content

mecomp_tui/ui/components/content_view/views/
traits.rs

1use super::ViewData;
2use mecomp_prost::RecordId;
3use ratatui::{
4    layout::{Constraint, Direction, Layout, Rect},
5    widgets::{Scrollbar, Widget},
6};
7use tokio::sync::mpsc::UnboundedSender;
8
9use crate::{
10    state::action::Action,
11    ui::widgets::tree::{item::CheckTreeItem, state::CheckTreeState},
12};
13
14/// Shared functionality for the props of an item view
15pub trait ItemViewProps {
16    /// Get the id of the thing that this view is displaying
17    fn id(&self) -> &RecordId;
18
19    /// Retrieve this view's props from the view data
20    fn retrieve(view_data: &ViewData) -> Option<Self>
21    where
22        Self: Sized;
23
24    /// The title of the view
25    fn title() -> &'static str
26    where
27        Self: Sized;
28
29    /// The string for when no items are checked
30    fn none_checked_string() -> &'static str
31    where
32        Self: Sized;
33
34    fn name() -> &'static str
35    where
36        Self: Sized;
37
38    #[must_use]
39    fn split_area(area: Rect) -> [Rect; 2] {
40        let [info_area, content_area] = Layout::default()
41            .direction(Direction::Vertical)
42            .constraints([Constraint::Length(3), Constraint::Min(4)])
43            .areas(area);
44
45        [info_area, content_area]
46    }
47
48    fn info_widget(&self) -> impl Widget;
49
50    /// Create the tree items for the view
51    ///
52    /// # Errors
53    ///
54    /// Returns an error if the tree items cannot be created, e.g. duplicate ids
55    fn tree_items(&self) -> Result<Vec<CheckTreeItem<'_, String>>, std::io::Error>;
56
57    /// Handle any extra key events specific to this view
58    #[inline]
59    fn handle_extra_key_events(
60        &mut self,
61        _: crossterm::event::KeyEvent,
62        _: UnboundedSender<Action>,
63        _: &mut CheckTreeState<String>,
64    ) {
65    }
66
67    /// Optionally define an additional footer to give instructions for the extra key events
68    #[must_use]
69    fn extra_footer() -> Option<&'static str>
70    where
71        Self: Sized,
72    {
73        None
74    }
75
76    /// Optionally use a scrollbar when rendering the tree
77    #[must_use]
78    fn scrollbar() -> Option<Scrollbar<'static>>
79    where
80        Self: Sized,
81    {
82        None
83    }
84}
85
86pub trait SortableViewProps<Item> {
87    /// This exists essentially because the generic `SortableItemView` doesn't actually know what its items are, per se
88    fn sort_items(&mut self, sort_mode: &impl SortMode<Item>);
89}
90
91pub trait SortMode<T>: ToString + Default {
92    #[must_use]
93    fn next(&self) -> Self;
94    #[must_use]
95    fn prev(&self) -> Self;
96
97    fn sort_items(&self, items: &mut [T]);
98}