use crate::core::{Bounds, FocusId, HitboxId, Pixels, Point, Size};
use crate::gpu::Affine;
use crate::view::context::ElementContext;
use crate::view::dispatch::DispatchNode;
use crate::view::interactivity::HandlerEntry;
use std::any::TypeId;
use std::rc::Rc;
impl ElementContext<'_> {
pub fn insert_hitbox(&mut self, bounds: Bounds, blocks: bool) -> HitboxId {
let Some(transform) = self.hit_transforms.last().filter(|transform| !transform.is_identity()) else {
let clipped = self.mask().intersect(&bounds);
return self.frame.hitboxes.insert(clipped, blocks);
};
let [x, y, width, height] =
transform.bounds_of([bounds.origin.x.0, bounds.origin.y.0, bounds.size.width.0, bounds.size.height.0]);
self.frame
.hitboxes
.insert(Bounds::new(Point::new(Pixels(x), Pixels(y)), Size::new(Pixels(width), Pixels(height))), blocks)
}
pub fn push_hit_transform(&mut self, transform: Affine) {
let current = self.hit_transforms.last().copied().unwrap_or_default();
self.hit_transforms.push(transform.then(current));
}
pub fn pop_hit_transform(&mut self) {
self.hit_transforms.pop();
}
pub fn register_handlers(&mut self, entry: HandlerEntry) {
self.frame.handlers.push(entry);
}
pub fn push_dispatch_node(&mut self, node: DispatchNode) {
self.frame.dispatch.push(node);
}
pub fn pop_dispatch_node(&mut self) {
self.frame.dispatch.pop();
}
pub fn is_hovered(&self, hitbox: HitboxId) -> bool {
self.frame.hitboxes.is_hovered(hitbox, self.mouse.position)
}
pub fn accessibility_enabled(&self) -> bool {
self.frame.access_enabled
}
pub fn register_access(&mut self, node: crate::view::accessibility::AccessNode) {
if self.frame.access_enabled {
self.frame.access.push(node);
}
}
pub fn register_group(&mut self, group: Rc<str>, hitbox: HitboxId) {
self.frame.groups.entry(group).or_default().push(hitbox);
}
pub fn is_group_hovered(&self, group: &str) -> bool {
self.frame.groups.get(group).is_some_and(|hitboxes| hitboxes.iter().any(|hitbox| self.is_hovered(*hitbox)))
}
pub fn active_drag_type(&self) -> Option<TypeId> {
self.active_drag
}
pub fn is_pressed(&self, hitbox: HitboxId) -> bool {
self.mouse.pressed == Some(hitbox) && self.is_hovered(hitbox)
}
pub fn is_focused(&self, focus: FocusId) -> bool {
self.focused == Some(focus)
}
pub fn mouse_position(&self) -> Point {
self.mouse.position
}
}