Fixed bug with dialog without buttons

This commit is contained in:
Alexandre Bury 2015-07-28 21:54:32 +02:00
parent 36fbc1ce5b
commit ac85a1f288
4 changed files with 37 additions and 14 deletions

View File

@ -19,18 +19,19 @@ fn main() {
for line in reader.lines() { for line in reader.lines() {
select.add_item_str(&line.unwrap()); select.add_item_str(&line.unwrap());
} }
select.set_on_select(show_next_window);
let mut siv = Cursive::new(); let mut siv = Cursive::new();
// Let's add a BoxView to keep the list at a reasonable size - it can scroll anyway. // Let's add a BoxView to keep the list at a reasonable size - it can scroll anyway.
siv.add_layer(Dialog::new(BoxView::new((20,10), select.on_select(|s,city| show_next_window(s,city)))) siv.add_layer(Dialog::new(BoxView::new((20,10), select))
.title("Where are you from?")); .title("Where are you from?"));
siv.run(); siv.run();
} }
// Let's put the callback in a separate function to keep it clean, but it's not required. // Let's put the callback in a separate function to keep it clean, but it's not required.
fn show_next_window(siv: &mut Cursive, city: &str) { fn show_next_window(siv: &mut Cursive, city: &String) {
siv.pop_layer(); siv.pop_layer();
siv.add_layer(Dialog::new(TextView::new(&format!("{} is a great city!", city))) siv.add_layer(Dialog::new(TextView::new(&format!("{} is a great city!", city)))
.button("Quit", |s| s.quit())); .button("Quit", |s| s.quit()));

View File

@ -108,14 +108,22 @@ impl View for Dialog {
// Current horizontal position of the next button we'll draw. // Current horizontal position of the next button we'll draw.
// Sum of the sizes + len-1 for margins // Sum of the sizes + len-1 for margins
let width = self.buttons.iter().map(|button| button.size.x).fold(0, |a,b| a+b) + self.buttons.len() - 1; let width = if self.buttons.is_empty() {
0
} else {
self.buttons.iter()
.map(|button| button.size.x)
.fold(0, |a,b| a+b) +
self.buttons.len() - 1
};
let overhead = self.padding + self.borders; let overhead = self.padding + self.borders;
let mut offset = overhead.left + self.align.h.get_offset(width, printer.size.x - overhead.horizontal()); let mut offset = overhead.left +
self.align.h.get_offset(width, printer.size.x -
overhead.horizontal());
let y = printer.size.y - self.padding.bottom - self.borders.bottom - 1; let y = printer.size.y - self.padding.bottom - self.borders.bottom - 1;
for (i,button) in self.buttons.iter_mut().enumerate() { for (i,button) in self.buttons.iter_mut().enumerate() {
let size = button.size; let size = button.size;
// let offset = printer.size - self.borders.bot_right() - self.padding.bot_right() - size - Vec2::new(x, 0);
// Add some special effect to the focused button // Add some special effect to the focused button
button.draw(&printer.sub_printer(Vec2::new(offset, y), size, self.focus == Focus::Button(i))); button.draw(&printer.sub_printer(Vec2::new(offset, y), size, self.focus == Focus::Button(i)));
// Keep 1 blank between two buttons // Keep 1 blank between two buttons
@ -130,7 +138,10 @@ impl View for Dialog {
- self.borders.combined() - self.borders.combined()
- self.padding.combined(); - self.padding.combined();
self.content.draw(&printer.sub_printer(self.borders.top_left() + self.padding.top_left(), inner_size, self.focus == Focus::Content)); self.content.draw(&printer.sub_printer(self.borders.top_left() +
self.padding.top_left(),
inner_size,
self.focus == Focus::Content));
printer.print_box(Vec2::new(0,0), printer.size); printer.print_box(Vec2::new(0,0), printer.size);
@ -140,18 +151,22 @@ impl View for Dialog {
printer.print((x-2,0), ""); printer.print((x-2,0), "");
printer.print((x+len,0), ""); printer.print((x+len,0), "");
printer.with_color(ColorPair::TitlePrimary, |p| p.print((x,0), &self.title)); printer.with_color(ColorPair::TitlePrimary,
|p| p.print((x,0), &self.title));
} }
} }
fn get_min_size(&self, req: SizeRequest) -> Vec2 { fn get_min_size(&self, req: SizeRequest) -> Vec2 {
// Padding and borders are not available for kids. // Padding and borders are not available for kids.
let content_req = req.reduced(self.padding.combined() + self.borders.combined()); let content_req = req.reduced(self.padding.combined() +
self.borders.combined());
let content_size = self.content.get_min_size(content_req); let content_size = self.content.get_min_size(content_req);
let mut buttons_size = Vec2::new(0,0); let mut buttons_size = Vec2::new(0,0);
if !self.buttons.is_empty() { buttons_size.x += self.buttons.len() - 1; } if !self.buttons.is_empty() {
buttons_size.x += self.buttons.len() - 1;
}
for button in self.buttons.iter() { for button in self.buttons.iter() {
let s = button.view.get_min_size(req); let s = button.view.get_min_size(req);
buttons_size.x += s.x; buttons_size.x += s.x;

View File

@ -47,11 +47,17 @@ impl <T: 'static> SelectView<T> {
} }
} }
pub fn set_on_select<F>(&mut self, cb: F)
where F: Fn(&mut Cursive, &T) + 'static
{
self.select_cb = Some(Rc::new(Box::new(cb)));
}
/// Sets a function to be called when an item is selected (when ENTER is pressed). /// Sets a function to be called when an item is selected (when ENTER is pressed).
pub fn on_select<F>(mut self, cb: F) -> Self pub fn on_select<F>(mut self, cb: F) -> Self
where F: Fn(&mut Cursive, &T) + 'static where F: Fn(&mut Cursive, &T) + 'static
{ {
self.select_cb = Some(Rc::new(Box::new(cb))); self.set_on_select(cb);
self self
} }

View File

@ -40,8 +40,9 @@ impl <T: View> ViewWrapper for ShadowView<T> {
} }
}); });
self.view.draw(&printer.sub_printer(Vec2::new(1,1), printer.size - (2,2), true)); self.view.draw(&printer.sub_printer(Vec2::new(1,1),
printer.size - (2,2),
true));
let h = printer.size.y-1; let h = printer.size.y-1;
let w = printer.size.x-1; let w = printer.size.x-1;