pub struct Child<T>where
T: Component,{ /* private fields */ }Available on crate feature
winio only.Expand description
Helper to embed one component into another. It handles different types of messages and events.
Implementations§
Source§impl<T> Child<T>where
T: Component,
impl<T> Child<T>where
T: Component,
Sourcepub fn init<'a>(init: impl Into<<T as Component>::Init<'a>>) -> Child<T>
pub fn init<'a>(init: impl Into<<T as Component>::Init<'a>>) -> Child<T>
Create and initialize the child component.
Examples found in repository?
examples/options/options.rs (line 39)
35 fn init(mut init: Self::Init<'_>, sender: &ComponentSender<Self>) -> Self {
36 let mut window = init.window(sender);
37 // window.set_size(Size::new(800.0, 600.0));
38
39 let mut enabled = Child::<CheckBox>::init(&window);
40 enabled.set_text("Enable");
41
42 let mut b = Child::<CheckBox>::init(&window);
43 b.set_text("Switch");
44
45 let mut e_label = Child::<Label>::init(&window);
46 e_label.set_text("Mode:");
47 let mut e = Child::<ComboBox>::init(&window);
48 e.insert(0, "A");
49 e.insert(1, "B");
50
51 let mut s_label = Child::<Label>::init(&window);
52 s_label.set_text("Message:");
53 let mut s = Child::<Edit>::init(&window);
54
55 HANDLER.with_app(|a| {
56 let config = a.config();
57
58 enabled.set_checked(config.enabled);
59 b.set_checked(config.b);
60
61 e.set_selection(Some(match config.e {
62 Mode::A => 0,
63 Mode::B => 1,
64 }));
65
66 s.set_text(&config.s);
67 });
68
69 sender.post(MainMessage::EnabledClick);
70
71 window.show();
72
73 Self {
74 window,
75 enabled,
76 b,
77 s_label,
78 s,
79 e_label,
80 e,
81 }
82 }Sourcepub async fn start<C>(
&mut self,
sender: &ComponentSender<C>,
f: impl FnMut(<T as Component>::Event) -> Option<<C as Component>::Message>,
propagate: impl FnMut() -> <C as Component>::Message,
) -> !where
C: Component,
pub async fn start<C>(
&mut self,
sender: &ComponentSender<C>,
f: impl FnMut(<T as Component>::Event) -> Option<<C as Component>::Message>,
propagate: impl FnMut() -> <C as Component>::Message,
) -> !where
C: Component,
Start to receive and interp the events of the child component.
Define a root component MainModel, and it contains a
window: Child<Window>. The message of MainModel is defined as
ⓘ
enum MainMessage {
Noop,
Close,
}In the MainModel::start, you should write
ⓘ
async fn start(&mut self, sender: &ComponentSender<Self>) {
start! {
sender, default: MainMessage::Noop,
self.window => {
WindowEvent::Close => MainMessage::Close,
},
// ...other children
}
}It is equivalent to
ⓘ
async fn start(&mut self, sender: &ComponentSender<Self>) {
let fut_window = self.window.start(
sender,
|e| match e {
WindowEvent::Close => Some(MainMessage::Close),
// ignore other events
_ => None,
},
// you should always propagate internal messages
|| MainMessage::Noop,
);
// ...other children
futures_util::join!(fut_window, /* ... */);
}Sourcepub async fn emit(&mut self, message: <T as Component>::Message) -> bool
pub async fn emit(&mut self, message: <T as Component>::Message) -> bool
Emit message to the child component.
Examples found in repository?
examples/test/widgets.rs (line 203)
187 async fn update(&mut self, message: Self::Message, sender: &ComponentSender<Self>) -> bool {
188 futures_util::future::join(self.window.update(), self.canvas.update()).await;
189 match message {
190 MainMessage::Noop => false,
191 MainMessage::Close => {
192 sender.output(());
193 false
194 }
195 MainMessage::Redraw => true,
196 MainMessage::PasswordCheck => {
197 self.pentry.set_password(!self.pcheck.is_checked());
198 true
199 }
200 MainMessage::List(e) => {
201 self.pop_button.set_enabled(!self.list.is_empty());
202 self.combo
203 .emit(ComboBoxMessage::from_observable_vec_event(e))
204 .await
205 }
206 MainMessage::Select => {
207 self.index = self.combo.selection();
208 false
209 }
210 MainMessage::Push => {
211 self.list.push(
212 match self.rindex {
213 0 => &self.r1,
214 1 => &self.r2,
215 2 => &self.r3,
216 _ => unreachable!(),
217 }
218 .text(),
219 );
220 false
221 }
222 MainMessage::Pop => {
223 self.list.pop();
224 false
225 }
226 MainMessage::RSelect(i) => {
227 self.rindex = i;
228 false
229 }
230 MainMessage::Show => {
231 MessageBox::new()
232 .title("Show selected item")
233 .message(
234 self.index
235 .and_then(|index| self.list.get(index))
236 .map(|s| s.as_str())
237 .unwrap_or("No selection."),
238 )
239 .buttons(MessageBoxButton::Ok)
240 .show(&self.window)
241 .await;
242 false
243 }
244 MainMessage::OptionsPage(m) => {
245 tracing::debug!(?m, "Options page message");
246 match m {
247 OptionsPageMessage::Save(config, tx) => {
248 config.s = self.mltext.text();
249 tx.send(config).unwrap()
250 }
251 }
252 false
253 }
254 }
255 }Sourcepub async fn update(&mut self) -> bool
pub async fn update(&mut self) -> bool
Respond to the child message.
Examples found in repository?
examples/options/options.rs (line 98)
97 async fn update(&mut self, message: Self::Message, sender: &ComponentSender<Self>) -> bool {
98 futures_util::join!(self.window.update());
99 match message {
100 MainMessage::Noop => false,
101 MainMessage::Close => {
102 sender.output(());
103 false
104 }
105 MainMessage::Redraw => true,
106 MainMessage::EnabledClick => {
107 let enabled = self.enabled.is_checked();
108 self.b.set_enabled(enabled);
109 self.e.set_enabled(enabled);
110 self.s.set_enabled(enabled);
111 false
112 }
113 MainMessage::OptionsPage(m) => {
114 tracing::debug!(?m, "Options page message");
115 match m {
116 OptionsPageMessage::Save(config, tx) => {
117 config.enabled = self.enabled.is_checked();
118 config.b = self.b.is_checked();
119 config.e = match self.e.selection() {
120 Some(0) => Mode::A,
121 Some(1) => Mode::B,
122 _ => Default::default(),
123 };
124 config.s = self.s.text();
125 tx.send(config).unwrap()
126 }
127 }
128 false
129 }
130 }
131 }More examples
examples/test/widgets.rs (line 188)
187 async fn update(&mut self, message: Self::Message, sender: &ComponentSender<Self>) -> bool {
188 futures_util::future::join(self.window.update(), self.canvas.update()).await;
189 match message {
190 MainMessage::Noop => false,
191 MainMessage::Close => {
192 sender.output(());
193 false
194 }
195 MainMessage::Redraw => true,
196 MainMessage::PasswordCheck => {
197 self.pentry.set_password(!self.pcheck.is_checked());
198 true
199 }
200 MainMessage::List(e) => {
201 self.pop_button.set_enabled(!self.list.is_empty());
202 self.combo
203 .emit(ComboBoxMessage::from_observable_vec_event(e))
204 .await
205 }
206 MainMessage::Select => {
207 self.index = self.combo.selection();
208 false
209 }
210 MainMessage::Push => {
211 self.list.push(
212 match self.rindex {
213 0 => &self.r1,
214 1 => &self.r2,
215 2 => &self.r3,
216 _ => unreachable!(),
217 }
218 .text(),
219 );
220 false
221 }
222 MainMessage::Pop => {
223 self.list.pop();
224 false
225 }
226 MainMessage::RSelect(i) => {
227 self.rindex = i;
228 false
229 }
230 MainMessage::Show => {
231 MessageBox::new()
232 .title("Show selected item")
233 .message(
234 self.index
235 .and_then(|index| self.list.get(index))
236 .map(|s| s.as_str())
237 .unwrap_or("No selection."),
238 )
239 .buttons(MessageBoxButton::Ok)
240 .show(&self.window)
241 .await;
242 false
243 }
244 MainMessage::OptionsPage(m) => {
245 tracing::debug!(?m, "Options page message");
246 match m {
247 OptionsPageMessage::Save(config, tx) => {
248 config.s = self.mltext.text();
249 tx.send(config).unwrap()
250 }
251 }
252 false
253 }
254 }
255 }Sourcepub fn render(&mut self)
pub fn render(&mut self)
Render the child component.
Examples found in repository?
examples/options/options.rs (line 134)
133 fn render(&mut self, _sender: &ComponentSender<Self>) {
134 self.window.render();
135
136 let csize = self.window.client_size();
137
138 let m = Margin::new(5., 0., 5., 0.);
139 let m_l = Margin::new(0., 5., 0., 0.);
140
141 let mut form = layout! {
142 Grid::from_str("auto,1*", "auto,auto").unwrap(),
143 self.e_label => { column: 0, row: 0, margin: m_l, valign: VAlign::Center },
144 self.e => { column: 1, row: 0, margin: m },
145 self.s_label => { column: 0, row: 1, margin: m_l, valign: VAlign::Center },
146 self.s => { column: 1, row: 1, margin: m },
147 };
148
149 let mut grid = layout! {
150 Grid::from_str("auto,1*", "auto,auto,auto,1*").unwrap(),
151 self.enabled => { column: 0, row: 0, margin: m },
152 self.b => { column: 0, row: 1, margin: m },
153 form => { column: 0, row: 2, margin: m },
154 };
155 grid.set_size(csize);
156 }Trait Implementations§
Source§impl<T> AsRawWidget for Child<T>where
T: AsRawWidget + Component,
impl<T> AsRawWidget for Child<T>where
T: AsRawWidget + Component,
Source§fn as_raw_widget(&self) -> RawWidget
fn as_raw_widget(&self) -> RawWidget
Get the raw window handle.
Source§impl<T> AsRawWindow for Child<T>where
T: AsRawWindow + Component,
impl<T> AsRawWindow for Child<T>where
T: AsRawWindow + Component,
Source§fn as_raw_window(&self) -> RawWindow
fn as_raw_window(&self) -> RawWindow
Get the raw window handle.
Source§impl<T> AsWidget for Child<T>
impl<T> AsWidget for Child<T>
Source§fn as_widget(&self) -> BorrowedWidget<'_>
fn as_widget(&self) -> BorrowedWidget<'_>
Get the window handle.
Source§impl<T> AsWindow for Child<T>
impl<T> AsWindow for Child<T>
Source§fn as_window(&self) -> BorrowedWindow<'_>
fn as_window(&self) -> BorrowedWindow<'_>
Get the window handle.
Source§impl<T> Layoutable for Child<T>where
T: Component + Layoutable,
impl<T> Layoutable for Child<T>where
T: Component + Layoutable,
Source§fn preferred_size(&self) -> Size2D<f64, LogicalSpace>
fn preferred_size(&self) -> Size2D<f64, LogicalSpace>
The preferred size.
Auto Trait Implementations§
impl<T> Freeze for Child<T>
impl<T> !RefUnwindSafe for Child<T>
impl<T> Send for Child<T>
impl<T> Sync for Child<T>
impl<T> Unpin for Child<T>
impl<T> !UnwindSafe for Child<T>
Blanket Implementations§
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
Source§impl<T, A> DynAccess<T> for A
impl<T, A> DynAccess<T> for A
Source§fn load(&self) -> DynGuard<T>
fn load(&self) -> DynGuard<T>
The equivalent of
Access::load.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more