Add align support to SelectView

And moved some alignment offset computation to the align module.
This commit is contained in:
Alexandre Bury 2015-06-02 14:23:51 -07:00
parent ef84df3b09
commit 0b159d6bf1
4 changed files with 54 additions and 14 deletions

View File

@ -4,13 +4,14 @@ use std::fs::File;
use std::io::{BufReader,BufRead}; use std::io::{BufReader,BufRead};
use cursive::Cursive; use cursive::Cursive;
use cursive::align::HAlign;
use cursive::view::{Dialog,SelectView,TextView,BoxView}; use cursive::view::{Dialog,SelectView,TextView,BoxView};
fn main() { fn main() {
// To keep things simple, little error management is done here. // To keep things simple, little error management is done here.
// If you have an error, be sure to run this from the crate root, not from a sub directory. // If you have an error, be sure to run this from the crate root, not from a sub directory.
let mut select = SelectView::new(); let mut select = SelectView::new().h_align(HAlign::Center);
// Read the list of cities from separate file, and fill the view with it. // Read the list of cities from separate file, and fill the view with it.
let file = File::open("assets/cities.txt").unwrap(); let file = File::open("assets/cities.txt").unwrap();

View File

@ -33,3 +33,23 @@ pub enum VAlign {
Center, Center,
Bottom, Bottom,
} }
impl HAlign {
pub fn get_offset(&self, content: usize, container: usize) -> usize {
match *self {
HAlign::Left => 0,
HAlign::Center => (container - content)/2,
HAlign::Right => (container - content),
}
}
}
impl VAlign {
pub fn get_offset(&self, content: usize, container: usize) -> usize {
match *self {
VAlign::Top => 0,
VAlign::Center => (container - content)/2,
VAlign::Bottom => (container - content),
}
}
}

View File

@ -3,6 +3,7 @@ use std::rc::Rc;
use color; use color;
use ::Cursive; use ::Cursive;
use align::*;
use view::{View,IdView,SizeRequest,DimensionRequest}; use view::{View,IdView,SizeRequest,DimensionRequest};
use event::{Event,EventResult,Key}; use event::{Event,EventResult,Key};
use vec::Vec2; use vec::Vec2;
@ -31,6 +32,7 @@ pub struct SelectView<T=String> {
focus: usize, focus: usize,
scrollbase: ScrollBase, scrollbase: ScrollBase,
select_cb: Option<Rc<Box<Fn(&mut Cursive,&T)>>>, select_cb: Option<Rc<Box<Fn(&mut Cursive,&T)>>>,
align: Align,
} }
impl <T: 'static> SelectView<T> { impl <T: 'static> SelectView<T> {
@ -41,6 +43,7 @@ impl <T: 'static> SelectView<T> {
focus: 0, focus: 0,
scrollbase: ScrollBase::new(), scrollbase: ScrollBase::new(),
select_cb: None, select_cb: None,
align: Align::top_left(),
} }
} }
@ -53,6 +56,24 @@ impl <T: 'static> SelectView<T> {
self self
} }
pub fn align(mut self, align: Align) -> Self {
self.align = align;
self
}
pub fn v_align(mut self, v: VAlign) -> Self {
self.align.v = v;
self
}
pub fn h_align(mut self, h: HAlign) -> Self {
self.align.h = h;
self
}
/// Returns the value of the currently selected item. Panics if the list is empty. /// Returns the value of the currently selected item. Panics if the list is empty.
pub fn selection(&self) -> Rc<T> { pub fn selection(&self) -> Rc<T> {
self.items[self.focus].value.clone() self.items[self.focus].value.clone()
@ -92,6 +113,10 @@ impl SelectView<String> {
impl <T: 'static> View for SelectView<T> { impl <T: 'static> View for SelectView<T> {
fn draw(&mut self, printer: &Printer) { fn draw(&mut self, printer: &Printer) {
let h = self.items.len();
let offset = self.align.v.get_offset(h, printer.size.y);
let printer = &printer.sub_printer(Vec2::new(0,offset), printer.size, true);
self.scrollbase.draw(printer, |printer,i| { self.scrollbase.draw(printer, |printer,i| {
let style = if i == self.focus { let style = if i == self.focus {
if printer.focused { color::HIGHLIGHT } if printer.focused { color::HIGHLIGHT }
@ -100,9 +125,11 @@ impl <T: 'static> View for SelectView<T> {
color::PRIMARY color::PRIMARY
}; };
printer.with_color(style, |printer| { printer.with_color(style, |printer| {
printer.print((0,0), &self.items[i].label); let l = self.items[i].label.chars().count();
let x:usize = self.items[i].label.chars().count(); let x = self.align.h.get_offset(l, printer.size.x);
printer.print_hline((x,0), printer.size.x-x, ' ' as u64); printer.print_hline((0,0), x, ' ' as u64);
printer.print((x,0), &self.items[i].label);
printer.print_hline((x+l,0), printer.size.x-l-x, ' ' as u64);
}); });
}); });
} }

View File

@ -206,22 +206,14 @@ impl View for TextView {
fn draw(&mut self, printer: &Printer) { fn draw(&mut self, printer: &Printer) {
let h = self.rows.len(); let h = self.rows.len();
let offset = match self.align.v { let offset = self.align.v.get_offset(h, printer.size.y);
VAlign::Top => 0,
VAlign::Center => (printer.size.y - h)/2,
VAlign::Bottom => printer.size.y - h,
};
let printer = &printer.sub_printer(Vec2::new(0,offset), printer.size, true); let printer = &printer.sub_printer(Vec2::new(0,offset), printer.size, true);
self.scrollbase.draw(printer, |printer, i| { self.scrollbase.draw(printer, |printer, i| {
let row = &self.rows[i]; let row = &self.rows[i];
let text = &self.content[row.start..row.end]; let text = &self.content[row.start..row.end];
let l = text.chars().count(); let l = text.chars().count();
let x = match self.align.h { let x = self.align.h.get_offset(l, printer.size.x);
HAlign::Left => 0,
HAlign::Center => (printer.size.x-l)/2,
HAlign::Right => printer.size.x-l,
};
printer.print((x,0), text); printer.print((x,0), text);
}); });
} }