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 async fn init<'a>(
init: impl Into<<T as Component>::Init<'a>>,
) -> Result<Child<T>, <T as Component>::Error>
pub async fn init<'a>( init: impl Into<<T as Component>::Init<'a>>, ) -> Result<Child<T>, <T as Component>::Error>
Create and initialize the child component.
Examples found in repository?
examples/options/options.rs (line 42)
35 async fn init(
36 mut init: Self::Init<'_>,
37 sender: &ComponentSender<Self>,
38 ) -> Result<Self, Self::Error> {
39 let mut window = init.window(sender).await?;
40 // window.set_size(Size::new(800.0, 600.0));
41
42 let mut enabled = Child::<CheckBox>::init(&window).await?;
43 enabled.set_text("Enable");
44
45 let mut b = Child::<CheckBox>::init(&window).await?;
46 b.set_text("Switch");
47
48 let mut e_label = Child::<Label>::init(&window).await?;
49 e_label.set_text("Mode:");
50 let mut e = Child::<ComboBox>::init(&window).await?;
51 e.insert(0, "A");
52 e.insert(1, "B");
53
54 let mut s_label = Child::<Label>::init(&window).await?;
55 s_label.set_text("Message:");
56 let mut s = Child::<Edit>::init(&window).await?;
57
58 HANDLER.with_app(|a| {
59 let config = a.config();
60
61 enabled.set_checked(config.enabled);
62 b.set_checked(config.b);
63
64 e.set_selection(match config.e {
65 Mode::A => 0,
66 Mode::B => 1,
67 });
68
69 s.set_text(&config.s);
70 });
71
72 sender.post(MainMessage::EnabledClick);
73
74 window.show();
75
76 Ok(Self {
77 window,
78 enabled,
79 b,
80 s_label,
81 s,
82 e_label,
83 e,
84 })
85 }More examples
examples/test/widgets.rs (line 77)
68 async fn init(
69 mut init: Self::Init<'_>,
70 sender: &ComponentSender<Self>,
71 ) -> Result<Self, Self::Error> {
72 // let mut window = Child::<Window>::init(init);
73 let mut window = init.window(sender).await?;
74 // window.set_text("Widgets example");
75 window.set_size(Size::new(800.0, 600.0));
76
77 let canvas = Child::<Canvas>::init(&window).await?;
78 let mut ulabel = Child::<Label>::init(&window).await?;
79 ulabel.set_text("Username:");
80 ulabel.set_halign(HAlign::Right);
81 let mut plabel = Child::<Label>::init(&window).await?;
82 plabel.set_text("Password:");
83 plabel.set_halign(HAlign::Right);
84 let mut uentry = Child::<Edit>::init(&window).await?;
85 uentry.set_text("AAA");
86 let mut pentry = Child::<Edit>::init(&window).await?;
87 pentry.set_text("123456");
88 pentry.set_password(true);
89 let mut pcheck = Child::<CheckBox>::init(&window).await?;
90 pcheck.set_text("Show");
91 pcheck.set_checked(false);
92 let combo = Child::<ComboBox>::init(&window).await?;
93 let mut list = Child::<ObservableVec<String>>::init(Vec::new())
94 .await
95 .unwrap();
96 // https://www.zhihu.com/question/23600507/answer/140640887
97 list.push("烫烫烫".to_string());
98 list.push("昍昍昍".to_string());
99 list.push("フフフフフフ".to_string());
100 list.push("쳌쳌쳌".to_string());
101 let mut r1 = Child::<RadioButton>::init(&window).await?;
102 r1.set_text("屯屯屯");
103 r1.set_checked(true);
104 let mut r2 = Child::<RadioButton>::init(&window).await?;
105 r2.set_text("锟斤拷");
106 let mut r3 = Child::<RadioButton>::init(&window).await?;
107 r3.set_text("╠╠╠");
108 // Initialize radio group with the radio buttons
109 let radio_group = Child::<RadioButtonGroup>::init(vec![r1, r2, r3]).await?;
110
111 let mut push_button = Child::<Button>::init(&window).await?;
112 push_button.set_text("Push");
113 let mut pop_button = Child::<Button>::init(&window).await?;
114 pop_button.set_text("Pop");
115 let mut show_button = Child::<Button>::init(&window).await?;
116 show_button.set_text("Show");
117 let mut progress = Child::<Progress>::init(&window).await?;
118 progress.set_indeterminate(true);
119 let mut mltext = Child::<TextBox>::init(&window).await?;
120 HANDLER.with_app(|a| mltext.set_text(&a.config().s));
121
122 window.show();
123
124 Ok(Self {
125 window,
126 ulabel,
127 plabel,
128 uentry,
129 pentry,
130 pcheck,
131 canvas,
132 combo,
133 list,
134 index: None,
135 radio_group,
136 rindex: 0,
137 push_button,
138 pop_button,
139 show_button,
140 progress,
141 mltext,
142 })
143 }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 fn post(&mut self, message: <T as Component>::Message)
pub fn post(&mut self, message: <T as Component>::Message)
Post message to the child component.
Sourcepub async fn emit(
&mut self,
message: <T as Component>::Message,
) -> Result<bool, <T as Component>::Error>
pub async fn emit( &mut self, message: <T as Component>::Message, ) -> Result<bool, <T as Component>::Error>
Emit message to the child component.
Examples found in repository?
examples/test/widgets.rs (line 191)
176 async fn update(
177 &mut self,
178 message: Self::Message,
179 sender: &ComponentSender<Self>,
180 ) -> Result<bool, Self::Error> {
181 // futures_util::future::join(self.window.update(), self.canvas.update()).await;
182 Ok(match message {
183 MainMessage::Noop => false,
184 MainMessage::PasswordCheck => {
185 self.pentry.set_password(!self.pcheck.is_checked()?);
186 true
187 }
188 MainMessage::List(e) => {
189 self.pop_button.set_enabled(!self.list.is_empty());
190 self.combo
191 .emit(ComboBoxMessage::from_observable_vec_event(e))
192 .await?
193 }
194 MainMessage::Select => {
195 self.index = self.combo.selection()?;
196 false
197 }
198 MainMessage::Push => {
199 self.list.push(self.radio_group[self.rindex].text()?);
200 false
201 }
202 MainMessage::Pop => {
203 self.list.pop();
204 false
205 }
206 MainMessage::RSelect(i) => {
207 self.rindex = i;
208 false
209 }
210 MainMessage::Show => {
211 MessageBox::new()
212 .title("Show selected item")
213 .message(
214 self.index
215 .and_then(|index| self.list.get(index))
216 .map(|s| s.as_str())
217 .unwrap_or("No selection."),
218 )
219 .buttons(MessageBoxButton::Ok)
220 // https://github.com/compio-rs/winio/issues/105
221 .show(unsafe { BorrowedWindow::win32(self.window.as_container().as_win32()) })
222 .await;
223 false
224 }
225 MainMessage::OptionsPage(m) => {
226 tracing::debug!(?m, "Options page message");
227 match m {
228 OptionsPageMessage::Redraw => true,
229 OptionsPageMessage::Close => {
230 sender.output(());
231 false
232 }
233 OptionsPageMessage::Save(config, tx) => {
234 config.s = self.mltext.text()?;
235 tx.send(config).unwrap();
236 false
237 }
238 }
239 }
240 })
241 }Sourcepub async fn update(&mut self) -> Result<bool, <T as Component>::Error>
pub async fn update(&mut self) -> Result<bool, <T as Component>::Error>
Respond to the child message.
Sourcepub fn render(&mut self) -> Result<(), <T as Component>::Error>
pub fn render(&mut self) -> Result<(), <T as Component>::Error>
Render the child component.
Examples found in repository?
examples/options/options.rs (line 142)
141 fn render(&mut self, _sender: &ComponentSender<Self>) -> Result<(), Self::Error> {
142 self.window.render();
143
144 let csize = self.window.size()?;
145
146 let m = Margin::new(5., 0., 5., 0.);
147 let m_l = Margin::new(0., 5., 0., 0.);
148
149 let mut form = layout! {
150 Grid::from_str("auto,1*", "auto,auto").unwrap(),
151 self.e_label => { column: 0, row: 0, margin: m_l, valign: VAlign::Center },
152 self.e => { column: 1, row: 0, margin: m },
153 self.s_label => { column: 0, row: 1, margin: m_l, valign: VAlign::Center },
154 self.s => { column: 1, row: 1, margin: m },
155 };
156
157 let mut grid = layout! {
158 Grid::from_str("auto,1*", "auto,auto,auto,1*").unwrap(),
159 self.enabled => { column: 0, row: 0, margin: m },
160 self.b => { column: 0, row: 1, margin: m },
161 form => { column: 0, row: 2, margin: m },
162 };
163 grid.set_size(csize);
164 Ok(())
165 }Sourcepub fn sender(&self) -> &ComponentSender<T>
pub fn sender(&self) -> &ComponentSender<T>
Get the sender of the child component.
Trait Implementations§
Source§impl<T> AsContainer for Child<T>where
T: AsContainer + Component,
Available on crate feature handle only.
impl<T> AsContainer for Child<T>where
T: AsContainer + Component,
Available on crate feature
handle only.Source§fn as_container(&self) -> BorrowedContainer<'_>
fn as_container(&self) -> BorrowedContainer<'_>
Get the container handle.
Source§impl<T> AsWidget for Child<T>
Available on crate feature handle only.
impl<T> AsWidget for Child<T>
Available on crate feature
handle only.Source§fn as_widget(&self) -> BorrowedWidget<'_>
fn as_widget(&self) -> BorrowedWidget<'_>
Get the widget handle.
Source§impl<T> AsWindow for Child<T>
Available on crate feature handle only.
impl<T> AsWindow for Child<T>
Available on crate feature
handle only.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 loc(
&self,
) -> Result<Point2D<f64, LogicalSpace>, <Child<T> as Failable>::Error>
fn loc( &self, ) -> Result<Point2D<f64, LogicalSpace>, <Child<T> as Failable>::Error>
The left top location.
Source§fn set_loc(
&mut self,
p: Point2D<f64, LogicalSpace>,
) -> Result<(), <Child<T> as Failable>::Error>
fn set_loc( &mut self, p: Point2D<f64, LogicalSpace>, ) -> Result<(), <Child<T> as Failable>::Error>
Move the location.
Source§fn size(
&self,
) -> Result<Size2D<f64, LogicalSpace>, <Child<T> as Failable>::Error>
fn size( &self, ) -> Result<Size2D<f64, LogicalSpace>, <Child<T> as Failable>::Error>
The size.
Source§fn set_size(
&mut self,
s: Size2D<f64, LogicalSpace>,
) -> Result<(), <Child<T> as Failable>::Error>
fn set_size( &mut self, s: Size2D<f64, LogicalSpace>, ) -> Result<(), <Child<T> as Failable>::Error>
Resize.
Source§fn rect(&self) -> Result<Rect<f64, LogicalSpace>, <Child<T> as Failable>::Error>
fn rect(&self) -> Result<Rect<f64, LogicalSpace>, <Child<T> as Failable>::Error>
The bounding rectangle.
Source§fn set_rect(
&mut self,
r: Rect<f64, LogicalSpace>,
) -> Result<(), <Child<T> as Failable>::Error>
fn set_rect( &mut self, r: Rect<f64, LogicalSpace>, ) -> Result<(), <Child<T> as Failable>::Error>
Set the location and size.
Source§fn preferred_size(
&self,
) -> Result<Size2D<f64, LogicalSpace>, <Child<T> as Failable>::Error>
fn preferred_size( &self, ) -> Result<Size2D<f64, LogicalSpace>, <Child<T> as Failable>::Error>
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> UnsafeUnpin 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