use view::{Selector, View, ViewWrapper}; use vec::Vec2; use With; use std::any::Any; /// Wrapper around another view that can be hidden at will. /// /// By default, it simply forwards all calls to the inner view. /// /// When hidden (with `HideableView::hide()`), it will appear as a zero-sized /// invisible view, will not take focus and will not accept input. /// /// It can be made visible again with `HideableView::unhide()`. pub struct HideableView { view: V, visible: bool, invalidated: bool, } impl HideableView { /// Creates a new HideableView around `view`. /// /// It will be visible by default. pub fn new(view: V) -> Self { HideableView { view, visible: true, invalidated: true, } } /// Sets the visibility for this view. pub fn set_visible(&mut self, visible: bool) { self.visible = visible; self.invalidate(); } /// Sets the visibility for this view to `false`. pub fn hide(&mut self) { self.set_visible(false); } /// Sets the visibility for this view to `true`. pub fn unhide(&mut self) { self.set_visible(true); } /// Sets the visibility for this view to `false`. /// /// Chainable variant. pub fn hidden(self) -> Self { self.with(Self::hide) } fn invalidate(&mut self) { self.invalidated = true; } inner_getters!(self.view: V); } impl ViewWrapper for HideableView { type V = V; fn with_view(&self, f: F) -> Option where F: FnOnce(&Self::V) -> R, { if self.visible { Some(f(&self.view)) } else { None } } fn with_view_mut(&mut self, f: F) -> Option where F: FnOnce(&mut Self::V) -> R, { if self.visible { Some(f(&mut self.view)) } else { None } } fn wrap_call_on_any<'a>( &mut self, selector: &Selector, callback: Box, ) { // We always run callbacks, even when invisible. self.view.call_on_any(selector, callback) } fn into_inner(self) -> Result where Self: Sized, Self::V: Sized, { Ok(self.view) } fn wrap_layout(&mut self, size: Vec2) { self.invalidated = false; self.with_view_mut(|v| v.layout(size)); } fn wrap_needs_relayout(&self) -> bool { self.invalidated || (self.visible && self.view.needs_relayout()) } }