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]]
|
[[example]]
|
||||||
name = "theme"
|
name = "theme"
|
||||||
path = "examples/theme.rs"
|
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 vec;
|
||||||
pub mod theme;
|
pub mod theme;
|
||||||
pub mod align;
|
pub mod align;
|
||||||
|
pub mod orientation;
|
||||||
|
|
||||||
mod div;
|
mod div;
|
||||||
mod utf8;
|
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};
|
use std::cmp::{min,max,Ordering};
|
||||||
|
|
||||||
/// Simple 2D size, in characters.
|
/// Simple 2D size, in characters.
|
||||||
#[derive(Clone,Copy,PartialEq)]
|
#[derive(Clone,Copy,PartialEq,Debug)]
|
||||||
pub struct Vec2 {
|
pub struct Vec2 {
|
||||||
/// X coordinate (column), from left to right.
|
/// X coordinate (column), from left to right.
|
||||||
pub x: usize,
|
pub x: usize,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use vec::{Vec2,ToVec2};
|
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.
|
/// BoxView is a wrapper around an other view, with a given minimum size.
|
||||||
pub struct BoxView<T: View> {
|
pub struct BoxView<T: View> {
|
||||||
@ -29,7 +29,15 @@ impl <T: View> ViewWrapper for BoxView<T> {
|
|||||||
|
|
||||||
wrap_impl!(&self.view);
|
wrap_impl!(&self.view);
|
||||||
|
|
||||||
fn wrap_get_min_size(&self, _: SizeRequest) -> Vec2 {
|
fn wrap_get_min_size(&self, mut req: SizeRequest) -> Vec2 {
|
||||||
self.size
|
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 view::{View,SizeRequest,DimensionRequest};
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
use printer::Printer;
|
use printer::Printer;
|
||||||
|
use orientation::Orientation;
|
||||||
|
|
||||||
struct Child {
|
struct Child {
|
||||||
view: Box<View>,
|
view: Box<View>,
|
||||||
@ -13,40 +14,6 @@ pub struct LinearLayout {
|
|||||||
orientation: Orientation,
|
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 {
|
impl LinearLayout {
|
||||||
pub fn new(orientation: Orientation) -> Self {
|
pub fn new(orientation: Orientation) -> Self {
|
||||||
@ -126,6 +93,7 @@ impl View for LinearLayout {
|
|||||||
// Use pre-computed sizes
|
// Use pre-computed sizes
|
||||||
let mut offset = Vec2::zero();
|
let mut offset = Vec2::zero();
|
||||||
for child in self.children.iter_mut() {
|
for child in self.children.iter_mut() {
|
||||||
|
println!("Drawing at {:?} for {:?}", offset, child.size);
|
||||||
child.view.draw(&printer.sub_printer(offset, child.size, true));
|
child.view.draw(&printer.sub_printer(offset, child.size, true));
|
||||||
|
|
||||||
*self.orientation.get_ref(&mut offset) += self.orientation.get(&child.size);
|
*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) {
|
fn layout(&mut self, size: Vec2) {
|
||||||
|
println!("LAYOUT!!");
|
||||||
// Compute the very minimal required size
|
// Compute the very minimal required size
|
||||||
let req = SizeRequest{
|
let req = SizeRequest{
|
||||||
w: DimensionRequest::AtMost(size.x),
|
w: DimensionRequest::AtMost(size.x),
|
||||||
@ -145,6 +114,7 @@ impl View for LinearLayout {
|
|||||||
// (default comparison on Vec2 is strict)
|
// (default comparison on Vec2 is strict)
|
||||||
if !(min_size < size+(1,1)) {
|
if !(min_size < size+(1,1)) {
|
||||||
// Error! Not enough space! Emergency procedures!
|
// Error! Not enough space! Emergency procedures!
|
||||||
|
println!("Min: {:?}, size: {:?}", min_size, size);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +126,10 @@ impl View for LinearLayout {
|
|||||||
share(space, self.children.iter().map(|child| child.weight).collect())
|
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())) {
|
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;
|
let mut child_size = *child_size;
|
||||||
*self.orientation.get_ref(&mut child_size) += *extra;
|
*self.orientation.get_ref(&mut child_size) += *extra;
|
||||||
*self.orientation.swap().get_ref(&mut child_size) = self.orientation.swap().get(&size);
|
*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 {
|
fn get_min_size(&self, req: SizeRequest) -> Vec2 {
|
||||||
// First, make a naive scenario: everything will work fine.
|
// 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();
|
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())
|
self.orientation.stack(sizes.iter())
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user