mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-27 11:16:03 +00:00
Update documentation
This commit is contained in:
parent
daaff26e1c
commit
df11b4f1f0
@ -3,20 +3,20 @@ extern crate cursive;
|
|||||||
use cursive::Cursive;
|
use cursive::Cursive;
|
||||||
use cursive::view::{Dialog,TextView,LinearLayout,BoxView};
|
use cursive::view::{Dialog,TextView,LinearLayout,BoxView};
|
||||||
use cursive::align::HAlign;
|
use cursive::align::HAlign;
|
||||||
use cursive::orientation::Orientation;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut siv = Cursive::new();
|
let mut siv = Cursive::new();
|
||||||
|
|
||||||
// Some longish content
|
// Some description text
|
||||||
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.";
|
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");
|
// We'll create a dialog with a TextView serving as a title
|
||||||
|
|
||||||
siv.add_layer(
|
siv.add_layer(
|
||||||
Dialog::new(
|
Dialog::new(
|
||||||
LinearLayout::new(Orientation::Vertical)
|
LinearLayout::vertical()
|
||||||
.child(TextView::new("Title").h_align(HAlign::Center))
|
.child(TextView::new("Title").h_align(HAlign::Center))
|
||||||
|
// Box the textview, so it doesn't get too wide.
|
||||||
|
// A 0 height value means it will be unconstrained.
|
||||||
.child(BoxView::new((30,0), TextView::new(text))))
|
.child(BoxView::new((30,0), TextView::new(text))))
|
||||||
.button("Quit", |s| s.quit())
|
.button("Quit", |s| s.quit())
|
||||||
.h_align(HAlign::Center));
|
.h_align(HAlign::Center));
|
||||||
|
@ -20,6 +20,7 @@ pub enum EventResult {
|
|||||||
Consumed(Option<Rc<Callback>>),
|
Consumed(Option<Rc<Callback>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents a key, or a combination of keys.
|
||||||
#[derive(PartialEq,Eq,Clone,Copy,Hash)]
|
#[derive(PartialEq,Eq,Clone,Copy,Hash)]
|
||||||
pub enum Key {
|
pub enum Key {
|
||||||
/// Both Enter and numpad Enter
|
/// Both Enter and numpad Enter
|
||||||
@ -200,9 +201,13 @@ impl fmt::Display for Key {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents an event as seen by the application.
|
||||||
|
///
|
||||||
#[derive(PartialEq,Eq,Clone,Copy,Hash)]
|
#[derive(PartialEq,Eq,Clone,Copy,Hash)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
|
/// A text character was entered.
|
||||||
CharEvent(char),
|
CharEvent(char),
|
||||||
|
/// A key was pressed.
|
||||||
KeyEvent(Key),
|
KeyEvent(Key),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
|
//! Define an Orientation and associated methods.
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
|
|
||||||
|
/// Describes a vertical or horizontal orientation for a view.
|
||||||
#[derive(Clone,Copy,PartialEq)]
|
#[derive(Clone,Copy,PartialEq)]
|
||||||
pub enum Orientation {
|
pub enum Orientation {
|
||||||
|
/// Horizontal orientation
|
||||||
Horizontal,
|
Horizontal,
|
||||||
|
/// Vertical orientation
|
||||||
Vertical,
|
Vertical,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Orientation {
|
impl Orientation {
|
||||||
|
/// Returns the component of the given vector corresponding to this orientation.
|
||||||
|
/// (Horizontal will return the x value, and Vertical will return the y value.)
|
||||||
pub fn get(&self, v: &Vec2) -> usize {
|
pub fn get(&self, v: &Vec2) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
Orientation::Horizontal => v.x,
|
Orientation::Horizontal => v.x,
|
||||||
@ -14,6 +20,7 @@ impl Orientation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the other orientation.
|
||||||
pub fn swap(&self) -> Self {
|
pub fn swap(&self) -> Self {
|
||||||
match *self {
|
match *self {
|
||||||
Orientation::Horizontal => Orientation::Vertical,
|
Orientation::Horizontal => Orientation::Vertical,
|
||||||
@ -21,6 +28,8 @@ impl Orientation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a mutable reference to the component of the given vector
|
||||||
|
/// corresponding to this orientation.
|
||||||
pub fn get_ref<'a,'b>(&'a self, v: &'b mut Vec2) -> &'b mut usize {
|
pub fn get_ref<'a,'b>(&'a self, v: &'b mut Vec2) -> &'b mut usize {
|
||||||
match *self {
|
match *self {
|
||||||
Orientation::Horizontal => &mut v.x,
|
Orientation::Horizontal => &mut v.x,
|
||||||
@ -28,6 +37,11 @@ impl Orientation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Takes an iterator on sizes, and stack them in the current orientation,
|
||||||
|
/// returning the size of the required bounding box.
|
||||||
|
///
|
||||||
|
/// For an horizontal view, returns (Sum(x), Max(y)).
|
||||||
|
/// For a vertical view, returns (Max(x),Sum(y)).
|
||||||
pub fn stack<'a,T: Iterator<Item=&'a Vec2>>(&self, iter: T) -> Vec2 {
|
pub fn stack<'a,T: Iterator<Item=&'a Vec2>>(&self, iter: T) -> Vec2 {
|
||||||
match *self {
|
match *self {
|
||||||
Orientation::Horizontal => iter.fold(Vec2::zero(), |a,b| a.stack_horizontal(&b)),
|
Orientation::Horizontal => iter.fold(Vec2::zero(), |a,b| a.stack_horizontal(&b)),
|
||||||
|
@ -4,20 +4,21 @@ use printer::Printer;
|
|||||||
use orientation::Orientation;
|
use orientation::Orientation;
|
||||||
use event::{Event,EventResult,Key};
|
use event::{Event,EventResult,Key};
|
||||||
|
|
||||||
|
/// Arranges its children linearly according to its orientation.
|
||||||
|
pub struct LinearLayout {
|
||||||
|
children: Vec<Child>,
|
||||||
|
orientation: Orientation,
|
||||||
|
focus: usize,
|
||||||
|
}
|
||||||
|
|
||||||
struct Child {
|
struct Child {
|
||||||
view: Box<View>,
|
view: Box<View>,
|
||||||
size: Vec2,
|
size: Vec2,
|
||||||
weight: usize,
|
weight: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LinearLayout {
|
|
||||||
children: Vec<Child>,
|
|
||||||
orientation: Orientation,
|
|
||||||
focus: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl LinearLayout {
|
impl LinearLayout {
|
||||||
|
/// Creates a new layout with the given orientation.
|
||||||
pub fn new(orientation: Orientation) -> Self {
|
pub fn new(orientation: Orientation) -> Self {
|
||||||
LinearLayout {
|
LinearLayout {
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
@ -26,12 +27,16 @@ impl LinearLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Modifies the weight of the last child added.
|
||||||
|
///
|
||||||
|
/// It is an error to call this before adding a child (and it will panic).
|
||||||
pub fn weight(mut self, weight: usize) -> Self {
|
pub fn weight(mut self, weight: usize) -> Self {
|
||||||
self.children.last_mut().unwrap().weight = weight;
|
self.children.last_mut().unwrap().weight = weight;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds a child to the layout.
|
||||||
pub fn child<V: View + 'static>(mut self, view: V) -> Self {
|
pub fn child<V: View + 'static>(mut self, view: V) -> Self {
|
||||||
self.children.push(Child {
|
self.children.push(Child {
|
||||||
view: Box::new(view),
|
view: Box::new(view),
|
||||||
@ -42,14 +47,19 @@ impl LinearLayout {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new vertical layout.
|
||||||
pub fn vertical() -> Self {
|
pub fn vertical() -> Self {
|
||||||
LinearLayout::new(Orientation::Vertical)
|
LinearLayout::new(Orientation::Vertical)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new horizontal layout.
|
||||||
pub fn horizontal() -> Self {
|
pub fn horizontal() -> Self {
|
||||||
LinearLayout::new(Orientation::Horizontal)
|
LinearLayout::new(Orientation::Horizontal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the index of the maximum element.
|
||||||
|
/// WTF isn't it part of standard library??
|
||||||
fn find_max(list: &Vec<usize>) -> usize {
|
fn find_max(list: &Vec<usize>) -> usize {
|
||||||
let mut max_value = 0;
|
let mut max_value = 0;
|
||||||
let mut max = 0;
|
let mut max = 0;
|
||||||
@ -62,7 +72,12 @@ fn find_max(list: &Vec<usize>) -> usize {
|
|||||||
max
|
max
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Given a total number of points and a list of weights,
|
||||||
|
/// try to share the points according to the weight,
|
||||||
|
/// rounding properly and conserving the sum of points.
|
||||||
fn share(total: usize, weights: Vec<usize>) -> Vec<usize> {
|
fn share(total: usize, weights: Vec<usize>) -> Vec<usize> {
|
||||||
|
// It first give a base value to everyone, which is their truncated share.
|
||||||
|
// Then, it gives the rest to the most deserving.
|
||||||
if weights.len() == 0 { return Vec::new(); }
|
if weights.len() == 0 { return Vec::new(); }
|
||||||
|
|
||||||
let sum_weight = weights.iter().fold(0,|a,b| a+b);
|
let sum_weight = weights.iter().fold(0,|a,b| a+b);
|
||||||
@ -96,7 +111,6 @@ 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);
|
||||||
@ -104,7 +118,6 @@ 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),
|
||||||
@ -117,7 +130,6 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,10 +141,8 @@ 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);
|
||||||
@ -144,7 +154,6 @@ 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())
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,7 +71,9 @@ pub trait View {
|
|||||||
|
|
||||||
/// Selects a single view (if any) in the tree.
|
/// Selects a single view (if any) in the tree.
|
||||||
pub enum Selector<'a> {
|
pub enum Selector<'a> {
|
||||||
|
/// Selects a view from its ID
|
||||||
Id(&'a str),
|
Id(&'a str),
|
||||||
|
/// Selects a view from its path
|
||||||
Path(&'a ViewPath),
|
Path(&'a ViewPath),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user