Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
tui: Support container focus
Erik Kundt committed 2 years ago
commit 3a7cef8ceafd66d6f5b0057d64e950e30dc39f6e
parent dcfd4814248b005d8f9ef98ee3cd9feeec4e0cd3
7 files changed +95 -25
modified radicle-tui/src/app/page.rs
@@ -111,8 +111,8 @@ impl ViewPage for HomeView {
    ) -> Result<()> {
        if let Message::NavigationChanged(index) = message {
            self.active_component = Cid::Home(HomeCid::from(index as usize));
+
            app.active(&self.active_component)?;
        }
-
        app.active(&self.active_component)?;

        Ok(())
    }
@@ -148,16 +148,12 @@ impl ViewPage for HomeView {
/// Issue detail page
///
pub struct IssuePage {
-
    active_component: Cid,
    issue: (IssueId, Issue),
}

impl IssuePage {
    pub fn new(issue: (IssueId, Issue)) -> Self {
-
        IssuePage {
-
            active_component: Cid::Issue(IssueCid::List),
-
            issue,
-
        }
+
        IssuePage { issue }
    }
}

@@ -186,7 +182,7 @@ impl ViewPage for IssuePage {
        app.remount(Cid::Issue(IssueCid::Details), details, vec![])?;
        app.remount(Cid::Issue(IssueCid::Shortcuts), shortcuts, vec![])?;

-
        app.active(&self.active_component)?;
+
        app.active(&Cid::Issue(IssueCid::List))?;

        Ok(())
    }
@@ -212,8 +208,14 @@ impl ViewPage for IssuePage {
                let details = widget::issue::details(context, theme, (id, issue)).to_boxed();
                app.remount(Cid::Issue(IssueCid::Details), details, vec![])?;
            }
+
            Message::Issue(IssueMessage::FocusList) => {
+
                app.active(&Cid::Issue(IssueCid::List))?;
+
            }
+
            Message::Issue(IssueMessage::FocusDiscussion) => {
+
                app.active(&Cid::Issue(IssueCid::Discussion))?;
+
            }
+
            _ => {}
        }
-
        app.active(&self.active_component)?;

        Ok(())
    }
modified radicle-tui/src/ui/theme.rs
@@ -36,6 +36,8 @@ pub struct Colors {
    pub context_id_fg: Color,
    pub context_id_bg: Color,
    pub context_id_author_fg: Color,
+
    pub container_border_fg: Color,
+
    pub container_border_focus_fg: Color,
}

#[derive(Debug, Clone)]
@@ -105,6 +107,8 @@ pub fn default_dark() -> Theme {
            context_id_fg: Color::Cyan,
            context_id_bg: COLOR_DEFAULT_DARKEST,
            context_id_author_fg: Color::Gray,
+
            container_border_fg: COLOR_DEFAULT_DARKEST,
+
            container_border_focus_fg: COLOR_DEFAULT_DARK,
        },
        icons: Icons {
            property_divider: '∙',
modified radicle-tui/src/ui/widget/common.rs
@@ -45,8 +45,8 @@ pub fn container_header(theme: &Theme, label: Widget<Label>) -> Widget<Header<1>
    Widget::new(header)
}

