Trait kas_core::WidgetChildren
source · 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§
sourcefn num_children(&self) -> usize
fn num_children(&self) -> usize
Get the number of child widgets
Every value in the range 0..self.num_children()
is a valid child
index.
sourcefn get_child(&self, index: usize) -> Option<&dyn Widget>
fn get_child(&self, index: usize) -> Option<&dyn Widget>
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()
.
sourcefn get_child_mut(&mut self, index: usize) -> Option<&mut dyn Widget>
fn get_child_mut(&mut self, index: usize) -> Option<&mut dyn Widget>
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§
sourcefn find_child_index(&self, id: &WidgetId) -> Option<usize>
fn find_child_index(&self, id: &WidgetId) -> Option<usize>
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?
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
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,
}
}
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
}
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
};
}
}
}
}
sourcefn make_child_id(&mut self, index: usize) -> WidgetId
fn make_child_id(&mut self, index: usize) -> WidgetId
Make an identifier for a child
Default impl: self.id_ref().make_child(index)
Examples found in repository?
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);
}