From 193f098ee025ab5abf23c2d767f33778db7c66c0 Mon Sep 17 00:00:00 2001 From: Alexandre Bury Date: Fri, 9 Nov 2018 14:08:43 -0800 Subject: [PATCH] Add Printer::enabled --- examples/mines/game.rs | 2 +- examples/mines/main.rs | 22 +++++++++++------- src/printer.rs | 48 +++++++++++++++++++++------------------- src/views/button.rs | 9 +++----- src/views/checkbox.rs | 8 ++----- src/views/edit_view.rs | 22 +++++++++--------- src/views/radio.rs | 6 ++--- src/views/select_view.rs | 27 +++++++++++----------- src/views/text_area.rs | 27 +++++++++------------- 9 files changed, 83 insertions(+), 88 deletions(-) diff --git a/examples/mines/game.rs b/examples/mines/game.rs index 072c012..472d142 100644 --- a/examples/mines/game.rs +++ b/examples/mines/game.rs @@ -1,6 +1,6 @@ use cursive::vec::Vec2; use rand::{thread_rng, Rng}; -use std::cmp::max; +// use std::cmp::max; #[derive(Clone, Copy)] pub struct Options { diff --git a/examples/mines/main.rs b/examples/mines/main.rs index 148d71f..4cf4235 100644 --- a/examples/mines/main.rs +++ b/examples/mines/main.rs @@ -23,7 +23,8 @@ fn main() { .child(Button::new_raw(" New game ", show_options)) .child(Button::new_raw(" Best scores ", |s| { s.add_layer(Dialog::info("Not yet!").title("Scores")) - })).child(Button::new_raw(" Exit ", |s| s.quit())), + })) + .child(Button::new_raw(" Exit ", |s| s.quit())), ), ); @@ -42,23 +43,27 @@ fn show_options(siv: &mut Cursive) { size: Vec2::new(8, 8), mines: 10, }, - ).item( + ) + .item( "Medium: 16x16, 40 mines", game::Options { size: Vec2::new(16, 16), mines: 40, }, - ).item( + ) + .item( "Difficult: 24x24, 99 mines", game::Options { size: Vec2::new(24, 24), mines: 99, }, - ).on_submit(|s, option| { + ) + .on_submit(|s, option| { s.pop_layer(); new_game(s, *option); }), - ).dismiss_button("Back"), + ) + .dismiss_button("Back"), ); } @@ -77,7 +82,7 @@ struct BoardView { overlay: Vec, focused: Option, - missing_mines: usize, + _missing_mines: usize, } impl BoardView { @@ -88,7 +93,7 @@ impl BoardView { board, overlay, focused: None, - missing_mines: options.mines, + _missing_mines: options.mines, } } @@ -271,7 +276,8 @@ fn new_game(siv: &mut Cursive, options: game::Options) { .content( LinearLayout::horizontal() .child(Panel::new(BoardView::new(options))), - ).button("Quit game", |s| { + ) + .button("Quit game", |s| { s.pop_layer(); }), ); diff --git a/src/printer.rs b/src/printer.rs index 1d7ed5c..03022ac 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -17,6 +17,7 @@ use with::With; /// /// The part of the content it will print is defined by `content_offset` /// and `size`. +#[derive(Clone)] pub struct Printer<'a, 'b> { /// Offset into the window this printer should start drawing at. /// @@ -42,6 +43,9 @@ pub struct Printer<'a, 'b> { /// Whether the view to draw is currently focused or not. pub focused: bool, + /// Whether the view to draw is currently enabled or not. + pub enabled: bool, + /// Currently used theme pub theme: &'a Theme, @@ -49,20 +53,6 @@ pub struct Printer<'a, 'b> { backend: &'b Backend, } -impl<'a, 'b> Clone for Printer<'a, 'b> { - fn clone(&self) -> Self { - Printer { - offset: self.offset, - content_offset: self.content_offset, - output_size: self.output_size, - size: self.size, - focused: self.focused, - theme: self.theme, - backend: self.backend, - } - } -} - impl<'a, 'b> Printer<'a, 'b> { /// Creates a new printer on the given window. /// @@ -78,6 +68,7 @@ impl<'a, 'b> Printer<'a, 'b> { output_size: size, size, focused: true, + enabled: true, theme, backend, } @@ -304,16 +295,18 @@ impl<'a, 'b> Printer<'a, 'b> { where F: FnOnce(&Printer), { - let new_printer = Printer { - offset: self.offset, - size: self.size, - focused: self.focused, + f(&self.theme(theme)); + } + + /// Create a new sub-printer with the given theme. + pub fn theme<'c>(&self, theme: &'c Theme) -> Printer<'c, 'b> + where + 'a: 'c, + { + Printer { theme, - backend: self.backend, - output_size: self.output_size, - content_offset: self.content_offset, - }; - f(&new_printer); + ..self.clone() + } } /// Call the given closure with a modified printer @@ -480,6 +473,15 @@ impl<'a, 'b> Printer<'a, 'b> { }) } + /// Returns a new sub-printer inheriting the given enabled state. + /// + /// If `self` is enabled and `enabled == true`, the child will be enabled. + /// + /// Otherwise, he will be disabled. + pub fn enabled(&self, enabled: bool) -> Self { + self.clone().with(|s| s.enabled &= enabled) + } + /// Returns a new sub-printer with a cropped area. /// /// The new printer size will be the minimum of `size` and its current size. diff --git a/src/views/button.rs b/src/views/button.rs index 8dfec22..4e54d85 100644 --- a/src/views/button.rs +++ b/src/views/button.rs @@ -142,7 +142,7 @@ impl View for Button { return; } - let style = if !self.enabled { + let style = if !(self.enabled && printer.enabled) { ColorStyle::secondary() } else if !printer.focused { ColorStyle::primary() @@ -182,11 +182,8 @@ impl View for Button { event: MouseEvent::Release(MouseButton::Left), position, offset, - } - if position.fits_in_rect( - offset + (self_offset, 0), - self.req_size(), - ) => + } if position + .fits_in_rect(offset + (self_offset, 0), self.req_size()) => { EventResult::Consumed(Some(self.callback.clone())) } diff --git a/src/views/checkbox.rs b/src/views/checkbox.rs index 224e14b..65d336a 100644 --- a/src/views/checkbox.rs +++ b/src/views/checkbox.rs @@ -114,7 +114,7 @@ impl View for Checkbox { } fn draw(&self, printer: &Printer) { - if self.enabled { + if self.enabled && printer.enabled { printer.with_selection(printer.focused, |printer| { self.draw_internal(printer) }); @@ -132,11 +132,7 @@ impl View for Checkbox { event: MouseEvent::Release(MouseButton::Left), position, offset, - } - if position.fits_in_rect(offset, (3, 1)) => - { - self.toggle() - } + } if position.fits_in_rect(offset, (3, 1)) => self.toggle(), _ => EventResult::Ignored, } } diff --git a/src/views/edit_view.rs b/src/views/edit_view.rs index 073aaf9..4725d00 100644 --- a/src/views/edit_view.rs +++ b/src/views/edit_view.rs @@ -471,7 +471,8 @@ impl EditView { let suffix_length = simple_suffix( &self.content[self.offset..self.cursor], available, - ).length; + ) + .length; assert!(suffix_length <= self.cursor); self.offset = self.cursor - suffix_length; @@ -510,7 +511,7 @@ impl View for EditView { let width = self.content.width(); printer.with_color(self.style, |printer| { - let effect = if self.enabled { + let effect = if self.enabled && printer.enabled { Effect::Reverse } else { Effect::Simple @@ -542,7 +543,8 @@ impl View for EditView { } else { Some(g) } - }).map(|g| g.len()) + }) + .map(|g| g.len()) .sum(); let content = &content[..display_bytes]; @@ -660,14 +662,14 @@ impl View for EditView { event: MouseEvent::Press(_), position, offset, - } - if position.fits_in_rect(offset, (self.last_length, 1)) => - { + } if position.fits_in_rect(offset, (self.last_length, 1)) => { if let Some(position) = position.checked_sub(offset) { - self.cursor = self.offset + simple_prefix( - &self.content[self.offset..], - position.x, - ).length; + self.cursor = self.offset + + simple_prefix( + &self.content[self.offset..], + position.x, + ) + .length; } } _ => return EventResult::Ignored, diff --git a/src/views/radio.rs b/src/views/radio.rs index 4979a7b..6e61078 100644 --- a/src/views/radio.rs +++ b/src/views/radio.rs @@ -163,7 +163,7 @@ impl View for RadioButton { } fn draw(&self, printer: &Printer) { - if self.enabled { + if self.enabled && printer.enabled { printer.with_selection(printer.focused, |printer| { self.draw_internal(printer) }); @@ -184,9 +184,7 @@ impl View for RadioButton { event: MouseEvent::Release(MouseButton::Left), position, offset, - } - if position.fits_in_rect(offset, self.req_size()) => - { + } if position.fits_in_rect(offset, self.req_size()) => { self.select(); EventResult::Consumed(None) } diff --git a/src/views/select_view.rs b/src/views/select_view.rs index 08a39f2..7a8e7d3 100644 --- a/src/views/select_view.rs +++ b/src/views/select_view.rs @@ -505,13 +505,12 @@ impl SelectView { event: MouseEvent::Press(_), position, offset, - } - if position - .checked_sub(offset) - .map(|position| { - position < self.last_size && position.y < self.len() - }) - .unwrap_or(false) => + } if position + .checked_sub(offset) + .map(|position| { + position < self.last_size && position.y < self.len() + }) + .unwrap_or(false) => { self.focus.set(position.y - offset.y) } @@ -519,8 +518,8 @@ impl SelectView { event: MouseEvent::Release(MouseButton::Left), position, offset, - } - if self.on_submit.is_some() && position + } if self.on_submit.is_some() + && position .checked_sub(offset) .map(|position| { position < self.last_size && position.y == self.focus() @@ -610,9 +609,7 @@ impl SelectView { event: MouseEvent::Release(MouseButton::Left), position, offset, - } - if position.fits_in_rect(offset, self.last_size) => - { + } if position.fits_in_rect(offset, self.last_size) => { self.open_popup() } _ => EventResult::Ignored, @@ -679,7 +676,7 @@ impl View for SelectView { if self.popup { // Popup-select only draw the active element. // We'll draw the full list in a popup if needed. - let style = if !self.enabled { + let style = if !(self.enabled && printer.enabled) { ColorStyle::secondary() } else if !printer.focused { ColorStyle::primary() @@ -715,7 +712,9 @@ impl View for SelectView { printer.offset((0, i)).with_selection( i == self.focus(), |printer| { - if i != self.focus() && !self.enabled { + if i != self.focus() + && !(self.enabled && printer.enabled) + { printer.with_color( ColorStyle::secondary(), |printer| self.draw_item(printer, i), diff --git a/src/views/text_area.rs b/src/views/text_area.rs index 30affcc..251fef8 100644 --- a/src/views/text_area.rs +++ b/src/views/text_area.rs @@ -461,7 +461,7 @@ impl View for TextArea { fn draw(&self, printer: &Printer) { printer.with_color(ColorStyle::secondary(), |printer| { - let effect = if self.enabled { + let effect = if self.enabled && printer.enabled { Effect::Reverse } else { Effect::Simple @@ -545,18 +545,14 @@ impl View for TextArea { Event::Mouse { event: MouseEvent::WheelUp, .. - } - if self.scrollbase.can_scroll_up() => - { + } if self.scrollbase.can_scroll_up() => { fix_scroll = false; self.scrollbase.scroll_up(5); } Event::Mouse { event: MouseEvent::WheelDown, .. - } - if self.scrollbase.can_scroll_down() => - { + } if self.scrollbase.can_scroll_down() => { fix_scroll = false; self.scrollbase.scroll_down(5); } @@ -564,12 +560,12 @@ impl View for TextArea { event: MouseEvent::Press(MouseButton::Left), position, offset, - } - if position - .checked_sub(offset) - .map(|position| { - self.scrollbase.start_drag(position, self.last_size.x) - }).unwrap_or(false) => + } if position + .checked_sub(offset) + .map(|position| { + self.scrollbase.start_drag(position, self.last_size.x) + }) + .unwrap_or(false) => { fix_scroll = false; } @@ -586,9 +582,8 @@ impl View for TextArea { event: MouseEvent::Press(_), position, offset, - } - if !self.rows.is_empty() - && position.fits_in_rect(offset, self.last_size) => + } if !self.rows.is_empty() + && position.fits_in_rect(offset, self.last_size) => { if let Some(position) = position.checked_sub(offset) { let y = position.y + self.scrollbase.start_line;