vizia_core/tree/
focus_iter.rs
use crate::entity::Entity;
use crate::prelude::Style;
use crate::style::{Abilities, Display};
use vizia_id::GenerationalId;
use vizia_storage::{
DoubleEndedTreeTour, FocusTreeIterator, TourDirection, Tree, TreeExt, TreeTour,
};
pub(crate) fn is_navigatable(
tree: &Tree<Entity>,
style: &Style,
node: Entity,
lock_focus_to: Entity,
) -> bool {
if style.disabled.get(node).cloned().unwrap_or_default() {
return false;
}
if style.display.get(node).copied().unwrap_or_default() == Display::None {
return false;
}
if !node.is_descendant_of(tree, lock_focus_to) {
return false;
}
if tree.is_ignored(node) {
return false;
}
style
.abilities
.get(node)
.map(|abilities| abilities.contains(Abilities::NAVIGABLE))
.unwrap_or(false)
}
pub(crate) fn focus_forward(
tree: &Tree<Entity>,
style: &Style,
node: Entity,
lock_focus_to: Entity,
) -> Option<Entity> {
FocusTreeIterator::new(
tree,
DoubleEndedTreeTour::new(Some(node), Some(Entity::root())),
|node| {
style.display.get(node).copied().unwrap_or_default() == Display::None
},
)
.skip(1)
.find(|node| is_navigatable(tree, style, *node, lock_focus_to))
}
pub(crate) fn focus_backward(
tree: &Tree<Entity>,
style: &Style,
node: Entity,
lock_focus_to: Entity,
) -> Option<Entity> {
let mut iter = FocusTreeIterator::new(
tree,
DoubleEndedTreeTour::new_raw(
TreeTour::new(Some(Entity::root())),
TreeTour::with_direction(Some(node), TourDirection::Leaving),
),
|node| {
for ancestor in node.parent_iter(tree) {
if style.display.get(ancestor).copied().unwrap_or_default() == Display::None {
return true;
}
}
false
},
);
iter.next_back();
iter.filter(|node| is_navigatable(tree, style, *node, lock_focus_to)).next_back()
}