use std::num::NonZeroU64;
use std::ops::{Deref, DerefMut};
use super::prelude::*;
use crate::debug_state::DebugState;
use crate::widget::Axis;
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub struct WidgetId(NonZeroU64);
pub trait Widget<T> {
fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env);
fn lifecycle(&mut self, ctx: &mut LifeCycleCtx, event: &LifeCycle, data: &T, env: &Env);
fn update(&mut self, ctx: &mut UpdateCtx, old_data: &T, data: &T, env: &Env);
fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints, data: &T, env: &Env) -> Size;
fn paint(&mut self, ctx: &mut PaintCtx, data: &T, env: &Env);
#[doc(hidden)]
fn id(&self) -> Option<WidgetId> {
None
}
#[doc(hidden)]
fn type_name(&self) -> &'static str {
std::any::type_name::<Self>()
}
#[doc(hidden)]
fn short_type_name(&self) -> &'static str {
let name = self.type_name();
name.split('<')
.next()
.unwrap_or(name)
.split("::")
.last()
.unwrap_or(name)
}
#[doc(hidden)]
fn debug_state(&self, data: &T) -> DebugState {
#![allow(unused_variables)]
DebugState {
display_name: self.short_type_name().to_string(),
..Default::default()
}
}
fn compute_max_intrinsic(
&mut self,
axis: Axis,
ctx: &mut LayoutCtx,
bc: &BoxConstraints,
data: &T,
env: &Env,
) -> f64 {
match axis {
Axis::Horizontal => self.layout(ctx, bc, data, env).width,
Axis::Vertical => self.layout(ctx, bc, data, env).height,
}
}
}
impl WidgetId {
pub fn next() -> WidgetId {
use crate::shell::Counter;
static WIDGET_ID_COUNTER: Counter = Counter::new();
WidgetId(WIDGET_ID_COUNTER.next_nonzero())
}
#[allow(unsafe_code)]
pub const fn reserved(raw: u16) -> WidgetId {
let id = u64::max_value() - raw as u64;
WidgetId(unsafe { std::num::NonZeroU64::new_unchecked(id) })
}
pub(crate) fn to_raw(self) -> u64 {
self.0.into()
}
}
impl<T> Widget<T> for Box<dyn Widget<T>> {
fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
self.deref_mut().event(ctx, event, data, env)
}
fn lifecycle(&mut self, ctx: &mut LifeCycleCtx, event: &LifeCycle, data: &T, env: &Env) {
self.deref_mut().lifecycle(ctx, event, data, env);
}
fn update(&mut self, ctx: &mut UpdateCtx, old_data: &T, data: &T, env: &Env) {
self.deref_mut().update(ctx, old_data, data, env);
}
fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints, data: &T, env: &Env) -> Size {
self.deref_mut().layout(ctx, bc, data, env)
}
fn paint(&mut self, ctx: &mut PaintCtx, data: &T, env: &Env) {
self.deref_mut().paint(ctx, data, env);
}
fn id(&self) -> Option<WidgetId> {
self.deref().id()
}
fn type_name(&self) -> &'static str {
self.deref().type_name()
}
fn debug_state(&self, data: &T) -> DebugState {
self.deref().debug_state(data)
}
fn compute_max_intrinsic(
&mut self,
axis: Axis,
ctx: &mut LayoutCtx,
bc: &BoxConstraints,
data: &T,
env: &Env,
) -> f64 {
self.deref_mut()
.compute_max_intrinsic(axis, ctx, bc, data, env)
}
}