use zng_app::widget::info::{
WidgetInfo,
iter::{self as w_iter, TreeIterator},
};
use super::*;
pub trait IterFocusableExt<I: Iterator<Item = WidgetInfo>> {
fn focusable(self, focus_disabled_widgets: bool, focus_hidden_widgets: bool) -> IterFocusable<I>;
}
impl<I> IterFocusableExt<I> for I
where
I: Iterator<Item = WidgetInfo>,
{
fn focusable(self, focus_disabled_widgets: bool, focus_hidden_widgets: bool) -> IterFocusable<I> {
IterFocusable {
iter: self,
mode: FocusMode::new(focus_disabled_widgets, focus_hidden_widgets),
}
}
}
pub struct IterFocusable<I: Iterator<Item = WidgetInfo>> {
iter: I,
mode: FocusMode,
}
impl<I> Iterator for IterFocusable<I>
where
I: Iterator<Item = WidgetInfo>,
{
type Item = WidgetFocusInfo;
fn next(&mut self) -> Option<Self::Item> {
for next in self.iter.by_ref() {
if let Some(next) = next.into_focusable(self.mode.contains(FocusMode::DISABLED), self.mode.contains(FocusMode::HIDDEN)) {
return Some(next);
}
}
None
}
}
impl<I> DoubleEndedIterator for IterFocusable<I>
where
I: Iterator<Item = WidgetInfo> + DoubleEndedIterator,
{
fn next_back(&mut self) -> Option<Self::Item> {
while let Some(next) = self.iter.next_back() {
if let Some(next) = next.into_focusable(self.mode.contains(FocusMode::DISABLED), self.mode.contains(FocusMode::HIDDEN)) {
return Some(next);
}
}
None
}
}
pub struct FocusTreeIter<I>
where
I: TreeIterator,
{
iter: I,
mode: FocusMode,
}
impl<I> FocusTreeIter<I>
where
I: TreeIterator,
{
pub(super) fn new(iter: I, mode: FocusMode) -> Self {
Self { iter, mode }
}
pub fn tree_filter<F>(self, mut filter: F) -> FocusTreeFilterIter<I, impl FnMut(&WidgetInfo) -> w_iter::TreeFilter>
where
F: FnMut(&WidgetFocusInfo) -> w_iter::TreeFilter,
{
FocusTreeFilterIter {
iter: self.iter.tree_filter(move |w| {
if let Some(f) = w
.clone()
.into_focusable(self.mode.contains(FocusMode::DISABLED), self.mode.contains(FocusMode::HIDDEN))
{
filter(&f)
} else {
w_iter::TreeFilter::Skip
}
}),
mode: self.mode,
}
}
pub fn tree_find<F>(self, filter: F) -> Option<WidgetFocusInfo>
where
F: FnMut(&WidgetFocusInfo) -> w_iter::TreeFilter,
{
self.tree_filter(filter).next()
}
pub fn tree_any<F>(self, filter: F) -> bool
where
F: FnMut(&WidgetFocusInfo) -> w_iter::TreeFilter,
{
self.tree_find(filter).is_some()
}
}
impl FocusTreeIter<w_iter::TreeIter> {
pub fn tree_rev(self) -> FocusTreeIter<w_iter::RevTreeIter> {
FocusTreeIter::new(self.iter.tree_rev(), self.mode)
}
}
impl<I> Iterator for FocusTreeIter<I>
where
I: TreeIterator,
{
type Item = WidgetFocusInfo;
fn next(&mut self) -> Option<Self::Item> {
for next in self.iter.by_ref() {
if let Some(next) = next.into_focusable(self.mode.contains(FocusMode::DISABLED), self.mode.contains(FocusMode::HIDDEN)) {
return Some(next);
}
}
None
}
}
pub struct FocusTreeFilterIter<I, F>
where
I: TreeIterator,
F: FnMut(&WidgetInfo) -> w_iter::TreeFilter,
{
iter: w_iter::TreeFilterIter<I, F>,
mode: FocusMode,
}
impl<I, F> Iterator for FocusTreeFilterIter<I, F>
where
F: FnMut(&WidgetInfo) -> w_iter::TreeFilter,
I: TreeIterator,
{
type Item = WidgetFocusInfo;
fn next(&mut self) -> Option<Self::Item> {
self.iter
.next()
.map(|w| w.into_focus_info(self.mode.contains(FocusMode::DISABLED), self.mode.contains(FocusMode::HIDDEN)))
}
}