relm4_macros

Attribute Macro factory

source
#[factory]
Expand description

Macro that implements relm4::factory::FactoryComponent and generates the corresponding widgets struct.

§Attributes

To create public struct use #[factory(pub)] or #[factory(visibility = pub)].

§Example

use relm4::prelude::*;
use relm4::factory::*;
use gtk::prelude::*;


#[derive(Debug)]
struct Counter {
    value: u8,
}

#[derive(Debug)]
enum CounterMsg {
    Increment,
    Decrement,
}

#[derive(Debug)]
enum CounterOutput {
    SendFront(DynamicIndex),
}

#[relm4_macros::factory(pub)]
impl FactoryComponent for Counter {
    type CommandOutput = ();
    type Init = u8;
    type Input = CounterMsg;
    type Output = CounterOutput;
    type ParentWidget = gtk::Box;
     

    view! {
        root = gtk::Box {
            set_orientation: gtk::Orientation::Horizontal,
            set_spacing: 10,

            #[name(label)]
            gtk::Label {
                #[watch]
                set_label: &self.value.to_string(),
                set_width_chars: 3,
            },

            #[name(add_button)]
            gtk::Button {
                set_label: "+",
                connect_clicked => CounterMsg::Increment,
            },

            #[name(remove_button)]
            gtk::Button {
                set_label: "-",
                connect_clicked => CounterMsg::Decrement,
            },

            #[name(to_front_button)]
            gtk::Button {
                set_label: "To start",
                connect_clicked[sender, index] => move |_| {
                    sender.output(CounterOutput::SendFront(index.clone()));
                }
            }
        }
    }

    fn init_model(
        value: Self::Init,
        _index: &DynamicIndex,
        _sender: FactorySender<Self>,
    ) -> Self {
        Self { value }
    }

    fn update(&mut self, msg: Self::Input, _sender: FactorySender<Self>) {
        match msg {
            CounterMsg::Increment => {
                self.value = self.value.wrapping_add(1);
            }
            CounterMsg::Decrement => {
                self.value = self.value.wrapping_sub(1);
            }
        }
    }
}

Note: the enclosing App view (which has AppMsg as its input) is responsible for adding a forward handler to the FactoryVecDeque, which will translate CounterOutput events into AppMsg events. For example CounterOutput::SendFront(index) => AppMsg::SendFront(index)