mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
BugFix in LinearLayout
And add a simple linear example.
This commit is contained in:
parent
df5ff808e3
commit
40af72a567
@ -52,3 +52,7 @@ path = "examples/select.rs"
|
||||
[[example]]
|
||||
name = "theme"
|
||||
path = "examples/theme.rs"
|
||||
|
||||
[[example]]
|
||||
name = "linear"
|
||||
path = "examples/linear.rs"
|
||||
|
25
examples/linear.rs
Normal file
25
examples/linear.rs
Normal file
@ -0,0 +1,25 @@
|
||||
extern crate cursive;
|
||||
|
||||
use cursive::Cursive;
|
||||
use cursive::view::{Dialog,TextView,LinearLayout,BoxView};
|
||||
use cursive::align::HAlign;
|
||||
use cursive::orientation::Orientation;
|
||||
|
||||
fn main() {
|
||||
let mut siv = Cursive::new();
|
||||
|
||||
// Some longish content
|
||||
let text = "This is a very simple example of linear layout. Two views are present, a short title above, and this text. The text has a fixed width, and the title is centered horizontally.";
|
||||
|
||||
println!("Blaaah");
|
||||
|
||||
siv.add_layer(
|
||||
Dialog::new(
|
||||
LinearLayout::new(Orientation::Vertical)
|
||||
.child(TextView::new("Title").h_align(HAlign::Center))
|
||||
.child(BoxView::new((30,0), TextView::new(text))))
|
||||
.button("Quit", |s| s.quit())
|
||||
.h_align(HAlign::Center));
|
||||
|
||||
siv.run();
|
||||
}
|
@ -29,6 +29,7 @@ pub mod printer;
|
||||
pub mod vec;
|
||||
pub mod theme;
|
||||
pub mod align;
|
||||
pub mod orientation;
|
||||
|
||||
mod div;
|
||||
mod utf8;
|
||||
|
36
src/orientation.rs
Normal file
36
src/orientation.rs
Normal file
@ -0,0 +1,36 @@
|
||||
use vec::Vec2;
|
||||
|
||||
pub enum Orientation {
|
||||
Horizontal,
|
||||
Vertical,
|
||||
}
|
||||
|
||||
impl Orientation {
|
||||
pub fn get(&self, v: &Vec2) -> usize {
|
||||
match *self {
|
||||
Orientation::Horizontal => v.x,
|
||||
Orientation::Vertical => v.y,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn swap(&self) -> Self {
|
||||
match *self {
|
||||
Orientation::Horizontal => Orientation::Vertical,
|
||||
Orientation::Vertical => Orientation::Horizontal,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_ref<'a,'b>(&'a self, v: &'b mut Vec2) -> &'b mut usize {
|
||||
match *self {
|
||||
Orientation::Horizontal => &mut v.x,
|
||||
Orientation::Vertical => &mut v.y,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stack<'a,T: Iterator<Item=&'a Vec2>>(&self, iter: T) -> Vec2 {
|
||||
match *self {
|
||||
Orientation::Horizontal => iter.fold(Vec2::zero(), |a,b| a.stack_horizontal(&b)),
|
||||
Orientation::Vertical => iter.fold(Vec2::zero(), |a,b| a.stack_vertical(&b)),
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ use std::ops::{Add, Sub, Mul, Div};
|
||||
use std::cmp::{min,max,Ordering};
|
||||
|
||||
/// Simple 2D size, in characters.
|
||||
#[derive(Clone,Copy,PartialEq)]
|
||||
#[derive(Clone,Copy,PartialEq,Debug)]
|
||||
pub struct Vec2 {
|
||||
/// X coordinate (column), from left to right.
|
||||
pub x: usize,
|
||||
|
@ -1,5 +1,5 @@
|
||||
use vec::{Vec2,ToVec2};
|
||||
use super::{View,ViewWrapper,SizeRequest};
|
||||
use super::{View,ViewWrapper,SizeRequest,DimensionRequest};
|
||||
|
||||
/// BoxView is a wrapper around an other view, with a given minimum size.
|
||||
pub struct BoxView<T: View> {
|
||||
@ -29,7 +29,15 @@ impl <T: View> ViewWrapper for BoxView<T> {
|
||||
|
||||
wrap_impl!(&self.view);
|
||||
|
||||
fn wrap_get_min_size(&self, _: SizeRequest) -> Vec2 {
|
||||
self.size
|
||||
fn wrap_get_min_size(&self, mut req: SizeRequest) -> Vec2 {
|
||||
if self.size.x > 0 { req.w = DimensionRequest::AtMost(self.size.x); }
|
||||
if self.size.y > 0 { req.h = DimensionRequest::AtMost(self.size.y); }
|
||||
|
||||
let mut size = self.view.get_min_size(req);
|
||||
|
||||
if self.size.x > 0 { size.x = self.size.x; }
|
||||
if self.size.y > 0 { size.y = self.size.y; }
|
||||
|
||||
size
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
use view::{View,SizeRequest,DimensionRequest};
|
||||
use vec::Vec2;
|
||||
use printer::Printer;
|
||||
use orientation::Orientation;
|
||||
|
||||
struct Child {
|
||||
view: Box<View>,
|
||||
@ -13,40 +14,6 @@ pub struct LinearLayout {
|
||||
orientation: Orientation,
|
||||
}
|
||||
|
||||
pub enum Orientation {
|
||||
Horizontal,
|
||||
Vertical,
|
||||
}
|
||||
|
||||
impl Orientation {
|
||||
fn get(&self, v: &Vec2) -> usize {
|
||||
match *self {
|
||||
Orientation::Horizontal => v.x,
|
||||
Orientation::Vertical => v.y,
|
||||
}
|
||||
}
|
||||
|
||||
fn swap(&self) -> Self {
|
||||
match *self {
|
||||
Orientation::Horizontal => Orientation::Vertical,
|
||||
Orientation::Vertical => Orientation::Horizontal,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_ref<'a,'b>(&'a self, v: &'b mut Vec2) -> &'b mut usize {
|
||||
match *self {
|
||||
Orientation::Horizontal => &mut v.x,
|
||||
Orientation::Vertical => &mut v.y,
|
||||
}
|
||||
}
|
||||
|
||||
fn stack<'a,T: Iterator<Item=&'a Vec2>>(&self, iter: T) -> Vec2 {
|
||||
match *self {
|
||||
Orientation::Horizontal => iter.fold(Vec2::zero(), |a,b| a.stack_horizontal(&b)),
|
||||
Orientation::Vertical => iter.fold(Vec2::zero(), |a,b| a.stack_vertical(&b)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LinearLayout {
|
||||
pub fn new(orientation: Orientation) -> Self {
|
||||
@ -126,6 +93,7 @@ impl View for LinearLayout {
|
||||
// Use pre-computed sizes
|
||||
let mut offset = Vec2::zero();
|
||||
for child in self.children.iter_mut() {
|
||||
println!("Drawing at {:?} for {:?}", offset, child.size);
|
||||
child.view.draw(&printer.sub_printer(offset, child.size, true));
|
||||
|
||||
*self.orientation.get_ref(&mut offset) += self.orientation.get(&child.size);
|
||||
@ -133,6 +101,7 @@ impl View for LinearLayout {
|
||||
}
|
||||
|
||||
fn layout(&mut self, size: Vec2) {
|
||||
println!("LAYOUT!!");
|
||||
// Compute the very minimal required size
|
||||
let req = SizeRequest{
|
||||
w: DimensionRequest::AtMost(size.x),
|
||||
@ -145,6 +114,7 @@ impl View for LinearLayout {
|
||||
// (default comparison on Vec2 is strict)
|
||||
if !(min_size < size+(1,1)) {
|
||||
// Error! Not enough space! Emergency procedures!
|
||||
println!("Min: {:?}, size: {:?}", min_size, size);
|
||||
return
|
||||
}
|
||||
|
||||
@ -156,7 +126,10 @@ impl View for LinearLayout {
|
||||
share(space, self.children.iter().map(|child| child.weight).collect())
|
||||
};
|
||||
|
||||
println!("Sizes: {}, {}, {}", self.children.len(), min_sizes.len(), extras.len());
|
||||
|
||||
for (child,(child_size,extra)) in self.children.iter_mut().zip(min_sizes.iter().zip(extras.iter())) {
|
||||
println!("Child size: {:?}", child_size);
|
||||
let mut child_size = *child_size;
|
||||
*self.orientation.get_ref(&mut child_size) += *extra;
|
||||
*self.orientation.swap().get_ref(&mut child_size) = self.orientation.swap().get(&size);
|
||||
@ -168,6 +141,7 @@ impl View for LinearLayout {
|
||||
fn get_min_size(&self, req: SizeRequest) -> Vec2 {
|
||||
// First, make a naive scenario: everything will work fine.
|
||||
let sizes: Vec<Vec2> = self.children.iter().map(|view| view.view.get_min_size(req)).collect();
|
||||
println!("Views size: {:?}", sizes);
|
||||
self.orientation.stack(sizes.iter())
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user