use crate::cursor::Cursor;
use crate::tree::El;
use super::UiState;
impl UiState {
pub fn cursor(&self, root: &El) -> Cursor {
if let Some(pressed) = &self.pressed {
let id = pressed.node_id.as_str();
if let Some(c) = cursor_pressed_at_target(root, id) {
return c;
}
return cursor_for_target(root, id).unwrap_or(Cursor::Default);
}
if self.hovered_link.is_some() {
return Cursor::Pointer;
}
if let Some(hovered) = &self.hovered {
return cursor_for_target(root, hovered.node_id.as_str()).unwrap_or(Cursor::Default);
}
Cursor::Default
}
}
fn cursor_pressed_at_target(root: &El, target_id: &str) -> Option<Cursor> {
fn walk(node: &El, target_id: &str) -> Option<Option<Cursor>> {
if node.computed_id == target_id {
return Some(node.cursor_pressed);
}
for c in &node.children {
if let Some(found) = walk(c, target_id) {
return Some(found);
}
}
None
}
walk(root, target_id).flatten()
}
fn cursor_for_target(root: &El, target_id: &str) -> Option<Cursor> {
fn walk(node: &El, target_id: &str, inherited: Option<Cursor>) -> Option<Option<Cursor>> {
let here = node.cursor.or(inherited);
if node.computed_id == target_id {
return Some(here);
}
for c in &node.children {
if let Some(found) = walk(c, target_id, here) {
return Some(found);
}
}
None
}
walk(root, target_id, None).flatten()
}