pub struct Connector<C: Component> { /* private fields */ }
Expand description
Contains the post-launch input sender and output receivers with the root widget.
The receiver can be separated from the Connector
by choosing a method for handling it.
Implementations§
source§impl<C: Component> Connector<C>
impl<C: Component> Connector<C>
sourcepub fn forward<X: 'static, F: Fn(C::Output) -> X + 'static>(
self,
sender_: &Sender<X>,
transform: F
) -> Controller<C>
pub fn forward<X: 'static, F: Fn(C::Output) -> X + 'static>( self, sender_: &Sender<X>, transform: F ) -> Controller<C>
Forwards output events to the designated sender.
Examples found in repository?
examples/message_broker.rs (line 193)
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
fn init(
_init: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let header = Header::builder()
.launch_with_broker((), &HEADER_BROKER)
.forward(sender.input_sender(), identity);
let dialog = Dialog::builder()
.launch(root.clone().upcast())
.forward(sender.input_sender(), identity);
let model = App {
mode: AppMode::View,
header,
dialog,
};
let widgets = view_output!();
ComponentParts { model, widgets }
}
More examples
examples/transient_dialog.rs (line 113)
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
fn init(
_init: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
// We don't have access to the parent window from here
// but we can just use the button to set the transient window for the dialog.
// Relm4 will get the window later by calling [`WidgetExt::root()`]
// on the button once all widgets are connected.
let dialog = Dialog::builder()
.transient_for(&root)
.launch_with_broker((), &DIALOG_BROKER)
.forward(sender.input_sender(), identity);
let model = Button { dialog };
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, _msg: Self::Input, _sender: ComponentSender<Self>) {}
}
#[derive(Debug)]
enum AppMsg {}
struct App {
button: Controller<Button>,
}
#[relm4::component]
impl SimpleComponent for App {
type Init = ();
type Input = AppMsg;
type Output = ();
view! {
main_window = gtk::ApplicationWindow {
set_default_size: (500, 250),
set_child: Some(model.button.widget()),
}
}
fn init(
_init: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let button = Button::builder()
.launch(())
.forward(sender.input_sender(), identity);
let model = App { button };
let widgets = view_output!();
ComponentParts { model, widgets }
}
examples/components.rs (line 184)
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
fn init(
_: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let header = Header::builder()
.launch(())
.forward(sender.input_sender(), identity);
let dialog = Dialog::builder()
.transient_for(&root)
.launch(DialogInit {
text: "Do you want to close before saving?".to_string(),
secondary_text: Some("All unsaved changes will be lost".to_string()),
accept_text: "Close".to_string(),
cancel_text: "Cancel".to_string(),
})
.forward(sender.input_sender(), identity);
let model = App {
mode: AppMode::View,
header,
dialog,
};
let widgets = view_output!();
ComponentParts { model, widgets }
}
sourcepub fn connect_receiver<F: FnMut(&mut Sender<C::Input>, C::Output) + 'static>(
self,
func: F
) -> Controller<C>
pub fn connect_receiver<F: FnMut(&mut Sender<C::Input>, C::Output) + 'static>( self, func: F ) -> Controller<C>
Given a mutable closure, captures the receiver for handling.
Examples found in repository?
examples/settings_list.rs (lines 29-68)
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 66 67 68 69 70 71 72 73 74 75
fn main() {
gtk::Application::builder()
.application_id("org.relm4.SettingsListExample")
.launch(|_app, window| {
// Initialize a component's root widget
let mut component = App::builder()
// Attach the root widget to the given window.
.attach_to(&window)
// Start the component service with an initial parameter
.launch("Settings List Demo".into())
// Attach the returned receiver's messages to this closure.
.connect_receiver(move |sender, message| match message {
Output::Clicked(id) => {
eprintln!("ID {id} Clicked");
match id {
0 => xdg_open("https://github.com/Relm4/Relm4".into()),
1 => xdg_open("https://docs.rs/relm4/".into()),
2 => {
sender.send(Input::Clear).unwrap();
}
_ => (),
}
}
Output::Reload => {
sender
.send(Input::AddSetting {
description: "Browse GitHub Repository".into(),
button: "GitHub".into(),
id: 0,
})
.unwrap();
sender
.send(Input::AddSetting {
description: "Browse Documentation".into(),
button: "Docs".into(),
id: 1,
})
.unwrap();
sender
.send(Input::AddSetting {
description: "Clear List".into(),
button: "Clear".into(),
id: 2,
})
.unwrap();
}
});
// Keep runtime alive after the component is dropped
component.detach_runtime();
println!("parent is {:?}", component.widget().toplevel_window());
});
}
sourcepub fn detach(self) -> Controller<C>
pub fn detach(self) -> Controller<C>
Ignore outputs from the component and finish the builder.
sourcepub fn into_stream(self) -> ComponentStream<C>
pub fn into_stream(self) -> ComponentStream<C>
Convert his type into a Stream
that yields output events
as futures.
Examples found in repository?
examples/message_stream.rs (line 149)
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>, root: &Self::Root) {
match msg {
AppMsg::StartSearch => {
self.searching = true;
let stream = Dialog::builder()
.transient_for(root)
.launch(())
.into_stream();
sender.oneshot_command(async move {
// Use the component as stream
let result = stream.recv_one().await;
if let Some(search) = result {
let response =
reqwest::get(format!("https://duckduckgo.com/lite/?q={search}"))
.await
.unwrap();
let response_text = response.text().await.unwrap();
// Extract the url of the first search result.
if let Some(url) = response_text.split("<a rel=\"nofollow\" href=\"").nth(1)
{
let url = url.split('\"').next().unwrap().replace("amp;", "");
Some(format!("https:{url}"))
} else {
None
}
} else {
None
}
});
}
}
}
Trait Implementations§
source§impl<C: Component> ComponentController<C> for Connector<C>
impl<C: Component> ComponentController<C> for Connector<C>
source§fn state(&self) -> &StateWatcher<C>
fn state(&self) -> &StateWatcher<C>
Provides access to the state of a component.
source§fn detach_runtime(&mut self)
fn detach_runtime(&mut self)
Dropping this type will usually stop the runtime of the component.
With this method you can give the runtime a static lifetime.
In other words, dropping the controller or connector will not stop
the runtime anymore, instead it will run until the app is closed.
Auto Trait Implementations§
impl<C> Freeze for Connector<C>
impl<C> !RefUnwindSafe for Connector<C>
impl<C> !Send for Connector<C>
impl<C> !Sync for Connector<C>
impl<C> Unpin for Connector<C>
impl<C> !UnwindSafe for Connector<C>
Blanket Implementations§
source§impl<C> AsyncPosition<()> for C
impl<C> AsyncPosition<()> for C
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more