pub trait WidgetChildren: WidgetCore {
    fn num_children(&self) -> usize;
    fn get_child(&self, index: usize) -> Option<&dyn Widget>;
    fn get_child_mut(&mut self, index: usize) -> Option<&mut dyn Widget>;

    fn find_child_index(&self, id: &WidgetId) -> Option<usize> { ... }
    fn make_child_id(&mut self, index: usize) -> WidgetId { ... }
}
Expand description

Listing of a Widget’s children

This trait enumerates child widgets (that is, components of the widget which are themselves widgets).

Enumerated widgets are automatically configured, via recursion, when their parent is. See Widget::configure.

Implementing WidgetChildren

Implementations of this trait are usually generated via macro. See Widget trait documentation.

In a few cases, namely widgets which may add/remove children dynamically, this trait should be implemented directly.

Note that parents are responsible for ensuring that newly added children get configured, either by sending TkAction::RECONFIGURE by calling ConfigMgr::configure.

Required Methods§

Get the number of child widgets

Every value in the range 0..self.num_children() is a valid child index.

Get a reference to a child widget by index, or None if the index is out of bounds.

For convenience, Index<usize> is implemented via this method.

Required: index < self.len().

Mutable variant of get

Warning: directly adjusting a widget without requiring reconfigure or redraw may break the UI. If a widget is replaced, a reconfigure must be requested. This can be done via EventState::send_action. This method may be removed in the future.

Provided Methods§

Find the child which is an ancestor of this id, if any

If Some(index) is returned, this is probably but not guaranteed to be a valid child index.

The default implementation simply uses WidgetId::next_key_after. Widgets may choose to assign children custom keys by overriding this method and Self::make_child_id.

Examples found in repository?
src/core/widget.rs (line 627)
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
    fn find_widget(&self, id: &WidgetId) -> Option<&dyn Widget> {
        if let Some(index) = self.find_child_index(id) {
            self.get_child(index)
                .and_then(|child| child.find_widget(id))
        } else if self.eq_id(id) {
            return Some(self.as_widget());
        } else {
            None
        }
    }

    /// Find the descendant with this `id`, if any
    fn find_widget_mut(&mut self, id: &WidgetId) -> Option<&mut dyn Widget> {
        if let Some(index) = self.find_child_index(id) {
            self.get_child_mut(index)
                .and_then(|child| child.find_widget_mut(id))
        } else if self.eq_id(id) {
            return Some(self.as_widget_mut());
        } else {
            None
        }
    }
More examples
Hide additional examples
src/root.rs (line 118)
117
118
119
120
121
122
123
124
125
126
127
128
129
fn find_rect(widget: &dyn Widget, id: WidgetId) -> Option<Rect> {
    match widget.find_child_index(&id) {
        Some(i) => {
            if let Some(w) = widget.get_child(i) {
                find_rect(w, id).map(|rect| rect - widget.translation())
            } else {
                None
            }
        }
        None if widget.eq_id(&id) => Some(widget.rect()),
        _ => None,
    }
}
src/event/manager.rs (line 584)
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
    fn send_recurse(
        &mut self,
        widget: &mut dyn Widget,
        id: WidgetId,
        disabled: bool,
        event: Event,
    ) -> Response {
        let mut response = Response::Unused;
        if widget.steal_event(self, &id, &event) == Response::Used {
            response = Response::Used;
        } else if let Some(index) = widget.find_child_index(&id) {
            let translation = widget.translation();
            if let Some(w) = widget.get_child_mut(index) {
                response = self.send_recurse(w, id, disabled, event.clone() + translation);
                if self.scroll != Scroll::None {
                    widget.handle_scroll(self, self.scroll);
                }
            } else {
                log::warn!(
                    "send_recurse: {} found index {index} for {id} but not child",
                    widget.identify()
                );
            }

            if matches!(response, Response::Unused) {
                response = widget.handle_unused(self, index, event);
            } else if self.has_msg() {
                widget.handle_message(self, index);
            }
        } else if disabled {
            // event is unused
        } else if id == widget.id_ref() {
            if event == Event::NavFocus(true) {
                self.set_scroll(Scroll::Rect(widget.rect()));
                response = Response::Used;
            }

            response |= widget.pre_handle_event(self, event)
        } else {
            log::warn!(
                "send_recurse: Widget {} cannot find path to {id}",
                widget.identify()
            );
        }

        response
    }
src/event/manager/config_mgr.rs (line 179)
169
170
171
172
173
174
175
176
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
        fn nav(
            mgr: &mut ConfigMgr,
            widget: &mut dyn Widget,
            focus: Option<&WidgetId>,
            rev: bool,
        ) -> Option<WidgetId> {
            if mgr.ev_state().is_disabled(widget.id_ref()) {
                return None;
            }

            let mut child = focus.and_then(|id| widget.find_child_index(id));

            if !rev {
                if let Some(index) = child {
                    if let Some(id) = widget
                        .get_child_mut(index)
                        .and_then(|w| nav(mgr, w, focus, rev))
                    {
                        return Some(id);
                    }
                } else if !widget.eq_id(focus) && widget.navigable() {
                    return Some(widget.id());
                }

                loop {
                    if let Some(index) = widget.nav_next(mgr, rev, child) {
                        if let Some(id) = widget
                            .get_child_mut(index)
                            .and_then(|w| nav(mgr, w, focus, rev))
                        {
                            return Some(id);
                        }
                        child = Some(index);
                    } else {
                        return None;
                    }
                }
            } else {
                if let Some(index) = child {
                    if let Some(id) = widget
                        .get_child_mut(index)
                        .and_then(|w| nav(mgr, w, focus, rev))
                    {
                        return Some(id);
                    }
                }

                loop {
                    if let Some(index) = widget.nav_next(mgr, rev, child) {
                        if let Some(id) = widget
                            .get_child_mut(index)
                            .and_then(|w| nav(mgr, w, focus, rev))
                        {
                            return Some(id);
                        }
                        child = Some(index);
                    } else {
                        return if !widget.eq_id(focus) && widget.navigable() {
                            Some(widget.id())
                        } else {
                            None
                        };
                    }
                }
            }
        }

Make an identifier for a child

Default impl: self.id_ref().make_child(index)

Examples found in repository?
src/event/manager/config_mgr.rs (line 91)
87
88
89
90
91
92
93
94
95
96
97
98
    pub fn configure(&mut self, id: WidgetId, widget: &mut dyn Widget) {
        widget.pre_configure(self, id);

        for index in 0..widget.num_children() {
            let id = widget.make_child_id(index);
            if let Some(widget) = widget.get_child_mut(index) {
                self.configure(id, widget);
            }
        }

        widget.configure(self);
    }

Implementations on Foreign Types§

Implementors§