nrelm-components 0.1.1

An idiomatic GUI library inspired by Elm and based on gtk3-rs
use gtk::prelude::*;
use nrelm::factory::{DynamicIndex, FactoryComponent, FactorySender, FactoryView};
use nrelm::gtk;

use super::OpenButtonMsg;

use std::path::PathBuf;

#[derive(Debug)]
pub(crate) struct FileListItem {
    pub(crate) path: PathBuf,
}

#[nrelm::factory(pub(crate))]
impl FactoryComponent for FileListItem {
    type CommandOutput = ();
    type Input = ();
    type Init = PathBuf;
    type ParentWidget = gtk::ListBox;
    type Output = OpenButtonMsg;

    view! {
        gtk::ListBoxRow {
            set_focusable: true,

            gtk::Label {
                set_text: self.path.iter().next_back().expect("Empty path").to_str().unwrap(),
                set_margin: 6,
            },
        }
    }

    fn init_model(init: Self::Init, _: &DynamicIndex, _: FactorySender<Self>) -> Self {
        Self { path: init }
    }

    fn init_widgets(
        &mut self,
        index: &Self::Index,
        root: Self::Root,
        _returned_widget: &<Self::ParentWidget as FactoryView>::ReturnedWidget,
        sender: FactorySender<Self>,
    ) -> Self::Widgets {
        let widgets = view_output!();

        // In GTK3, mouse clicks on a row emit `row-activated` on the
        // `GtkListBox` (and not the row's own `activate` signal, which is only
        // emitted by Enter/Space), so handle activation on the parent list box
        // and match the activated row by identity.
        let index = index.clone();
        if let Some(list) = root
            .parent()
            .and_then(|p| p.downcast::<gtk::ListBox>().ok())
        {
            list.connect_row_activated(move |_, activated| {
                if activated == &root {
                    sender
                        .output(OpenButtonMsg::OpenRecent(index.clone()))
                        .unwrap();
                }
            });
        }

        widgets
    }
}