mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +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
|
||||
pub trait ViewWrapper {
|
||||
/// Type that this view wraps.
|
||||
type V: 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.
|
||||
fn get_view_mut(&mut self) -> &mut View;
|
||||
fn get_view_mut(&mut self) -> &mut Self::V;
|
||||
|
||||
/// Wraps the `draw` method.
|
||||
fn wrap_draw(&self, printer: &Printer) {
|
||||
@ -90,27 +93,13 @@ impl<T: ViewWrapper> View for T {
|
||||
|
||||
/// 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
|
||||
///
|
||||
/// # 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
|
||||
/// # #[macro_use] extern crate cursive;
|
||||
/// # use cursive::view::{View,ViewWrapper};
|
||||
@ -119,30 +108,21 @@ impl<T: ViewWrapper> View for T {
|
||||
/// }
|
||||
///
|
||||
/// impl <T: View> ViewWrapper for FooView<T> {
|
||||
/// wrap_impl!(&self.view);
|
||||
/// wrap_impl!(self.view: T);
|
||||
/// }
|
||||
/// # fn main() { }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
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
|
||||
}
|
||||
|
||||
fn get_view_mut(&mut self) -> &mut View {
|
||||
fn get_view_mut(&mut self) -> &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> {
|
||||
wrap_impl!(&self.view);
|
||||
wrap_impl!(self.view: T);
|
||||
|
||||
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> {
|
||||
wrap_impl!(&self.view);
|
||||
wrap_impl!(self.view: T);
|
||||
|
||||
fn wrap_find(&mut self, selector: &Selector) -> Option<&mut Any> {
|
||||
match selector {
|
||||
|
@ -16,16 +16,16 @@ use view::{View, ViewWrapper};
|
||||
/// .register('q', |s| s.quit())
|
||||
/// .register(Key::Esc, |s| s.quit());
|
||||
/// ```
|
||||
pub struct KeyEventView {
|
||||
content: Box<View>,
|
||||
pub struct KeyEventView<T: View> {
|
||||
content: T,
|
||||
callbacks: HashMap<Event, Callback>,
|
||||
}
|
||||
|
||||
impl KeyEventView {
|
||||
impl <T: View> KeyEventView<T> {
|
||||
/// Wraps the given view in a new KeyEventView.
|
||||
pub fn new<V: View + 'static>(view: V) -> Self {
|
||||
pub fn new(view: T) -> Self {
|
||||
KeyEventView {
|
||||
content: Box::new(view),
|
||||
content: view,
|
||||
callbacks: HashMap::new(),
|
||||
}
|
||||
}
|
||||
@ -40,8 +40,8 @@ impl KeyEventView {
|
||||
}
|
||||
}
|
||||
|
||||
impl ViewWrapper for KeyEventView {
|
||||
wrap_impl!(self.content);
|
||||
impl <T: View> ViewWrapper for KeyEventView<T> {
|
||||
wrap_impl!(self.content: T);
|
||||
|
||||
fn wrap_on_event(&mut self, event: Event) -> EventResult {
|
||||
match self.content.on_event(event) {
|
||||
|
@ -16,7 +16,7 @@ impl<V: View> 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 {
|
||||
// TODO: make borders conditional?
|
||||
|
@ -45,7 +45,7 @@ impl<T: View> 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 {
|
||||
// Make sure req >= offset
|
||||
|
@ -21,7 +21,7 @@ impl<T: View> 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) {
|
||||
self.size = size;
|
||||
|
@ -36,7 +36,7 @@ impl<T: View> TrackedView<T> {
|
||||
}
|
||||
|
||||
impl<T: View> ViewWrapper for TrackedView<T> {
|
||||
wrap_impl!(&self.view);
|
||||
wrap_impl!(self.view: T);
|
||||
|
||||
fn wrap_draw(&self, printer: &Printer) {
|
||||
self.offset.set(printer.offset);
|
||||
|
Loading…
Reference in New Issue
Block a user