use super::*;
use std::any::{TypeId, type_name};
use traitcast::TraitObject;
pub mod link;
pub mod as_widget;
#[doc(hidden)]
pub mod cast;
pub mod ext;
#[doc(hidden)]
pub mod imp;
pub mod resolved;
pub mod resolvable;
pub mod root;
pub mod array;
pub mod ident;
pub trait Widget<E>: WBase<E> where E: Env + 'static {
fn id(&self) -> E::WidgetID;
fn _render(&self, l: Link<E>, r: &mut RenderLink<E>);
fn _event_direct(&self, l: Link<E>, e: &EventCompound<E>) -> EventResp;
fn _size(&self, l: Link<E>, e: &EStyle<E>) -> ESize<E>;
fn childs(&self) -> usize;
fn child<'s>(&'s self, i: usize) -> Result<Resolvable<'s,E>,()>;
fn into_child<'s>(self: Box<Self>, i: usize) -> Result<Resolvable<'s,E>,()> where Self: 's;
#[deprecated]
fn childs_ref<'s>(&'s self) -> Vec<Resolvable<'s,E>> {
(0..self.childs())
.map(#[inline] |i| self.child(i).unwrap() )
.collect::<Vec<_>>()
}
fn into_childs<'w>(self: Box<Self>) -> Vec<Resolvable<'w,E>> where Self: 'w;
#[deprecated]
fn child_paths(&self, own_path: E::WidgetPath) -> Vec<E::WidgetPath> {
(0..self.childs())
.map(#[inline] |i| self.child(i).unwrap().in_parent_path(own_path.refc()) )
.collect::<Vec<_>>()
}
#[inline]
fn resolve<'s>(&'s self, i: E::WidgetPath) -> Result<Resolvable<'s,E>,GuionError<E>> {
if i.is_empty() {
return Ok(Resolvable::Widget(self.box_ref()))
}
let (c,sub) = self.resolve_child(&i)?;
self.child(c).unwrap().resolve_child(sub)
}
#[inline]
fn into_resolve<'w>(self: Box<Self>, i: E::WidgetPath) -> Result<Resolvable<'w,E>,GuionError<E>> where Self: 'w {
if i.is_empty() {
return Ok(Resolvable::Widget(self.box_box()))
}
let (c,sub) = self.resolve_child(&i)?;
self.into_child(c).unwrap_nodebug().resolve_child(sub)
}
#[inline]
fn resolve_child(&self, sub_path: &E::WidgetPath) -> Result<(usize,E::WidgetPath),GuionError<E>> {
for c in 0..self.childs() {
if let Some(r) = self.child(c).unwrap().resolved_by_path(sub_path) {
return Ok((c,r.sub_path));
}
}
Err(self.gen_diag_error_resolve_fail(sub_path, "resolve"))
}
#[inline]
fn trace_bounds(&self, l: Link<E>, i: E::WidgetPath, b: &Bounds, e: &EStyle<E>, force: bool) -> Result<Bounds,GuionError<E>> {
if i.is_empty() {
return Ok(*b)
}
let (child,_) = self.resolve_child(&i)?;
let bounds = self.child_bounds(l,b,e,force)?;
Ok(bounds[child])
}
fn child_bounds(&self, l: Link<E>, b: &Bounds, e: &EStyle<E>, force: bool) -> Result<Vec<Bounds>,()>;
#[inline]
#[deprecated]
fn in_parent_path(&self, parent: E::WidgetPath) -> E::WidgetPath {
parent.for_child_widget_id(self.id())
}
#[inline]
#[deprecated]
fn resolved_by_path(&self, sub_path: &E::WidgetPath) -> Option<ResolvesThruResult<E>> {
E::WidgetPath::resolves_thru_child_id(self.id(), sub_path)
}
fn focusable(&self) -> bool;
#[inline]
fn _focus_on_mouse_down(&self) -> bool {
self.focusable()
}
#[inline]
fn _tabulate_by_tab(&self) -> bool {
true
}
fn _tabulate_next_child(&self, _l: Link<E>, origin: TabulateNextChildOrigin, dir: TabulateDirection) -> TabulateNextChildResponse {
match origin {
TabulateNextChildOrigin::Enter => match dir {
TabulateDirection::Forward if self.focusable() => TabulateNextChildResponse::This,
TabulateDirection::Forward if self.childs() != 0 => TabulateNextChildResponse::Child(0),
TabulateDirection::Backward if self.childs() != 0 => TabulateNextChildResponse::Child(self.childs()-1),
TabulateDirection::Backward if self.focusable() => TabulateNextChildResponse::This,
_ => TabulateNextChildResponse::Leave,
}
TabulateNextChildOrigin::This => match dir {
TabulateDirection::Forward if self.childs() != 0 => TabulateNextChildResponse::Child(0),
_ => TabulateNextChildResponse::Leave,
}
TabulateNextChildOrigin::Child(child_id) => match dir {
TabulateDirection::Forward if child_id < self.childs()-1 => TabulateNextChildResponse::Child(child_id+1),
TabulateDirection::Backward if child_id != 0 => TabulateNextChildResponse::Child(child_id-1),
TabulateDirection::Backward if self.focusable() => TabulateNextChildResponse::This,
_ => TabulateNextChildResponse::Leave,
}
}
}
fn _tabulate(&self, mut l: Link<E>, op: TabulateOrigin<E>, dir: TabulateDirection) -> Result<TabulateResponse<E>,GuionError<E>> {
let enter_child_sub = |l: &mut Link<E>, child_id: usize, to: TabulateOrigin<E>| -> Result<TabulateResponse<E>,GuionError<E>> {
l.for_child(child_id).unwrap()._tabulate(to,dir)
};
let next_child = |l: &mut Link<E>, mut child_id: Option<usize>| -> Result<TabulateResponse<E>,GuionError<E>> {
loop {
let targeted_child = self._tabulate_next_child(
l.reference(),
TabulateNextChildOrigin::child_or_this(child_id),
dir,
);
match targeted_child {
TabulateNextChildResponse::Child(t) => match enter_child_sub(l,t,TabulateOrigin::Enter)? {
TabulateResponse::Done(v) => return Ok(TabulateResponse::Done(v)),
TabulateResponse::Leave => {
child_id = Some(t);
continue
},
}
TabulateNextChildResponse::This =>
if self.focusable() {
return Ok(TabulateResponse::Done(l.path()))
}else{
child_id = None;
continue
},
TabulateNextChildResponse::Leave => break,
}
}
Ok(TabulateResponse::Leave)
};
let enter_child = |l: &mut Link<E>, child_id: usize, to: TabulateOrigin<E>| -> Result<TabulateResponse<E>,GuionError<E>> {
match enter_child_sub(l,child_id,to)? {
TabulateResponse::Done(v) => return Ok(TabulateResponse::Done(v)),
TabulateResponse::Leave => return next_child(l,Some(child_id)),
}
};
match op {
TabulateOrigin::Resolve(p) => {
if !p.is_empty() {
let (child_id,sub_path) = self.resolve_child(&p)?;
return enter_child(&mut l, child_id, TabulateOrigin::Resolve(sub_path));
}else{
return next_child(&mut l, None);
}
},
TabulateOrigin::Enter => {
let enter_dir = self._tabulate_next_child(
l.reference(),
TabulateNextChildOrigin::Enter,
dir,
);
match enter_dir {
TabulateNextChildResponse::Child(t) => return enter_child(&mut l, t, TabulateOrigin::Enter),
TabulateNextChildResponse::This => return Ok(TabulateResponse::Done(l.path())),
TabulateNextChildResponse::Leave => return Ok(TabulateResponse::Leave),
}
},
}
}
#[inline]
fn inner(&self) -> Option<&dyn Widget<E>> {
None
}
#[inline]
fn innest(&self) -> Option<&dyn Widget<E>> {
let mut i = self.erase();
loop {
let v = i.inner();
if let Some(v) = v {
i = v;
}else{
return Some(i);
}
}
}
fn debug_type_name(&self, dest: &mut Vec<&'static str>) {
dest.push(self.type_name());
}
fn debugged_type_name(&self) -> Vec<&'static str> {
let mut v = Vec::new();
self.debug_type_name(&mut v);
v.shrink_to_fit();
v
}
#[allow(unused)]
#[doc(hidden)]
#[inline]
unsafe fn _as_trait_ref(&self, t: TypeId) -> Option<TraitObject> {
None
}
#[inline]
fn box_ref<'s>(&'s self) -> WidgetRef<'s,E> {
WBase::_box_ref(self)
}
#[inline]
fn box_box<'w>(self: Box<Self>) -> WidgetRef<'w,E> where Self: 'w {
WBase::_box_box(self)
}
#[inline]
fn boxed<'w>(self) -> WidgetRef<'w,E> where Self: Sized+'w {
WBase::_boxed(self)
}
#[inline(never)]
fn gen_diag_error_resolve_fail(&self, sub_path: &E::WidgetPath, op: &'static str) -> GuionError<E> {
let widget_type = self.debugged_type_name();
let child_info = (0..self.childs())
.map(#[inline] |i| self.child(i).unwrap().guion_resolve_error_child_info(i) )
.collect::<Vec<_>>();
GuionError::ResolveError(Box::new(ResolveError{
op,
sub_path: sub_path.clone(),
widget_type,
child_info,
}))
}
}
pub trait WidgetMut<E>: Widget<E> + WBaseMut<E> where E: Env + 'static {
#[allow(unused)]
#[inline]
fn message(&mut self, m: E::Message) {
}
#[allow(unused)]
#[inline]
fn _set_invalid(&mut self, v: bool) {
}
fn child_mut<'s>(&'s mut self, i: usize) -> Result<ResolvableMut<'s,E>,()>;
fn into_child_mut<'w>(self: Box<Self>, i: usize) -> Result<ResolvableMut<'w,E>,()> where Self: 'w;
#[deprecated]
fn childs_mut<'s>(&'s mut self) -> Vec<ResolvableMut<'s,E>>;
fn into_childs_mut<'w>(self: Box<Self>) -> Vec<ResolvableMut<'w,E>> where Self: 'w;
#[inline]
fn resolve_mut<'s>(&'s mut self, i: E::WidgetPath) -> Result<ResolvableMut<'s,E>,GuionError<E>> {
if i.is_empty() {
return Ok(ResolvableMut::Widget(self.box_mut()))
}
let (c,sub) = self.resolve_child(&i)?;
self.child_mut(c).unwrap().resolve_child_mut(sub)
}
#[inline]
fn into_resolve_mut<'w>(self: Box<Self>, i: E::WidgetPath) -> Result<ResolvableMut<'w,E>,GuionError<E>> where Self: 'w {
if i.is_empty() {
return Ok(ResolvableMut::Widget(self.box_box_mut()))
}
let (c,sub) = self.resolve_child(&i)?;
self.into_child_mut(c).unwrap_nodebug().resolve_child_mut(sub)
}
#[inline]
fn resolve_child_mut(&mut self, sub_path: &E::WidgetPath) -> Result<(usize,E::WidgetPath),GuionError<E>> {
for c in 0..self.childs() {
if let Some(r) = self.child(c).unwrap().resolved_by_path(sub_path) {
return Ok((c,r.sub_path));
}
}
Err(self.gen_diag_error_resolve_fail_mut(sub_path,"resolve_mut"))
}
#[inline]
fn inner_mut(&mut self) -> Option<&mut dyn WidgetMut<E>> {
None
}
#[inline]
fn pass(self) -> Self where Self: Sized {
self
}
fn debug_type_name_mut(&mut self, dest: &mut Vec<&'static str>) {
dest.push(self.type_name());
}
fn debugged_type_name_mut(&mut self) -> Vec<&'static str> {
let mut v = Vec::new();
self.debug_type_name_mut(&mut v);
v.shrink_to_fit();
v
}
#[allow(unused)]
#[doc(hidden)]
#[inline]
unsafe fn _as_trait_mut(&mut self, t: TypeId) -> Option<TraitObject> {
None
}
#[inline]
fn box_mut<'s>(&'s mut self) -> WidgetRefMut<'s,E> {
WBaseMut::_box_mut(self)
}
#[inline]
fn box_box_mut<'w>(self: Box<Self>) -> WidgetRefMut<'w,E> where Self: 'w {
WBaseMut::_box_box_mut(self)
}
#[inline]
fn boxed_mut<'w>(self) -> WidgetRefMut<'w,E> where Self: Sized+'w {
WBaseMut::_boxed_mut(self)
}
#[inline(never)]
fn gen_diag_error_resolve_fail_mut(&mut self, sub_path: &E::WidgetPath, op: &'static str) -> GuionError<E> {
let widget_type = self.debugged_type_name_mut();
let child_info = (0..self.childs())
.map(#[inline] |i| self.child_mut(i).unwrap().guion_resolve_error_child_info(i) )
.collect::<Vec<_>>();
GuionError::ResolveError(Box::new(ResolveError{
op,
sub_path: sub_path.clone(),
widget_type,
child_info,
}))
}
}
#[doc(hidden)]
pub trait WBase<E> where E: Env {
fn type_name(&self) -> &'static str;
fn erase(&self) -> &dyn Widget<E>;
fn _box_ref<'s>(&'s self) -> WidgetRef<'s,E>;
fn _box_box<'w>(self: Box<Self>) -> WidgetRef<'w,E> where Self: 'w;
fn _boxed<'w>(self) -> WidgetRef<'w,E> where Self: Sized+'w;
}
impl<T,E> WBase<E> for T where T: Widget<E>, E: Env {
#[inline]
fn type_name(&self) -> &'static str {
type_name::<Self>()
}
#[inline]
fn erase(&self) -> &dyn Widget<E> {
self
}
#[inline]
fn _box_ref<'s>(&'s self) -> WidgetRef<'s,E> {
Box::new(self.erase())
}
#[inline]
fn _box_box<'w>(self: Box<Self>) -> WidgetRef<'w,E> where Self: 'w {
self
}
#[inline]
fn _boxed<'w>(self) -> WidgetRef<'w,E> where Self: Sized + 'w {
Box::new(self)
}
}
#[doc(hidden)]
pub trait WBaseMut<E> where E: Env {
fn base(&self) -> &dyn Widget<E>;
fn erase_mut(&mut self) -> &mut dyn WidgetMut<E>;
fn _box_mut<'s>(&'s mut self) -> WidgetRefMut<'s,E>;
fn _box_box_mut<'w>(self: Box<Self>) -> WidgetRefMut<'w,E> where Self: 'w;
fn _boxed_mut<'w>(self) -> WidgetRefMut<'w,E> where Self: Sized+'w;
}
impl<T,E> WBaseMut<E> for T where T: WidgetMut<E>, E: Env {
#[inline]
fn base(&self) -> &dyn Widget<E> {
self
}
#[inline]
fn erase_mut(&mut self) -> &mut dyn WidgetMut<E> {
self
}
#[inline]
fn _box_mut<'s>(&'s mut self) -> WidgetRefMut<'s,E> {
Box::new(self.erase_mut())
}
#[inline]
fn _box_box_mut<'w>(self: Box<Self>) -> WidgetRefMut<'w,E> where Self: 'w {
self
}
#[inline]
fn _boxed_mut<'w>(self) -> WidgetRefMut<'w,E> where Self: Sized + 'w {
Box::new(self)
}
}