mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Add StackView::remove_layer
This commit is contained in:
parent
6171930649
commit
027038db6f
@ -20,8 +20,12 @@ pub struct StackView {
|
|||||||
bg_dirty: cell::Cell<bool>,
|
bg_dirty: cell::Cell<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Where should the view be on the screen (per dimension).
|
||||||
enum Placement {
|
enum Placement {
|
||||||
|
/// View is floating at a specific position.
|
||||||
Floating(Position),
|
Floating(Position),
|
||||||
|
|
||||||
|
/// View is full-screen; it should not have a 1-cell border.
|
||||||
Fullscreen,
|
Fullscreen,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +56,7 @@ impl Placement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A child view can be wrapped in multiple ways.
|
/// A child view can be wrapped in multiple ways.
|
||||||
enum ChildWrapper<T: View> {
|
enum ChildWrapper<T: View> {
|
||||||
// Some views include a shadow around.
|
// Some views include a shadow around.
|
||||||
Shadow(ShadowView<Layer<CircularFocus<T>>>),
|
Shadow(ShadowView<Layer<CircularFocus<T>>>),
|
||||||
@ -209,6 +213,22 @@ impl StackView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the number of layers in this `StackView`.
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.layers.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if `position` points to a valid layer.
|
||||||
|
///
|
||||||
|
/// Returns `false` if it exceeds the bounds.
|
||||||
|
pub fn fits(&self, position: LayerPosition) -> bool {
|
||||||
|
let i = match position {
|
||||||
|
LayerPosition::FromBack(i) | LayerPosition::FromFront(i) => i,
|
||||||
|
};
|
||||||
|
|
||||||
|
i < self.len()
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds a new full-screen layer on top of the stack.
|
/// Adds a new full-screen layer on top of the stack.
|
||||||
///
|
///
|
||||||
/// Fullscreen layers have no shadow.
|
/// Fullscreen layers have no shadow.
|
||||||
@ -247,16 +267,18 @@ impl StackView {
|
|||||||
|
|
||||||
/// Returns a reference to the layer at the given position.
|
/// Returns a reference to the layer at the given position.
|
||||||
pub fn get(&self, pos: LayerPosition) -> Option<&View> {
|
pub fn get(&self, pos: LayerPosition) -> Option<&View> {
|
||||||
let i = self.get_index(pos);
|
self.get_index(pos).and_then(|i| {
|
||||||
self.layers.get(i).map(|child| &**child.view.get_inner())
|
self.layers.get(i).map(|child| &**child.view.get_inner())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a mutable reference to the layer at the given position.
|
/// Returns a mutable reference to the layer at the given position.
|
||||||
pub fn get_mut(&mut self, pos: LayerPosition) -> Option<&mut View> {
|
pub fn get_mut(&mut self, pos: LayerPosition) -> Option<&mut View> {
|
||||||
let i = self.get_index(pos);
|
self.get_index(pos).and_then(move |i| {
|
||||||
self.layers
|
self.layers
|
||||||
.get_mut(i)
|
.get_mut(i)
|
||||||
.map(|child| &mut **child.view.get_inner_mut())
|
.map(|child| &mut **child.view.get_inner_mut())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Looks for the layer containing a view with the given ID.
|
/// Looks for the layer containing a view with the given ID.
|
||||||
@ -266,6 +288,9 @@ impl StackView {
|
|||||||
///
|
///
|
||||||
/// Returns `None` if the given ID is not found.
|
/// Returns `None` if the given ID is not found.
|
||||||
///
|
///
|
||||||
|
/// Note that the returned position may be invalidated if some layers are
|
||||||
|
/// removed from the view.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
@ -357,7 +382,7 @@ impl StackView {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a view on top of the stack.
|
/// Adds a view on top of the stack at the given position.
|
||||||
///
|
///
|
||||||
/// Chainable variant.
|
/// Chainable variant.
|
||||||
pub fn layer_at<T>(self, position: Position, view: T) -> Self
|
pub fn layer_at<T>(self, position: Position, view: T) -> Self
|
||||||
@ -367,6 +392,16 @@ impl StackView {
|
|||||||
self.with(|s| s.add_layer_at(position, view))
|
self.with(|s| s.add_layer_at(position, view))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Remove a layer from this `StackView`.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// If the given position is out of bounds.
|
||||||
|
pub fn remove_layer(&mut self, position: LayerPosition) -> Box<View> {
|
||||||
|
let i = self.get_index(position).unwrap();
|
||||||
|
self.layers.remove(i).view.unwrap().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
/// Remove the top-most layer.
|
/// Remove the top-most layer.
|
||||||
pub fn pop_layer(&mut self) -> Option<Box<View>> {
|
pub fn pop_layer(&mut self) -> Option<Box<View>> {
|
||||||
self.bg_dirty.set(true);
|
self.bg_dirty.set(true);
|
||||||
@ -396,10 +431,12 @@ impl StackView {
|
|||||||
self.layers.iter().map(|layer| layer.size).collect()
|
self.layers.iter().map(|layer| layer.size).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_index(&self, pos: LayerPosition) -> usize {
|
fn get_index(&self, pos: LayerPosition) -> Option<usize> {
|
||||||
match pos {
|
match pos {
|
||||||
LayerPosition::FromBack(i) => i,
|
LayerPosition::FromBack(i) => Some(i),
|
||||||
LayerPosition::FromFront(i) => self.layers.len() - i - 1,
|
LayerPosition::FromFront(i) => {
|
||||||
|
self.layers.len().checked_sub(i + 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,38 +444,47 @@ impl StackView {
|
|||||||
///
|
///
|
||||||
/// This only affects the elevation of a layer (whether it is drawn over
|
/// This only affects the elevation of a layer (whether it is drawn over
|
||||||
/// or under other views).
|
/// or under other views).
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// If either `from` or `to` is out of bounds.
|
||||||
pub fn move_layer(&mut self, from: LayerPosition, to: LayerPosition) {
|
pub fn move_layer(&mut self, from: LayerPosition, to: LayerPosition) {
|
||||||
// Convert relative positions to indices in the array
|
// Convert relative positions to indices in the array
|
||||||
let from_i = self.get_index(from);
|
let from = self.get_index(from).unwrap();
|
||||||
let to_i = self.get_index(to);
|
let to = self.get_index(to).unwrap();
|
||||||
|
|
||||||
let removed = self.layers.remove(from_i);
|
let removed = self.layers.remove(from);
|
||||||
|
self.layers.insert(to, removed);
|
||||||
self.layers.insert(to_i, removed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Brings the given view to the front of the stack.
|
/// Brings the given view to the front of the stack.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// If `layer` is out of bounds.
|
||||||
pub fn move_to_front(&mut self, layer: LayerPosition) {
|
pub fn move_to_front(&mut self, layer: LayerPosition) {
|
||||||
self.move_layer(layer, LayerPosition::FromFront(0));
|
self.move_layer(layer, LayerPosition::FromFront(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pushes the given view to the back of the stack.
|
/// Pushes the given view to the back of the stack.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// If `layer` is out of bounds.
|
||||||
pub fn move_to_back(&mut self, layer: LayerPosition) {
|
pub fn move_to_back(&mut self, layer: LayerPosition) {
|
||||||
self.move_layer(layer, LayerPosition::FromBack(0));
|
self.move_layer(layer, LayerPosition::FromBack(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Moves a layer to a new position on the screen.
|
/// Moves a layer to a new position on the screen.
|
||||||
///
|
///
|
||||||
/// Has no effect on fullscreen layers
|
/// # Panics
|
||||||
/// Has no effect if layer is not found
|
///
|
||||||
|
/// If `layer` is out of bounds.
|
||||||
pub fn reposition_layer(
|
pub fn reposition_layer(
|
||||||
&mut self, layer: LayerPosition, position: Position,
|
&mut self, layer: LayerPosition, position: Position,
|
||||||
) {
|
) {
|
||||||
let i = self.get_index(layer);
|
let i = self.get_index(layer).unwrap();
|
||||||
let child = match self.layers.get_mut(i) {
|
let child = &mut self.layers[i];
|
||||||
Some(i) => i,
|
|
||||||
None => return,
|
|
||||||
};
|
|
||||||
match child.placement {
|
match child.placement {
|
||||||
Placement::Floating(_) => {
|
Placement::Floating(_) => {
|
||||||
child.placement = Placement::Floating(position);
|
child.placement = Placement::Floating(position);
|
||||||
@ -451,7 +497,8 @@ impl StackView {
|
|||||||
/// Background drawing
|
/// Background drawing
|
||||||
///
|
///
|
||||||
/// Drawing functions are split into forground and background to
|
/// Drawing functions are split into forground and background to
|
||||||
/// ease inserting layers under the stackview but above it's background
|
/// ease inserting layers under the stackview but above its background.
|
||||||
|
///
|
||||||
/// you probably just want to call draw()
|
/// you probably just want to call draw()
|
||||||
pub fn draw_bg(&self, printer: &Printer) {
|
pub fn draw_bg(&self, printer: &Printer) {
|
||||||
// If the background is dirty draw a new background
|
// If the background is dirty draw a new background
|
||||||
@ -470,8 +517,9 @@ impl StackView {
|
|||||||
/// Forground drawing
|
/// Forground drawing
|
||||||
///
|
///
|
||||||
/// Drawing functions are split into forground and background to
|
/// Drawing functions are split into forground and background to
|
||||||
/// ease inserting layers under the stackview but above it's background
|
/// ease inserting layers under the stackview but above its background.
|
||||||
/// you probably just want to call draw()
|
///
|
||||||
|
/// You probably just want to call draw()
|
||||||
pub fn draw_fg(&self, printer: &Printer) {
|
pub fn draw_fg(&self, printer: &Printer) {
|
||||||
let last = self.layers.len();
|
let last = self.layers.len();
|
||||||
printer.with_color(ColorStyle::primary(), |printer| {
|
printer.with_color(ColorStyle::primary(), |printer| {
|
||||||
@ -490,14 +538,17 @@ impl StackView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StackPositionIterator<R: Deref<Target = Child>, I: Iterator<Item = R>> {
|
/// Iterates on the layers and compute the position of each.
|
||||||
|
struct StackPositionIterator<I> {
|
||||||
inner: I,
|
inner: I,
|
||||||
previous: Vec2,
|
previous: Vec2,
|
||||||
total_size: Vec2,
|
total_size: Vec2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Deref<Target = Child>, I: Iterator<Item = R>>
|
impl<I> StackPositionIterator<I>
|
||||||
StackPositionIterator<R, I>
|
where
|
||||||
|
I: Iterator,
|
||||||
|
I::Item: Deref<Target = Child>,
|
||||||
{
|
{
|
||||||
/// Returns a new StackPositionIterator
|
/// Returns a new StackPositionIterator
|
||||||
pub fn new(inner: I, total_size: Vec2) -> Self {
|
pub fn new(inner: I, total_size: Vec2) -> Self {
|
||||||
@ -510,12 +561,14 @@ impl<R: Deref<Target = Child>, I: Iterator<Item = R>>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Deref<Target = Child>, I: Iterator<Item = R>> Iterator
|
impl<I> Iterator for StackPositionIterator<I>
|
||||||
for StackPositionIterator<R, I>
|
where
|
||||||
|
I: Iterator,
|
||||||
|
I::Item: Deref<Target = Child>,
|
||||||
{
|
{
|
||||||
type Item = (R, Vec2);
|
type Item = (I::Item, Vec2);
|
||||||
|
|
||||||
fn next(&mut self) -> Option<(R, Vec2)> {
|
fn next(&mut self) -> Option<(I::Item, Vec2)> {
|
||||||
self.inner.next().map(|v| {
|
self.inner.next().map(|v| {
|
||||||
let offset = v.placement.compute_offset(
|
let offset = v.placement.compute_offset(
|
||||||
v.size,
|
v.size,
|
||||||
|
Loading…
Reference in New Issue
Block a user