use {
super::Widget,
crate::callback::{widget_callback, Callback},
accesskit::NodeId,
anyhow::Result,
std::{
fmt::{self, Debug},
marker::PhantomData,
sync::atomic::{AtomicU64, Ordering},
},
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RawWidgetId(u64);
impl RawWidgetId {
pub fn new_unique() -> Self {
static NEXT_ID: AtomicU64 = AtomicU64::new(1);
Self(NEXT_ID.fetch_add(1, Ordering::Relaxed))
}
}
impl From<RawWidgetId> for NodeId {
fn from(value: RawWidgetId) -> Self {
value.0.into()
}
}
impl From<NodeId> for RawWidgetId {
fn from(value: NodeId) -> Self {
RawWidgetId(value.into())
}
}
pub struct WidgetId<T>(RawWidgetId, PhantomData<T>);
impl<T> WidgetId<T> {
pub fn new(id: RawWidgetId) -> Self {
Self(id, PhantomData)
}
pub fn raw(self) -> RawWidgetId {
self.0
}
pub fn callback<E, F>(self, func: F) -> Callback<E>
where
T: Widget,
F: Fn(&mut T, E) -> Result<()> + 'static,
E: 'static,
{
widget_callback(self, func)
}
}
impl<T> Debug for WidgetId<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"WidgetId<{}>({:?})",
std::any::type_name::<T>(),
self.0 .0,
)
}
}
impl<T> Clone for WidgetId<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> Copy for WidgetId<T> {}
impl<T> From<WidgetId<T>> for RawWidgetId {
fn from(value: WidgetId<T>) -> Self {
value.raw()
}
}
impl<T> From<WidgetId<T>> for NodeId {
fn from(value: WidgetId<T>) -> Self {
value.raw().into()
}
}