From 8da659367d55a2a7b0746af0225ddc6b291036c8 Mon Sep 17 00:00:00 2001 From: Alexandre Bury Date: Mon, 18 Dec 2017 18:18:23 +0100 Subject: [PATCH] Add StackView::move_layer --- src/views/mod.rs | 2 +- src/views/stack_view.rs | 48 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/views/mod.rs b/src/views/mod.rs index 36b61a1..d803fa6 100644 --- a/src/views/mod.rs +++ b/src/views/mod.rs @@ -82,7 +82,7 @@ pub use self::select_view::SelectView; pub use self::shadow_view::ShadowView; pub use self::sized_view::SizedView; pub use self::slider_view::SliderView; -pub use self::stack_view::StackView; +pub use self::stack_view::{StackView, LayerPosition}; pub use self::text_area::TextArea; pub use self::text_view::TextView; pub use self::tracked_view::TrackedView; diff --git a/src/views/stack_view.rs b/src/views/stack_view.rs index ad90789..fbf84a5 100644 --- a/src/views/stack_view.rs +++ b/src/views/stack_view.rs @@ -12,6 +12,7 @@ use views::{Layer, ShadowView}; /// Simple stack of views. /// Only the top-most view is active and can receive input. pub struct StackView { + // Store layers from back to front. layers: Vec, last_size: Vec2, } @@ -21,6 +22,15 @@ enum Placement { Fullscreen, } +/// Identifies a layer in a `StackView`. +#[derive(Clone, Copy, Debug)] +pub enum LayerPosition { + /// Starts from the back (bottom) of the stack. + FromBack(usize), + /// Starts from the front (top) of the stack. + FromFront(usize), +} + impl Placement { pub fn compute_offset( &self, size: S, available: A, parent: P @@ -236,6 +246,44 @@ impl StackView { pub fn layer_sizes(&self) -> Vec { self.layers.iter().map(|layer| layer.size).collect() } + + fn get_index(&self, pos: LayerPosition) -> usize { + match pos { + LayerPosition::FromBack(i) => i, + LayerPosition::FromFront(i) => self.layers.len() - i - 1, + } + } + + /// Moves a layer to a new position in the stack. + /// + /// This only affects the elevation of a layer (whether it is drawn over + /// or under other views). + pub fn move_layer(&mut self, from: LayerPosition, to: LayerPosition) { + // Convert relative positions to indices in the array + let from_i = self.get_index(from); + let to_i = self.get_index(to); + + let removed = self.layers.remove(from_i); + + // Shift the position if needed + let to_i = if to_i > from_i { + to_i - 1 + } else { + to_i + }; + + self.layers.insert(to_i, removed); + } + + /// Brings the given view to the front of the stack. + pub fn move_to_front(&mut self, layer: LayerPosition) { + self.move_layer(layer, LayerPosition::FromFront(0)); + } + + /// Pushes the given view to the back of the stack. + pub fn move_to_back(&mut self, layer: LayerPosition) { + self.move_layer(layer, LayerPosition::FromBack(0)); + } } struct StackPositionIterator, I: Iterator> {