use crate::app_state::with_app_state;
use crate::reactive::owner::with_root_owner;
use crate::reactive::{Prop, create_effect, dispose_owner_now, with_owner};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum CursorIcon {
#[default]
Default,
Text,
Pointer,
Crosshair,
Move,
NotAllowed,
Grab,
Grabbing,
ResizeNorth,
ResizeSouth,
ResizeEast,
ResizeWest,
ResizeNorthEast,
ResizeNorthWest,
ResizeSouthEast,
ResizeSouthWest,
ColResize,
RowResize,
Wait,
Progress,
Hidden,
}
pub(crate) fn point_at(declared: Prop<CursorIcon>) {
let unchanged = with_app_state(|app| app.pointed_cursor.replace(declared) == declared);
if unchanged {
return;
}
if let Some(watch) = with_app_state(|app| app.cursor_watch.take()) {
dispose_owner_now(watch);
}
if let Prop::Reactive(signal) = declared {
let ((), watch) = with_root_owner(|| {
with_owner(|| {
create_effect(move || {
if signal.is_live() {
show(signal.get());
}
})
})
});
with_app_state(|app| app.cursor_watch.set(Some(watch)));
} else {
show(declared.get_or_untracked(CursorIcon::Default));
}
}
fn show(cursor: CursorIcon) {
with_app_state(|app| {
if app.current_cursor.replace(cursor) != cursor {
app.outgoing_cursor.set(cursor);
}
});
}
pub(crate) fn resend_cursor() {
with_app_state(|app| app.outgoing_cursor.set(app.current_cursor.get()));
}
pub(crate) fn take_cursor_change() -> Option<CursorIcon> {
with_app_state(|app| app.outgoing_cursor.take())
}