Rename BoxableView -> IntoBoxedView

And add an implementation for Box<View>
This commit is contained in:
Alexandre Bury 2018-03-14 13:58:57 -07:00
parent 17ccda2d40
commit f27f7792df
6 changed files with 74 additions and 34 deletions

View File

@ -9,7 +9,7 @@ use std::path::Path;
use std::sync::mpsc; use std::sync::mpsc;
use theme; use theme;
use vec::Vec2; use vec::Vec2;
use view::{self, AnyView, BoxableView, Finder, Position, View}; use view::{self, AnyView, IntoBoxedView, Finder, Position, View};
use views::{self, LayerPosition}; use views::{self, LayerPosition};
/// Identifies a screen in the cursive root. /// Identifies a screen in the cursive root.
@ -456,7 +456,7 @@ impl Cursive {
/// ``` /// ```
pub fn add_layer<T>(&mut self, view: T) pub fn add_layer<T>(&mut self, view: T)
where where
T: BoxableView, T: IntoBoxedView,
{ {
self.screen_mut().add_layer(view); self.screen_mut().add_layer(view);
} }
@ -466,7 +466,7 @@ impl Cursive {
/// Fullscreen layers have no shadow. /// Fullscreen layers have no shadow.
pub fn add_fullscreen_layer<T>(&mut self, view: T) pub fn add_fullscreen_layer<T>(&mut self, view: T)
where where
T: BoxableView, T: IntoBoxedView,
{ {
self.screen_mut().add_fullscreen_layer(view); self.screen_mut().add_fullscreen_layer(view);
} }

23
src/view/internal.rs Normal file
View File

@ -0,0 +1,23 @@
//! Internal module for some implementation details.
//!
//! You probable are not interested in anything here. These elements are
//! required to be public, but you should never need to use them directly.
use view::{View, AnyView};
/// A trait for elements that can be converted to `AnyView`.
///
/// You should never need to implement this yourself; it is automatically
/// implemented for any `T: View`.
///
/// Just ignore this trait entirely.
pub trait ToAny {
/// Converts a boxed `Self` to a boxed `AnyView`.
fn to_any(self: Box<Self>) -> Box<AnyView>;
}
impl <T: View> ToAny for T {
fn to_any(self: Box<Self>) -> Box<AnyView> {
self
}
}

View File

@ -0,0 +1,28 @@
use view::{AnyView, View};
/// Represents a type that can be made into a `Box<AnyView>`.
pub trait IntoBoxedView {
/// Returns a `Box<AnyView>`.
fn as_boxed_view(self) -> Box<AnyView>;
}
impl<T> IntoBoxedView for T
where
T: View,
{
fn as_boxed_view(self) -> Box<AnyView> {
Box::new(self)
}
}
impl IntoBoxedView for Box<AnyView> {
fn as_boxed_view(self) -> Box<AnyView> {
self
}
}
impl IntoBoxedView for Box<View> {
fn as_boxed_view(self) -> Box<AnyView> {
self.to_any()
}
}

View File

@ -49,6 +49,11 @@ mod scroll;
mod identifiable; mod identifiable;
mod boxable; mod boxable;
mod into_boxed_view;
pub mod internal;
pub use self::into_boxed_view::IntoBoxedView;
pub use self::boxable::Boxable; pub use self::boxable::Boxable;
pub use self::identifiable::Identifiable; pub use self::identifiable::Identifiable;
pub use self::position::{Offset, Position}; pub use self::position::{Offset, Position};
@ -107,31 +112,13 @@ impl<T: View> AnyView for T {
} }
} }
/// Represents a type that can be made into a `Box<AnyView>`.
pub trait BoxableView {
/// Returns a `Box<AnyView>`.
fn as_boxed_view(self) -> Box<AnyView>;
}
impl<T> BoxableView for T
where
T: View,
{
fn as_boxed_view(self) -> Box<AnyView> {
Box::new(self)
}
}
impl BoxableView for Box<AnyView> {
fn as_boxed_view(self) -> Box<AnyView> {
self
}
}
/// Main trait defining a view behaviour. /// Main trait defining a view behaviour.
/// ///
/// This is what you should implement to define a custom View. /// This is what you should implement to define a custom View.
pub trait View: Any { ///
/// You can ignore the `Any` and `ToAny` trait bound;
/// they are implementation details, and will be implemented automatically.
pub trait View: Any + internal::ToAny {
/// Called when a key was pressed. /// Called when a key was pressed.
/// ///
/// Default implementation just ignores it. /// Default implementation just ignores it.

View File

@ -1,7 +1,9 @@
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use view::{AnyView, BoxableView, ViewWrapper}; use view::{AnyView, IntoBoxedView, ViewWrapper};
/// A boxed `AnyView`. /// A boxed `AnyView`.
///
/// It derefs to the wrapped view.
pub struct AnyBox { pub struct AnyBox {
view: Box<AnyView>, view: Box<AnyView>,
} }
@ -13,7 +15,7 @@ impl AnyBox {
} }
/// Box the given view /// Box the given view
pub fn boxed<T: BoxableView>(view: T) -> Self { pub fn boxed<T: IntoBoxedView>(view: T) -> Self {
AnyBox::new(view.as_boxed_view()) AnyBox::new(view.as_boxed_view())
} }

View File

@ -7,7 +7,7 @@ use std::cell;
use std::ops::Deref; use std::ops::Deref;
use theme::ColorStyle; use theme::ColorStyle;
use vec::Vec2; use vec::Vec2;
use view::{AnyView, BoxableView, Offset, Position, Selector, View, use view::{AnyView, IntoBoxedView, Offset, Position, Selector, View,
ViewWrapper}; ViewWrapper};
use views::{AnyBox, Layer, ShadowView}; use views::{AnyBox, Layer, ShadowView};
@ -181,7 +181,7 @@ impl StackView {
/// Fullscreen layers have no shadow. /// Fullscreen layers have no shadow.
pub fn add_fullscreen_layer<T>(&mut self, view: T) pub fn add_fullscreen_layer<T>(&mut self, view: T)
where where
T: BoxableView, T: IntoBoxedView,
{ {
let boxed = AnyBox::boxed(view); let boxed = AnyBox::boxed(view);
self.layers.push(Child { self.layers.push(Child {
@ -195,7 +195,7 @@ impl StackView {
/// Adds new view on top of the stack in the center of the screen. /// Adds new view on top of the stack in the center of the screen.
pub fn add_layer<T>(&mut self, view: T) pub fn add_layer<T>(&mut self, view: T)
where where
T: BoxableView, T: IntoBoxedView,
{ {
self.add_layer_at(Position::center(), view); self.add_layer_at(Position::center(), view);
} }
@ -205,7 +205,7 @@ impl StackView {
/// Chainable variant. /// Chainable variant.
pub fn layer<T>(self, view: T) -> Self pub fn layer<T>(self, view: T) -> Self
where where
T: BoxableView, T: IntoBoxedView,
{ {
self.with(|s| s.add_layer(view)) self.with(|s| s.add_layer(view))
} }
@ -266,7 +266,7 @@ impl StackView {
/// Chainable variant. /// Chainable variant.
pub fn fullscreen_layer<T>(self, view: T) -> Self pub fn fullscreen_layer<T>(self, view: T) -> Self
where where
T: BoxableView, T: IntoBoxedView,
{ {
self.with(|s| s.add_fullscreen_layer(view)) self.with(|s| s.add_fullscreen_layer(view))
} }
@ -274,7 +274,7 @@ impl StackView {
/// Adds a view on top of the stack. /// Adds a view on top of the stack.
pub fn add_layer_at<T>(&mut self, position: Position, view: T) pub fn add_layer_at<T>(&mut self, position: Position, view: T)
where where
T: BoxableView, T: IntoBoxedView,
{ {
let boxed = AnyBox::boxed(view); let boxed = AnyBox::boxed(view);
self.layers.push(Child { self.layers.push(Child {
@ -295,7 +295,7 @@ impl StackView {
/// Chainable variant. /// Chainable variant.
pub fn layer_at<T>(self, position: Position, view: T) -> Self pub fn layer_at<T>(self, position: Position, view: T) -> Self
where where
T: BoxableView, T: IntoBoxedView,
{ {
self.with(|s| s.add_layer_at(position, view)) self.with(|s| s.add_layer_at(position, view))
} }