mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-09 10:50:40 +00:00
parent
053544d192
commit
f504ad8f0e
@ -15,7 +15,7 @@ fn main() {
|
||||
|
||||
// The text is too long to fit on a line, so the view will wrap lines,
|
||||
// and will adapt to the terminal size.
|
||||
siv.add_layer(Dialog::around(TextView::new(content))
|
||||
siv.add_fullscreen_layer(Dialog::around(TextView::new(content))
|
||||
.h_align(HAlign::Center)
|
||||
.button("Quit", |s| s.quit()));
|
||||
// Show a popup on top of the view.
|
||||
|
11
src/lib.rs
11
src/lib.rs
@ -437,7 +437,7 @@ impl Cursive {
|
||||
self.global_callbacks.insert(event.into(), Callback::from_fn(cb));
|
||||
}
|
||||
|
||||
/// Convenient method to add a layer to the current screen.
|
||||
/// Add a layer to the current screen.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -454,6 +454,15 @@ impl Cursive {
|
||||
self.screen_mut().add_layer(view);
|
||||
}
|
||||
|
||||
/// Adds a new full-screen layer to the current screen.
|
||||
///
|
||||
/// Fullscreen layers have no shadow.
|
||||
pub fn add_fullscreen_layer<T>(&mut self, view: T)
|
||||
where T: 'static + View
|
||||
{
|
||||
self.screen_mut().add_fullscreen_layer(view);
|
||||
}
|
||||
|
||||
/// Convenient method to remove a layer from the current screen.
|
||||
pub fn pop_layer(&mut self) {
|
||||
self.screen_mut().pop_layer();
|
||||
|
31
src/views/layer.rs
Normal file
31
src/views/layer.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use Printer;
|
||||
use view::{View, ViewWrapper};
|
||||
|
||||
/// Wrapper view that fills the background.
|
||||
///
|
||||
/// Used as layer in the [`StackView`].
|
||||
///
|
||||
/// [`StackView`]: struct.StackView.html
|
||||
pub struct Layer<T: View> {
|
||||
view: T,
|
||||
}
|
||||
|
||||
impl <T: View> Layer<T> {
|
||||
/// Wraps the given view.
|
||||
pub fn new(view: T) -> Self {
|
||||
Layer {
|
||||
view: view,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: View> ViewWrapper for Layer<T> {
|
||||
wrap_impl!(self.view: T);
|
||||
|
||||
fn wrap_draw(&self, printer: &Printer) {
|
||||
for y in 0..printer.size.y {
|
||||
printer.print_hline((0, y), printer.size.x, " ");
|
||||
}
|
||||
self.view.draw(printer);
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
//! Various views to use when creating the layout.
|
||||
|
||||
/// A macro to help with creating toggleable views.
|
||||
macro_rules! impl_enabled {
|
||||
(self.$x:ident) => {
|
||||
|
||||
@ -42,6 +43,7 @@ mod dummy;
|
||||
mod edit_view;
|
||||
mod id_view;
|
||||
mod key_event_view;
|
||||
mod layer;
|
||||
mod linear_layout;
|
||||
mod list_view;
|
||||
mod menubar;
|
||||
@ -66,6 +68,7 @@ pub use self::dummy::DummyView;
|
||||
pub use self::edit_view::EditView;
|
||||
pub use self::id_view::IdView;
|
||||
pub use self::key_event_view::KeyEventView;
|
||||
pub use self::layer::Layer;
|
||||
pub use self::linear_layout::LinearLayout;
|
||||
pub use self::list_view::ListView;
|
||||
pub use self::menu_popup::MenuPopup;
|
||||
|
@ -70,16 +70,6 @@ impl<T: View> ViewWrapper for ShadowView<T> {
|
||||
let offset = Vec2::new(self.left_padding as usize,
|
||||
self.top_padding as usize);
|
||||
let printer = &printer.offset(offset, true);
|
||||
|
||||
// Draw the view background
|
||||
for y in 0..printer.size.y - 1 {
|
||||
printer.print_hline((0, y), printer.size.x - 1, " ");
|
||||
}
|
||||
|
||||
self.view.draw(&printer.sub_printer(Vec2::zero(),
|
||||
printer.size - (1, 1),
|
||||
true));
|
||||
|
||||
if printer.theme.shadow {
|
||||
let h = printer.size.y;
|
||||
let w = printer.size.x;
|
||||
@ -89,5 +79,10 @@ impl<T: View> ViewWrapper for ShadowView<T> {
|
||||
printer.print_vline((w - 1, 1), h - 1, " ");
|
||||
});
|
||||
}
|
||||
|
||||
// Draw the view background
|
||||
let printer =
|
||||
printer.sub_printer(Vec2::zero(), printer.size - (1, 1), true);
|
||||
self.view.draw(&printer);
|
||||
}
|
||||
}
|
||||
|
@ -6,20 +6,44 @@ use std::any::Any;
|
||||
use theme::ColorStyle;
|
||||
use vec::Vec2;
|
||||
use view::{Offset, Position, Selector, View};
|
||||
use views::ShadowView;
|
||||
use views::{Layer, ShadowView};
|
||||
|
||||
/// Simple stack of views.
|
||||
/// Only the top-most view is active and can receive input.
|
||||
pub struct StackView {
|
||||
layers: Vec<Layer>,
|
||||
layers: Vec<Child>,
|
||||
last_size: Vec2,
|
||||
}
|
||||
|
||||
struct Layer {
|
||||
enum Placement {
|
||||
Floating(Position),
|
||||
Fullscreen,
|
||||
}
|
||||
|
||||
impl Placement {
|
||||
pub fn compute_offset<S, A, P>(&self, size: S, available: A, parent: P)
|
||||
-> Vec2
|
||||
where S: Into<Vec2>,
|
||||
A: Into<Vec2>,
|
||||
P: Into<Vec2>
|
||||
{
|
||||
match *self {
|
||||
Placement::Floating(ref position) => {
|
||||
position.compute_offset(size, available, parent)
|
||||
}
|
||||
Placement::Fullscreen => Vec2::zero(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Child {
|
||||
view: Box<View>,
|
||||
size: Vec2,
|
||||
position: Position,
|
||||
// Has it received the gift yet?
|
||||
placement: Placement,
|
||||
|
||||
// We cannot call `take_focus` until we've called `layout()`
|
||||
// So we want to call `take_focus` right after the first call
|
||||
// to `layout`; this flag remembers when we've done that.
|
||||
virgin: bool,
|
||||
}
|
||||
|
||||
@ -34,21 +58,38 @@ impl StackView {
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a new full-screen layer on top of the stack.
|
||||
///
|
||||
/// Fullscreen layers have no shadow.
|
||||
pub fn add_fullscreen_layer<T>(&mut self, view: T)
|
||||
where T: 'static + View
|
||||
{
|
||||
self.layers.push(Child {
|
||||
view: Box::new(Layer::new(view)),
|
||||
size: Vec2::zero(),
|
||||
placement: Placement::Fullscreen,
|
||||
virgin: true,
|
||||
});
|
||||
}
|
||||
|
||||
/// Adds new view on top of the stack in the center of the screen.
|
||||
pub fn add_layer<T: 'static + View>(&mut self, view: T) {
|
||||
pub fn add_layer<T>(&mut self, view: T)
|
||||
where T: 'static + View
|
||||
{
|
||||
self.add_layer_at(Position::center(), view);
|
||||
}
|
||||
|
||||
/// Adds a view on top of the stack.
|
||||
pub fn add_layer_at<T: 'static + View>(&mut self, position: Position,
|
||||
view: T) {
|
||||
self.layers.push(Layer {
|
||||
pub fn add_layer_at<T>(&mut self, position: Position, view: T)
|
||||
where T: 'static + View
|
||||
{
|
||||
self.layers.push(Child {
|
||||
// Skip padding for absolute/parent-placed views
|
||||
view: Box::new(ShadowView::new(view)
|
||||
view: Box::new(ShadowView::new(Layer::new(view))
|
||||
.top_padding(position.y == Offset::Center)
|
||||
.left_padding(position.x == Offset::Center)),
|
||||
size: Vec2::new(0, 0),
|
||||
position: position,
|
||||
placement: Placement::Floating(position),
|
||||
virgin: true,
|
||||
});
|
||||
}
|
||||
@ -62,7 +103,7 @@ impl StackView {
|
||||
pub fn offset(&self) -> Vec2 {
|
||||
let mut previous = Vec2::zero();
|
||||
for layer in &self.layers {
|
||||
let offset = layer.position
|
||||
let offset = layer.placement
|
||||
.compute_offset(layer.size, self.last_size, previous);
|
||||
previous = offset;
|
||||
}
|
||||
@ -83,7 +124,7 @@ impl View for StackView {
|
||||
for (i, v) in self.layers.iter().enumerate() {
|
||||
// Place the view
|
||||
// Center the view
|
||||
let offset = v.position
|
||||
let offset = v.placement
|
||||
.compute_offset(v.size, printer.size, previous);
|
||||
|
||||
previous = offset;
|
||||
|
Loading…
Reference in New Issue
Block a user