mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-27 11:16:03 +00:00
Use an associated type in ViewWrapper
This removes the need for dynamic dispatching
This commit is contained in:
parent
3813f7c446
commit
08d1c1e5b0
@ -16,11 +16,14 @@ use event::{Event, EventResult};
|
|||||||
///
|
///
|
||||||
/// [`wrap_impl!`]: ../macro.wrap_impl.html
|
/// [`wrap_impl!`]: ../macro.wrap_impl.html
|
||||||
pub trait ViewWrapper {
|
pub trait ViewWrapper {
|
||||||
|
/// Type that this view wraps.
|
||||||
|
type V: View;
|
||||||
|
|
||||||
/// Get an immutable reference to the wrapped view.
|
/// Get an immutable reference to the wrapped view.
|
||||||
fn get_view(&self) -> &View;
|
fn get_view(&self) -> &Self::V;
|
||||||
|
|
||||||
/// Get a mutable reference to the wrapped view.
|
/// Get a mutable reference to the wrapped view.
|
||||||
fn get_view_mut(&mut self) -> &mut View;
|
fn get_view_mut(&mut self) -> &mut Self::V;
|
||||||
|
|
||||||
/// Wraps the `draw` method.
|
/// Wraps the `draw` method.
|
||||||
fn wrap_draw(&self, printer: &Printer) {
|
fn wrap_draw(&self, printer: &Printer) {
|
||||||
@ -90,27 +93,13 @@ impl<T: ViewWrapper> View for T {
|
|||||||
|
|
||||||
/// Convenient macro to implement the [`ViewWrapper`] trait.
|
/// Convenient macro to implement the [`ViewWrapper`] trait.
|
||||||
///
|
///
|
||||||
|
/// It defines the `get_view` and `get_view_mut` implementations,
|
||||||
|
/// as well as the `type V` declaration.
|
||||||
|
///
|
||||||
/// [`ViewWrapper`]: view/trait.ViewWrapper.html
|
/// [`ViewWrapper`]: view/trait.ViewWrapper.html
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// If the wrapped view is in a box, just name it in the macro:
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// # #[macro_use] extern crate cursive;
|
|
||||||
/// # use cursive::view::{View,ViewWrapper};
|
|
||||||
/// struct BoxFooView {
|
|
||||||
/// content: Box<View>,
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl ViewWrapper for BoxFooView {
|
|
||||||
/// wrap_impl!(self.content);
|
|
||||||
/// }
|
|
||||||
/// # fn main() { }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// If the content is directly a view, reference it:
|
|
||||||
///
|
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// # #[macro_use] extern crate cursive;
|
/// # #[macro_use] extern crate cursive;
|
||||||
/// # use cursive::view::{View,ViewWrapper};
|
/// # use cursive::view::{View,ViewWrapper};
|
||||||
@ -119,30 +108,21 @@ impl<T: ViewWrapper> View for T {
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// impl <T: View> ViewWrapper for FooView<T> {
|
/// impl <T: View> ViewWrapper for FooView<T> {
|
||||||
/// wrap_impl!(&self.view);
|
/// wrap_impl!(self.view: T);
|
||||||
/// }
|
/// }
|
||||||
/// # fn main() { }
|
/// # fn main() { }
|
||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! wrap_impl {
|
macro_rules! wrap_impl {
|
||||||
(&self.$v:ident) => {
|
(self.$v:ident: $t:path) => {
|
||||||
|
type V = $t;
|
||||||
|
|
||||||
fn get_view(&self) -> &View {
|
fn get_view(&self) -> &Self::V {
|
||||||
&self.$v
|
&self.$v
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_view_mut(&mut self) -> &mut View {
|
fn get_view_mut(&mut self) -> &mut Self::V {
|
||||||
&mut self.$v
|
&mut self.$v
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
(self.$v:ident) => {
|
|
||||||
|
|
||||||
fn get_view(&self) -> &View {
|
|
||||||
&*self.$v
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_view_mut(&mut self) -> &mut View {
|
|
||||||
&mut *self.$v
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ impl<T: View> BoxView<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: View> ViewWrapper for BoxView<T> {
|
impl<T: View> ViewWrapper for BoxView<T> {
|
||||||
wrap_impl!(&self.view);
|
wrap_impl!(self.view: T);
|
||||||
|
|
||||||
fn wrap_get_min_size(&mut self, req: Vec2) -> Vec2 {
|
fn wrap_get_min_size(&mut self, req: Vec2) -> Vec2 {
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ impl<T: View> IdView<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: View + Any> ViewWrapper for IdView<T> {
|
impl<T: View + Any> ViewWrapper for IdView<T> {
|
||||||
wrap_impl!(&self.view);
|
wrap_impl!(self.view: T);
|
||||||
|
|
||||||
fn wrap_find(&mut self, selector: &Selector) -> Option<&mut Any> {
|
fn wrap_find(&mut self, selector: &Selector) -> Option<&mut Any> {
|
||||||
match selector {
|
match selector {
|
||||||
|
@ -16,16 +16,16 @@ use view::{View, ViewWrapper};
|
|||||||
/// .register('q', |s| s.quit())
|
/// .register('q', |s| s.quit())
|
||||||
/// .register(Key::Esc, |s| s.quit());
|
/// .register(Key::Esc, |s| s.quit());
|
||||||
/// ```
|
/// ```
|
||||||
pub struct KeyEventView {
|
pub struct KeyEventView<T: View> {
|
||||||
content: Box<View>,
|
content: T,
|
||||||
callbacks: HashMap<Event, Callback>,
|
callbacks: HashMap<Event, Callback>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyEventView {
|
impl <T: View> KeyEventView<T> {
|
||||||
/// Wraps the given view in a new KeyEventView.
|
/// Wraps the given view in a new KeyEventView.
|
||||||
pub fn new<V: View + 'static>(view: V) -> Self {
|
pub fn new(view: T) -> Self {
|
||||||
KeyEventView {
|
KeyEventView {
|
||||||
content: Box::new(view),
|
content: view,
|
||||||
callbacks: HashMap::new(),
|
callbacks: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,8 +40,8 @@ impl KeyEventView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ViewWrapper for KeyEventView {
|
impl <T: View> ViewWrapper for KeyEventView<T> {
|
||||||
wrap_impl!(self.content);
|
wrap_impl!(self.content: T);
|
||||||
|
|
||||||
fn wrap_on_event(&mut self, event: Event) -> EventResult {
|
fn wrap_on_event(&mut self, event: Event) -> EventResult {
|
||||||
match self.content.on_event(event) {
|
match self.content.on_event(event) {
|
||||||
|
@ -16,7 +16,7 @@ impl<V: View> Panel<V> {
|
|||||||
|
|
||||||
|
|
||||||
impl<V: View> ViewWrapper for Panel<V> {
|
impl<V: View> ViewWrapper for Panel<V> {
|
||||||
wrap_impl!(&self.view);
|
wrap_impl!(self.view: V);
|
||||||
|
|
||||||
fn wrap_get_min_size(&mut self, req: Vec2) -> Vec2 {
|
fn wrap_get_min_size(&mut self, req: Vec2) -> Vec2 {
|
||||||
// TODO: make borders conditional?
|
// TODO: make borders conditional?
|
||||||
|
@ -45,7 +45,7 @@ impl<T: View> ShadowView<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: View> ViewWrapper for ShadowView<T> {
|
impl<T: View> ViewWrapper for ShadowView<T> {
|
||||||
wrap_impl!(&self.view);
|
wrap_impl!(self.view: T);
|
||||||
|
|
||||||
fn wrap_get_min_size(&mut self, req: Vec2) -> Vec2 {
|
fn wrap_get_min_size(&mut self, req: Vec2) -> Vec2 {
|
||||||
// Make sure req >= offset
|
// Make sure req >= offset
|
||||||
|
@ -21,7 +21,7 @@ impl<T: View> SizedView<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: View> ViewWrapper for SizedView<T> {
|
impl<T: View> ViewWrapper for SizedView<T> {
|
||||||
wrap_impl!(&self.view);
|
wrap_impl!(self.view: T);
|
||||||
|
|
||||||
fn wrap_layout(&mut self, size: Vec2) {
|
fn wrap_layout(&mut self, size: Vec2) {
|
||||||
self.size = size;
|
self.size = size;
|
||||||
|
@ -36,7 +36,7 @@ impl<T: View> TrackedView<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: View> ViewWrapper for TrackedView<T> {
|
impl<T: View> ViewWrapper for TrackedView<T> {
|
||||||
wrap_impl!(&self.view);
|
wrap_impl!(self.view: T);
|
||||||
|
|
||||||
fn wrap_draw(&self, printer: &Printer) {
|
fn wrap_draw(&self, printer: &Printer) {
|
||||||
self.offset.set(printer.offset);
|
self.offset.set(printer.offset);
|
||||||
|
Loading…
Reference in New Issue
Block a user