1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use tui::widgets::{Paragraph, Widget};

use crate::{
    components::{FooterWidget, ProxyGroupFocusStatus, ProxyTree},
    get_block, get_focused_block,
};

#[derive(Clone, Debug)]
pub struct ProxyTreeWidget<'a> {
    state: &'a ProxyTree<'a>,
}

impl<'a> ProxyTreeWidget<'a> {
    pub fn new(state: &'a ProxyTree<'a>) -> Self {
        Self { state }
    }
}

impl<'a> Widget for ProxyTreeWidget<'a> {
    fn render(self, area: tui::layout::Rect, buf: &mut tui::buffer::Buffer) {
        let cursor = &self.state.cursor;
        let skip = if self.state.expanded {
            *cursor
        } else {
            cursor.saturating_sub(2)
        };
        let text = self
            .state
            .groups
            .iter()
            .skip(skip)
            .enumerate()
            .map(|(i, x)| {
                x.get_widget(
                    area.width as usize,
                    match (self.state.expanded, *cursor == i + skip) {
                        (true, true) => ProxyGroupFocusStatus::Expanded,
                        (false, true) => ProxyGroupFocusStatus::Focused,
                        _ => ProxyGroupFocusStatus::None,
                    },
                )
            })
            .reduce(|mut a, b| {
                a.extend(b);
                a
            })
            .unwrap_or_default()
            .into_iter()
            .take(area.height as usize)
            .collect::<Vec<_>>();

        let block = if self.state.expanded {
            get_focused_block("Proxies")
        } else {
            get_block("Proxies")
        };

        let inner = block.inner(area);

        block.render(area, buf);

        Paragraph::new(text).render(inner, buf);
        FooterWidget::new(&self.state.footer).render(area, buf);
    }
}