-
pub fn container(_theme: &Theme, component: Box<dyn MockComponent>) -> Widget<Container> {
-
    let container = Container::new(component);
+
pub fn container(theme: &Theme, component: Box<dyn MockComponent>) -> Widget<Container> {
+
    let container = Container::new(component, theme.clone());
    Widget::new(container)
}

@@ -59,7 +59,7 @@ pub fn labeled_container(
        theme,
        label(&format!(" {title} ")).foreground(theme.colors.default_fg),
    );
-
    let container = LabeledContainer::new(header, component);
+
    let container = LabeledContainer::new(header, component, theme.clone());

    Widget::new(container)
}
modified radicle-tui/src/ui/widget/common/container.rs
@@ -1,7 +1,5 @@
use tuirealm::command::{Cmd, CmdResult};
-
use tuirealm::props::{
-
    AttrValue, Attribute, BorderSides, BorderType, Color, Props, Style, TextModifiers,
-
};
+
use tuirealm::props::{AttrValue, Attribute, BorderSides, BorderType, Props, Style, TextModifiers};
use tuirealm::tui::layout::{Constraint, Direction, Layout, Rect};
use tuirealm::tui::widgets::{Block, Cell, Row};
use tuirealm::{Frame, MockComponent, State, StateValue};
@@ -276,10 +274,20 @@ impl<const W: usize> WidgetComponent for Header<W> {
        let display = properties
            .get_or(Attribute::Display, AttrValue::Flag(true))
            .unwrap_flag();
+
        let focus = properties
+
            .get_or(Attribute::Focus, AttrValue::Flag(false))
+
            .unwrap_flag();
+

+
        let color = if focus {
+
            self.theme.colors.container_border_focus_fg
+
        } else {
+
            self.theme.colors.container_border_fg
+
        };
+

        if display {
            let block = HeaderBlock::default()
                .borders(BorderSides::all())
-
                .border_style(Style::default().fg(Color::Rgb(48, 48, 48)))
+
                .border_style(Style::default().fg(color))
                .border_type(BorderType::Rounded);
            frame.render_widget(block, area);

@@ -322,11 +330,12 @@ impl<const W: usize> WidgetComponent for Header<W> {

pub struct Container {
    component: Box<dyn MockComponent>,
+
    theme: Theme,
}

impl Container {
-
    pub fn new(component: Box<dyn MockComponent>) -> Self {
-
        Self { component }
+
    pub fn new(component: Box<dyn MockComponent>, theme: Theme) -> Self {
+
        Self { component, theme }
    }
}

@@ -335,6 +344,15 @@ impl WidgetComponent for Container {
        let display = properties
            .get_or(Attribute::Display, AttrValue::Flag(true))
            .unwrap_flag();
+
        let focus = properties
+
            .get_or(Attribute::Focus, AttrValue::Flag(false))
+
            .unwrap_flag();
+

+
        let color = if focus {
+
            self.theme.colors.container_border_focus_fg
+
        } else {
+
            self.theme.colors.container_border_fg
+
        };

        if display {
            // Make some space on the left
@@ -349,7 +367,7 @@ impl WidgetComponent for Container {

            let block = Block::default()
                .borders(BorderSides::ALL)
-
                .border_style(Style::default().fg(Color::Rgb(48, 48, 48)))
+
                .border_style(Style::default().fg(color))
                .border_type(BorderType::Rounded);
            frame.render_widget(block, area);
        }
@@ -367,11 +385,16 @@ impl WidgetComponent for Container {
pub struct LabeledContainer {
    header: Widget<Header<1>>,
    component: Box<dyn MockComponent>,
+
    theme: Theme,
}

impl LabeledContainer {
-
    pub fn new(header: Widget<Header<1>>, component: Box<dyn MockComponent>) -> Self {
-
        Self { header, component }
+
    pub fn new(header: Widget<Header<1>>, component: Box<dyn MockComponent>, theme: Theme) -> Self {
+
        Self {
+
            header,
+
            component,
+
            theme,
+
        }
    }
}

@@ -380,6 +403,16 @@ impl WidgetComponent for LabeledContainer {
        let display = properties
            .get_or(Attribute::Display, AttrValue::Flag(true))
            .unwrap_flag();
+
        let focus = properties
+
            .get_or(Attribute::Focus, AttrValue::Flag(false))
+
            .unwrap_flag();
+

+
        let color = if focus {
+
            self.theme.colors.container_border_focus_fg
+
        } else {
+
            self.theme.colors.container_border_fg
+
        };
+

        let header_height = self
            .header
            .query(Attribute::Height)
@@ -399,14 +432,17 @@ impl WidgetComponent for LabeledContainer {
                .constraints(vec![Constraint::Length(1), Constraint::Min(0)].as_ref())
                .split(layout[1]);
            // reverse draw order: child needs to be drawn first?
+

+
            self.component.attr(Attribute::Focus, AttrValue::Flag(focus));
            self.component.view(frame, inner_layout[1]);

            let block = Block::default()
                .borders(BorderSides::BOTTOM | BorderSides::LEFT | BorderSides::RIGHT)
-
                .border_style(Style::default().fg(Color::Rgb(48, 48, 48)))
+
                .border_style(Style::default().fg(color))
                .border_type(BorderType::Rounded);
            frame.render_widget(block, layout[1]);

+
            self.header.attr(Attribute::Focus, AttrValue::Flag(focus));
            self.header.view(frame, layout[0]);
        }
    }
modified radicle-tui/src/ui/widget/common/list.rs
@@ -225,6 +225,16 @@ where
            .get_or(Attribute::HighlightedColor, AttrValue::Color(Color::Reset))
            .unwrap_color();

+
        let focus = properties
+
            .get_or(Attribute::Focus, AttrValue::Flag(false))
+
            .unwrap_flag();
+

+
        let color = if focus {
+
            self.theme.colors.container_border_focus_fg
+
        } else {
+
            self.theme.colors.container_border_fg
+
        };
+

        let layout = Layout::default()
            .direction(Direction::Vertical)
            .constraints(vec![Constraint::Length(3), Constraint::Min(1)])
@@ -241,7 +251,7 @@ where
            .block(
                Block::default()
                    .borders(BorderSides::BOTTOM | BorderSides::LEFT | BorderSides::RIGHT)
-
                    .border_style(Style::default().fg(Color::Rgb(48, 48, 48)))
+
                    .border_style(Style::default().fg(color))
                    .border_type(BorderType::Rounded),
            )
            .highlight_style(Style::default().bg(highlight))
@@ -253,7 +263,10 @@ where
            self.widths,
            self.theme.clone(),
        ));
+

+
        header.attr(Attribute::Focus, AttrValue::Flag(focus));
        header.view(frame, layout[0]);
+

        frame.render_stateful_widget(table, layout[1], &mut TableState::from(&self.state));
    }

modified radicle-tui/src/ui/widget/home.rs
@@ -106,14 +106,19 @@ impl IssueBrowser {
}

impl WidgetComponent for IssueBrowser {
-
    fn view(&mut self, _properties: &Props, frame: &mut Frame, area: Rect) {
+
    fn view(&mut self, properties: &Props, frame: &mut Frame, area: Rect) {
        let shortcuts_h = self
            .shortcuts
            .query(Attribute::Height)
            .unwrap_or(AttrValue::Size(0))
            .unwrap_size();
+
        let focus = properties
+
            .get_or(Attribute::Focus, AttrValue::Flag(false))
+
            .unwrap_flag();
+

        let layout = layout::root_component(area, shortcuts_h);

+
        self.table.attr(Attribute::Focus, AttrValue::Flag(focus));
        self.table.view(frame, layout[0]);
        self.shortcuts.view(frame, layout[1])
    }
@@ -187,14 +192,19 @@ impl PatchBrowser {
}

impl WidgetComponent for PatchBrowser {
-
    fn view(&mut self, _properties: &Props, frame: &mut Frame, area: Rect) {
+
    fn view(&mut self, properties: &Props, frame: &mut Frame, area: Rect) {
        let shortcuts_h = self
            .shortcuts
            .query(Attribute::Height)
            .unwrap_or(AttrValue::Size(0))
            .unwrap_size();
+
        let focus = properties
+
            .get_or(Attribute::Focus, AttrValue::Flag(false))
+
            .unwrap_flag();
+

        let layout = layout::root_component(area, shortcuts_h);

+
        self.table.attr(Attribute::Focus, AttrValue::Flag(focus));
        self.table.view(frame, layout[0]);
        self.shortcuts.view(frame, layout[1]);
    }
modified radicle-tui/src/ui/widget/issue.rs
@@ -56,7 +56,12 @@ impl LargeList {
}

impl WidgetComponent for LargeList {
-
    fn view(&mut self, _properties: &Props, frame: &mut Frame, area: Rect) {
+
    fn view(&mut self, properties: &Props, frame: &mut Frame, area: Rect) {
+
        let focus = properties
+
            .get_or(Attribute::Focus, AttrValue::Flag(false))
+
            .unwrap_flag();
+

+
        self.list.attr(Attribute::Focus, AttrValue::Flag(focus));
        self.list.view(frame, area);
    }