pub trait Component: Sized + 'static {
type CommandOutput: Debug + Send + 'static;
type Input: Debug + 'static;
type Output: Debug + 'static;
type Init;
type Root: Debug + Clone;
type Widgets: 'static;
// Required methods
fn init_root() -> Self::Root;
fn init(
init: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self>;
// Provided methods
fn builder() -> ComponentBuilder<Self> { ... }
fn update(
&mut self,
message: Self::Input,
sender: ComponentSender<Self>,
root: &Self::Root,
) { ... }
fn update_cmd(
&mut self,
message: Self::CommandOutput,
sender: ComponentSender<Self>,
root: &Self::Root,
) { ... }
fn update_cmd_with_view(
&mut self,
widgets: &mut Self::Widgets,
message: Self::CommandOutput,
sender: ComponentSender<Self>,
root: &Self::Root,
) { ... }
fn update_view(
&self,
widgets: &mut Self::Widgets,
sender: ComponentSender<Self>,
) { ... }
fn update_with_view(
&mut self,
widgets: &mut Self::Widgets,
message: Self::Input,
sender: ComponentSender<Self>,
root: &Self::Root,
) { ... }
fn shutdown(
&mut self,
widgets: &mut Self::Widgets,
output: Sender<Self::Output>,
) { ... }
fn id(&self) -> String { ... }
}Expand description
The fundamental building block of a Relm4 application.
A Component is an element of an application that defines initialization, state, behavior and
communication as a modular unit.
Component is powerful and flexible, but for many use-cases the SimpleComponent
convenience trait will suffice. SimpleComponent enforces separation between model and view
updates, and provides no-op implementations for advanced features that are not relevant for most
use-cases.
Required Associated Types§
Sourcetype CommandOutput: Debug + Send + 'static
type CommandOutput: Debug + Send + 'static
Messages which are received from commands executing in the background.
Required Methods§
Sourcefn init(
init: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self>
fn init( init: Self::Init, root: Self::Root, sender: ComponentSender<Self>, ) -> ComponentParts<Self>
Creates the initial model and view, docking it into the component.
Provided Methods§
Sourcefn builder() -> ComponentBuilder<Self>
fn builder() -> ComponentBuilder<Self>
Create a builder for this component.
Examples found in repository?
66 fn init(
67 _: Self::Init,
68 root: Self::Root,
69 sender: ComponentSender<Self>,
70 ) -> ComponentParts<Self> {
71 let image = WebImage::builder().launch(IMAGES[0].to_owned()).detach();
72 let model = App { image, idx: 0 };
73
74 let image = model.image.widget();
75 let widgets = view_output!();
76
77 ComponentParts { model, widgets }
78 }More examples
88 fn init(
89 _: Self::Init,
90 root: Self::Root,
91 sender: ComponentSender<Self>,
92 ) -> ComponentParts<Self> {
93 let model = App {
94 counter: 0,
95 worker: AsyncHandler::builder()
96 .detach_worker(())
97 .forward(sender.input_sender(), identity),
98 };
99
100 let widgets = view_output!();
101
102 ComponentParts { model, widgets }
103 }62 fn init(
63 _: Self::Init,
64 root: Self::Root,
65 sender: ComponentSender<Self>,
66 ) -> ComponentParts<Self> {
67 let model = App {
68 combo_row: SimpleComboRow::builder()
69 .launch(SimpleComboRow {
70 variants: vec!["Variant 1", "Variant 2"],
71 active_index: None,
72 })
73 .forward(sender.input_sender(), AppMsg::Selected),
74 selected_variant: 0,
75 };
76
77 let combo_row = model.combo_row.widget();
78 let widgets = view_output!();
79
80 ComponentParts { model, widgets }
81 }186 fn init(
187 _init: Self::Init,
188 root: Self::Root,
189 sender: ComponentSender<Self>,
190 ) -> ComponentParts<Self> {
191 let header = Header::builder()
192 .launch_with_broker((), &HEADER_BROKER)
193 .forward(sender.input_sender(), identity);
194
195 let dialog = Dialog::builder()
196 .launch(root.clone().upcast())
197 .forward(sender.input_sender(), identity);
198
199 let model = App {
200 mode: AppMode::View,
201 header,
202 dialog,
203 };
204
205 let widgets = view_output!();
206
207 ComponentParts { model, widgets }
208 }45 fn init(
46 _: Self::Init,
47 root: Self::Root,
48 sender: ComponentSender<Self>,
49 ) -> ComponentParts<Self> {
50 let open_button = OpenButton::builder()
51 .launch(OpenButtonSettings {
52 dialog_settings: OpenDialogSettings::default(),
53 icon: None,
54 text: "Open file",
55 recently_opened_files: Some(".recent_files"),
56 max_recent_files: 10,
57 })
58 .forward(sender.input_sender(), AppMsg::Open);
59 let model = App { open_button };
60
61 let widgets = view_output!();
62
63 ComponentParts { model, widgets }
64 }101 fn init(
102 _init: Self::Init,
103 root: Self::Root,
104 sender: ComponentSender<Self>,
105 ) -> ComponentParts<Self> {
106 // We don't have access to the parent window from here
107 // but we can just use the button to set the transient window for the dialog.
108 // Relm4 will get the window later by calling [`WidgetExt::root()`]
109 // on the button once all widgets are connected.
110 let dialog = Dialog::builder()
111 .transient_for(&root)
112 .launch_with_broker((), &DIALOG_BROKER)
113 .forward(sender.input_sender(), identity);
114
115 let model = Button { dialog };
116 let widgets = view_output!();
117 ComponentParts { model, widgets }
118 }
119
120 fn update(&mut self, _msg: Self::Input, _sender: ComponentSender<Self>) {}
121}
122
123#[derive(Debug)]
124enum AppMsg {}
125
126struct App {
127 button: Controller<Button>,
128}
129
130#[relm4::component]
131impl SimpleComponent for App {
132 type Init = ();
133 type Input = AppMsg;
134 type Output = ();
135
136 view! {
137 main_window = gtk::ApplicationWindow {
138 set_default_size: (500, 250),
139 set_child: Some(model.button.widget()),
140 }
141 }
142
143 fn init(
144 _init: Self::Init,
145 root: Self::Root,
146 sender: ComponentSender<Self>,
147 ) -> ComponentParts<Self> {
148 let button = Button::builder()
149 .launch(())
150 .forward(sender.input_sender(), identity);
151 let model = App { button };
152 let widgets = view_output!();
153 ComponentParts { model, widgets }
154 }- relm4-components/examples/combo_box.rs
- relm4/examples/multi_window.rs
- relm4/examples/components.rs
- relm4/examples/navigation_splitview_with_stack.rs
- relm4-components/examples/file_dialogs.rs
- relm4/examples/message_stream.rs
- relm4/examples/drop_sub_components.rs
- relm4-components/examples/alert.rs
- relm4/examples/settings_list.rs
- relm4/examples/state_management.rs
Sourcefn update(
&mut self,
message: Self::Input,
sender: ComponentSender<Self>,
root: &Self::Root,
)
fn update( &mut self, message: Self::Input, sender: ComponentSender<Self>, root: &Self::Root, )
Processes inputs received by the component.
Sourcefn update_cmd(
&mut self,
message: Self::CommandOutput,
sender: ComponentSender<Self>,
root: &Self::Root,
)
fn update_cmd( &mut self, message: Self::CommandOutput, sender: ComponentSender<Self>, root: &Self::Root, )
Defines how the component should respond to command updates.
Sourcefn update_cmd_with_view(
&mut self,
widgets: &mut Self::Widgets,
message: Self::CommandOutput,
sender: ComponentSender<Self>,
root: &Self::Root,
)
fn update_cmd_with_view( &mut self, widgets: &mut Self::Widgets, message: Self::CommandOutput, sender: ComponentSender<Self>, root: &Self::Root, )
Updates the model and view upon completion of a command.
Overriding this method is helpful if you need access to the widgets while processing a command output.
The default implementation of this method calls update_cmd followed by update_view.
If you override this method while using the component macro, you must remember to call
update_view in your implementation. Otherwise, the view will not reflect the updated
model.
Sourcefn update_view(
&self,
widgets: &mut Self::Widgets,
sender: ComponentSender<Self>,
)
fn update_view( &self, widgets: &mut Self::Widgets, sender: ComponentSender<Self>, )
Updates the view after the model has been updated.
Sourcefn update_with_view(
&mut self,
widgets: &mut Self::Widgets,
message: Self::Input,
sender: ComponentSender<Self>,
root: &Self::Root,
)
fn update_with_view( &mut self, widgets: &mut Self::Widgets, message: Self::Input, sender: ComponentSender<Self>, root: &Self::Root, )
Updates the model and view when a new input is received.
Overriding this method is helpful if you need access to the widgets while processing an input.
The default implementation of this method calls update followed by update_view. If
you override this method while using the component macro, you must remember to
call update_view in your implementation. Otherwise, the view will not reflect the
updated model.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.