StackView: store Layer<Box<V>> rather than Box<Layer<V>>

Rather than storing a Layer<V> as a Box<View>,
stores a Layer<Box<View>>, so we can unwrap it when
popping layers.
This commit is contained in:
Alexandre Bury 2017-12-15 08:19:18 +01:00
parent fd259bf32c
commit 1b7170e308

View File

@ -39,8 +39,73 @@ impl Placement {
} }
} }
// A child view can be wrapped in multiple ways.
enum ChildWrapper<T: View> {
// Some views include a shadow around.
Shadow(ShadowView<Layer<T>>),
// Some views don't (fullscreen views mostly)
Plain(Layer<T>),
}
// TODO: use macros to make this less ugly?
impl <T: View> View for ChildWrapper<T> {
fn draw(&self, printer: &Printer) {
match *self {
ChildWrapper::Shadow(ref v) => v.draw(printer),
ChildWrapper::Plain(ref v) => v.draw(printer),
}
}
fn on_event(&mut self, event: Event) -> EventResult {
match *self {
ChildWrapper::Shadow(ref mut v) => v.on_event(event),
ChildWrapper::Plain(ref mut v) => v.on_event(event),
}
}
fn layout(&mut self, size: Vec2) {
match *self {
ChildWrapper::Shadow(ref mut v) => v.layout(size),
ChildWrapper::Plain(ref mut v) => v.layout(size),
}
}
fn required_size(&mut self, size: Vec2) -> Vec2 {
match *self {
ChildWrapper::Shadow(ref mut v) => v.required_size(size),
ChildWrapper::Plain(ref mut v) => v.required_size(size),
}
}
fn take_focus(&mut self, source: Direction) -> bool {
match *self {
ChildWrapper::Shadow(ref mut v) => v.take_focus(source),
ChildWrapper::Plain(ref mut v) => v.take_focus(source),
}
}
fn call_on_any<'a>(
&mut self, selector: &Selector,
callback: Box<FnMut(&mut Any) + 'a>,
) {
match *self {
ChildWrapper::Shadow(ref mut v) => v.call_on_any(selector, callback),
ChildWrapper::Plain(ref mut v) => v.call_on_any(selector, callback),
}
}
fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
match *self {
ChildWrapper::Shadow(ref mut v) => v.focus_view(selector),
ChildWrapper::Plain(ref mut v) => v.focus_view(selector),
}
}
}
struct Child { struct Child {
view: Box<View>, view: ChildWrapper<Box<View>>,
size: Vec2, size: Vec2,
placement: Placement, placement: Placement,
@ -69,8 +134,9 @@ impl StackView {
where where
T: 'static + View, T: 'static + View,
{ {
let boxed: Box<View> = Box::new(view);
self.layers.push(Child { self.layers.push(Child {
view: Box::new(Layer::new(view)), view: ChildWrapper::Plain(Layer::new(boxed)),
size: Vec2::zero(), size: Vec2::zero(),
placement: Placement::Fullscreen, placement: Placement::Fullscreen,
virgin: true, virgin: true,
@ -110,10 +176,11 @@ impl StackView {
where where
T: 'static + View, T: 'static + View,
{ {
let boxed: Box<View> = Box::new(view);
self.layers.push(Child { self.layers.push(Child {
// Skip padding for absolute/parent-placed views // Skip padding for absolute/parent-placed views
view: Box::new( view: ChildWrapper::Shadow(
ShadowView::new(Layer::new(view)) ShadowView::new(Layer::new(boxed))
.top_padding(position.y == Offset::Center) .top_padding(position.y == Offset::Center)
.left_padding(position.x == Offset::Center), .left_padding(position.x == Offset::Center),
), ),