use crate::event::{EventState, NavAdvance};
use crate::geom::{Coord, Offset, Rect};
use crate::util::IdentifyWidget;
use crate::{ChildIndices, DefaultCoreType, WidgetCore, WidgetStatus};
use crate::{HasId, Id, Layout, Role, RoleCx};
use kas_macros::autoimpl;
#[allow(unused)] use super::{Events, RoleCxExt, Widget};
#[allow(unused)] use crate::layout::{self};
#[allow(unused)] use crate::theme::DrawCx;
#[allow(unused)] use kas_macros as macros;
#[autoimpl(for<T: trait + ?Sized> &'_ mut T, Box<T>)]
pub trait Tile: Layout {
#[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
#[cfg_attr(docsrs, doc(cfg(internal_doc)))]
fn core(&self) -> &impl WidgetCore
where
Self: Sized,
{
unimplemented!() as &DefaultCoreType
}
#[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
#[cfg_attr(docsrs, doc(cfg(internal_doc)))]
fn core_mut(&mut self) -> &mut impl WidgetCore
where
Self: Sized,
{
unimplemented!() as &mut DefaultCoreType
}
fn as_tile(&self) -> &dyn Tile {
unimplemented!() }
#[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
#[cfg_attr(docsrs, doc(cfg(internal_doc)))]
fn status(&self) -> WidgetStatus {
unimplemented!() }
fn id_ref(&self) -> &Id {
unimplemented!() }
#[inline]
fn id(&self) -> Id {
self.id_ref().clone()
}
fn identify(&self) -> IdentifyWidget<'_> {
unimplemented!() }
fn navigable(&self) -> bool {
false
}
fn tooltip(&self) -> Option<&str> {
None
}
fn role(&self, cx: &mut dyn RoleCx) -> Role<'_> {
let _ = cx;
Role::Unknown
}
#[inline]
fn role_child_properties(&self, cx: &mut dyn RoleCx, index: usize) {
let _ = (cx, index);
}
fn child_indices(&self) -> ChildIndices {
unimplemented!() }
fn get_child(&self, index: usize) -> Option<&dyn Tile> {
let _ = index;
unimplemented!() }
#[inline]
fn find_child_index(&self, id: &Id) -> Option<usize> {
id.next_key_after(self.id_ref())
}
fn try_probe(&self, coord: Coord) -> Option<Id> {
let _ = coord;
unimplemented!() }
fn nav_next(&self, reverse: bool, from: Option<usize>) -> Option<usize> {
let _ = (reverse, from);
unimplemented!() }
#[inline]
fn translation(&self, index: usize) -> Offset {
let _ = index;
Offset::ZERO
}
#[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
#[cfg_attr(docsrs, doc(cfg(internal_doc)))]
fn _nav_next(&self, cx: &EventState, focus: Option<&Id>, advance: NavAdvance) -> Option<Id>;
}
impl<W: Tile + ?Sized> HasId for &W {
#[inline]
fn has_id(self) -> Id {
self.id_ref().clone()
}
}
impl<W: Tile + ?Sized> HasId for &mut W {
#[inline]
fn has_id(self) -> Id {
self.id_ref().clone()
}
}
pub trait TileExt: Tile {
#[inline]
fn is_configured(&self) -> bool {
self.status() >= WidgetStatus::Configured
}
#[inline]
fn is_sized(&self) -> bool {
self.status() >= WidgetStatus::SetRect
}
#[inline]
fn eq_id<T>(&self, rhs: T) -> bool
where
Id: PartialEq<T>,
{
*self.id_ref() == rhs
}
#[inline]
fn is_ancestor_of(&self, id: &Id) -> bool {
self.id_ref().is_ancestor_of(id)
}
#[inline]
fn is_strict_ancestor_of(&self, id: &Id) -> bool {
!self.eq_id(id) && self.id_ref().is_ancestor_of(id)
}
fn children(&self) -> impl Iterator<Item = &dyn Tile> {
self.child_indices()
.into_iter()
.flat_map(|i| self.get_child(i))
}
fn find_tile(&self, id: &Id) -> Option<&dyn Tile> {
if let Some(child) = self.find_child_index(id).and_then(|i| self.get_child(i)) {
child.find_tile(id)
} else if self.eq_id(id) {
Some(self.as_tile())
} else {
None
}
}
fn find_tile_rect(&self, id: &Id) -> Option<(Rect, Offset)> {
let mut widget = self.as_tile();
let mut translation = Offset::ZERO;
loop {
if widget.eq_id(id) {
let rect = widget.rect();
return Some((rect, translation));
}
let index = widget.find_child_index(id)?;
translation += widget.translation(index);
widget = widget.get_child(index)?;
}
}
}
impl<W: Tile + ?Sized> TileExt for W {}