Element and Component query
Both component events and messages provide an element query that can be used to access elements and attributes of child components.
Attributes can be read and written to.
Querying elements
There are currently three element queries:
by_tagby_attributeat_position
A query can be followed by an additional query, or first or each.
first will stop at the first found element, whereas each will call the
closure for each element.
Example
children.elements()
.by_tag("border")
.by_attribute("button", true).
.as_position(pos)
.each(|element, attributes| {
// Each element and it's associated attributes
});
Cast an element
It's possible to cast an element to a specific widget using the to method.
The to method returns a &mut T.
For an immutable reference use to_ref.
If the element type is unknown use try_to and try_to_ref respectively.
Example
fn on_key(
&mut self,
key: KeyEvent,
state: &mut Self::State,
mut children: Children<'_, '_>,
mut context: Context<'_, '_, Self::State>,
) {
children
.elements()
.by_tag("overflow")
.by_attribute("abc", 123)
.first(|el, _| {
let overflow = el.to::<Overflow>();
overflow.scroll_up();
});
}
Filter elements
Example
fn on_mouse(
&mut self,
mouse: MouseEvent,
state: &mut Self::State,
mut children: Children<'_, '_>,
mut context: Context<'_, '_, Self::State>,
) {
children
.elements()
.by_attribute("abc", 123)
.each(|el, attributes| {
attributes.set("background", "green");
});
}
There are three methods to query the elements inside the component:
by_tag
This is the element tag name in the template, e.g text or overflow.
children
.elements()
.by_tag("text")
.each(|el, attributes| {
attributes.set("background", "green");
});
by_attribute
This is an attribute with a matching value on any element.
children
.elements()
.by_attribute("background", "green")
.each(|el, attributes| {
attributes.set("background", "red");
});
at_position
fn on_mouse(
&mut self,
mouse: MouseEvent,
state: &mut Self::State,
mut children: Elements<'_, '_>,
context: Context<'_, Self::State>,
) {
children
.elements()
.at_position(mouse.pos())
.each(|el, attributes| {
attributes.set("background", "red");
});
}
Setting attribute values
It is possible to assign an attribute to an element using the set function on the attributes.
// Component event
fn on_key(
&mut self,
key: KeyEvent,
state: &mut Self::State,
mut children: Children<'_, '_>,
mut context: Context<'_, '_, Self::State>,
) {
children
.elements()
.by_tag("position")
.each(|el, attrs| {
attrs.set("background", Color::Red);
});
}
Getting values from attributes
To get values from attributes use the get_as function.
E.e context.attributes.get_as::<&str>("name").unwrap();
Note that integers in the template can be auto cast to any integer type.
E.g i64 can be cast to a u8.
However integers can not be cast to floats, and floats can not be cast to integers.
// Component event
fn on_key(
&mut self,
key: KeyEvent,
state: &mut Self::State,
mut children: Children<'_, '_>,
mut context: Context<'_, '_, Self::State>,
) {
children.elements()
.by_tag("position")
.each(|el, attrs| {
let boolean = attrs.get_as::<bool>("is_true").unwrap();
let string = attrs.get("background").unwrap().as_str().unwrap();
});
}
Querying components
There are currently four component queries:
by_nameby_idby_attributeat_position
// Component event
fn on_key(
&mut self,
key: KeyEvent,
state: &mut Self::State,
mut children: Children<'_, '_>,
mut context: Context<'_, '_, Self::State>,
) {
children
.component()
.by_name("my_component")
.each(|id, comp, attrs| {
let boolean = attrs.get_as::<bool>("is_true").unwrap();
let string = attrs.get("background").unwrap().as_str().unwrap();
});
}