From ec8f7c93e8b97145911c7367bbd80f2609742a2b Mon Sep 17 00:00:00 2001 From: Alexandre Bury Date: Thu, 24 Jan 2019 11:57:30 -0800 Subject: [PATCH] Wrap each layer in a CircularFocus --- examples/dialog.rs | 11 ++-- src/views/circular_focus.rs | 2 + src/views/stack_view.rs | 111 ++++++++++++++++++++---------------- 3 files changed, 70 insertions(+), 54 deletions(-) diff --git a/examples/dialog.rs b/examples/dialog.rs index bf8ce28..630d4c6 100644 --- a/examples/dialog.rs +++ b/examples/dialog.rs @@ -1,6 +1,6 @@ extern crate cursive; -use cursive::views::{Dialog, TextView}; +use cursive::views::{CircularFocus, Dialog, TextView}; use cursive::Cursive; fn main() { @@ -10,9 +10,12 @@ fn main() { // Creates a dialog with a single "Quit" button siv.add_layer( // Most views can be configured in a chainable way - Dialog::around(TextView::new("Hello Dialog!")) - .title("Cursive") - .button("Quit", |s| s.quit()), + CircularFocus::wrap_tab( + Dialog::around(TextView::new("Hello Dialog!")) + .title("Cursive") + .button("Foo", |s| ()) + .button("Quit", |s| s.quit()), + ), ); // Starts the event loop. diff --git a/src/views/circular_focus.rs b/src/views/circular_focus.rs index c7e9329..485ccb8 100644 --- a/src/views/circular_focus.rs +++ b/src/views/circular_focus.rs @@ -53,6 +53,8 @@ impl CircularFocus { pub fn wraps_arrows(&self) -> bool { self.wrap_arrows } + + inner_getters!(self.view: T); } impl ViewWrapper for CircularFocus { diff --git a/src/views/stack_view.rs b/src/views/stack_view.rs index 8990f7a..65f1b2e 100644 --- a/src/views/stack_view.rs +++ b/src/views/stack_view.rs @@ -5,7 +5,7 @@ use std::ops::Deref; use theme::ColorStyle; use vec::Vec2; use view::{IntoBoxedView, Offset, Position, Selector, View, ViewWrapper}; -use views::{Layer, ShadowView, ViewBox}; +use views::{CircularFocus, Layer, ShadowView, ViewBox}; use Printer; use With; @@ -55,27 +55,39 @@ impl Placement { // A child view can be wrapped in multiple ways. enum ChildWrapper { // Some views include a shadow around. - Shadow(ShadowView>), + Shadow(ShadowView>>), // Some include only include a background. - Backfilled(Layer), + Backfilled(Layer>), // Some views don't even have a background (they'll be transparent). - Plain(T), + Plain(CircularFocus), } impl ChildWrapper { fn unwrap(self) -> T { match self { - // ShadowView::into_inner and Layer::into_inner can never fail. - ChildWrapper::Shadow(shadow) => { - shadow.into_inner().ok().unwrap().into_inner().ok().unwrap() - } + // All these into_inner() can never fail. + // (ShadowView, Layer, CircularFocus) + ChildWrapper::Shadow(shadow) => shadow + .into_inner() + .ok() + .unwrap() + .into_inner() + .ok() + .unwrap() + .into_inner() + .ok() + .unwrap(), // Layer::into_inner can never fail. - ChildWrapper::Backfilled(background) => { - background.into_inner().ok().unwrap() - } - ChildWrapper::Plain(layer) => layer, + ChildWrapper::Backfilled(background) => background + .into_inner() + .ok() + .unwrap() + .into_inner() + .ok() + .unwrap(), + ChildWrapper::Plain(layer) => layer.into_inner().ok().unwrap(), } } } @@ -84,9 +96,13 @@ impl ChildWrapper { /// Returns a reference to the inner view pub fn get_inner(&self) -> &T { match *self { - ChildWrapper::Shadow(ref shadow) => shadow.get_inner().get_inner(), - ChildWrapper::Backfilled(ref background) => background.get_inner(), - ChildWrapper::Plain(ref layer) => layer, + ChildWrapper::Shadow(ref shadow) => { + shadow.get_inner().get_inner().get_inner() + } + ChildWrapper::Backfilled(ref background) => { + background.get_inner().get_inner() + } + ChildWrapper::Plain(ref layer) => layer.get_inner(), } } @@ -94,12 +110,12 @@ impl ChildWrapper { pub fn get_inner_mut(&mut self) -> &mut T { match *self { ChildWrapper::Shadow(ref mut shadow) => { - shadow.get_inner_mut().get_inner_mut() + shadow.get_inner_mut().get_inner_mut().get_inner_mut() } ChildWrapper::Backfilled(ref mut background) => { - background.get_inner_mut() + background.get_inner_mut().get_inner_mut() } - ChildWrapper::Plain(ref mut layer) => layer, + ChildWrapper::Plain(ref mut layer) => layer.get_inner_mut(), } } } @@ -202,7 +218,9 @@ impl StackView { { let boxed = ViewBox::boxed(view); self.layers.push(Child { - view: ChildWrapper::Backfilled(Layer::new(boxed)), + view: ChildWrapper::Backfilled(Layer::new( + CircularFocus::wrap_tab(boxed), + )), size: Vec2::zero(), placement: Placement::Fullscreen, virgin: true, @@ -307,7 +325,7 @@ impl StackView { self.layers.push(Child { // Skip padding for absolute/parent-placed views view: ChildWrapper::Shadow( - ShadowView::new(Layer::new(boxed)) + ShadowView::new(Layer::new(CircularFocus::wrap_tab(boxed))) .top_padding(position.y == Offset::Center) .left_padding(position.x == Offset::Center), ), @@ -332,7 +350,7 @@ impl StackView { { let boxed = ViewBox::boxed(view); self.layers.push(Child { - view: ChildWrapper::Plain(boxed), + view: ChildWrapper::Plain(CircularFocus::wrap_tab(boxed)), size: Vec2::new(0, 0), placement: Placement::Floating(position), virgin: true, @@ -531,7 +549,8 @@ impl View for StackView { match StackPositionIterator::new( self.layers.iter_mut(), self.last_size, - ).last() + ) + .last() { None => EventResult::Ignored, Some((v, offset)) => v.view.on_event(event.relativized(offset)), @@ -674,33 +693,25 @@ mod tests { .layer(TextView::new("1")) .layer(TextView::new("2")); - assert!( - stack - .get(LayerPosition::FromFront(0)) - .unwrap() - .as_any() - .is::() - ); - assert!( - stack - .get(LayerPosition::FromBack(0)) - .unwrap() - .as_any() - .is::() - ); - assert!( - stack - .get_mut(LayerPosition::FromFront(0)) - .unwrap() - .as_any_mut() - .is::() - ); - assert!( - stack - .get_mut(LayerPosition::FromBack(0)) - .unwrap() - .as_any_mut() - .is::() - ); + assert!(stack + .get(LayerPosition::FromFront(0)) + .unwrap() + .as_any() + .is::()); + assert!(stack + .get(LayerPosition::FromBack(0)) + .unwrap() + .as_any() + .is::()); + assert!(stack + .get_mut(LayerPosition::FromFront(0)) + .unwrap() + .as_any_mut() + .is::()); + assert!(stack + .get_mut(LayerPosition::FromBack(0)) + .unwrap() + .as_any_mut() + .is::()); } }