diff --git a/src/printer.rs b/src/printer.rs index a6f4478..347f42c 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -96,11 +96,12 @@ impl<'a> Printer<'a> { // We don't want people to start calling prints in parallel? /// Prints some text at the given position relative to the window. pub fn print>(&self, start: S, text: &str) { + // Where we are asked to start printing. Oh boy. let start = start.into(); // We accept requests between `content_offset` and - // `content_offset + size` - if start >= self.output_size + self.content_offset { + // `content_offset + output_size`. + if !(start < (self.output_size + self.content_offset)) { return; } diff --git a/src/views/button.rs b/src/views/button.rs index 5ff8b81..79db99b 100644 --- a/src/views/button.rs +++ b/src/views/button.rs @@ -4,6 +4,7 @@ use event::*; use theme::ColorStyle; use unicode_width::UnicodeWidthStr; use vec::Vec2; +use rect::Rect; use view::View; use {Cursive, Printer, With}; @@ -139,8 +140,7 @@ impl View for Button { ColorStyle::highlight() }; - let offset = - HAlign::Center.get_offset(self.label.len(), printer.size.x); + let offset = HAlign::Center.get_offset(self.label.width(), printer.size.x); printer.with_color(style, |printer| { printer.print((offset, 0), &self.label); @@ -175,4 +175,11 @@ impl View for Button { fn take_focus(&mut self, _: Direction) -> bool { self.enabled } + + fn important_area(&self, view_size: Vec2) -> Rect { + let width = self.label.width(); + let offset = HAlign::Center.get_offset(width, view_size.x); + + Rect::from_size((offset, 0), (width, 1)) + } } diff --git a/src/views/scroll_view.rs b/src/views/scroll_view.rs index 1a779ce..560f871 100644 --- a/src/views/scroll_view.rs +++ b/src/views/scroll_view.rs @@ -182,13 +182,16 @@ where EventResult::Ignored => { // If it's an arrow, try to scroll in the given direction. // If it's a mouse scroll, try to scroll as well. + // Also allow Ctrl+arrow to move the view without moving selection. match event { + Event::Ctrl(Key::Up) | Event::Key(Key::Up) if self.enabled.y && self.offset.y > 0 => { self.offset.y -= 1; EventResult::Consumed(None) } + Event::Ctrl(Key::Down) | Event::Key(Key::Down) if self.enabled.y && (self.offset.y + self.last_size.y @@ -197,12 +200,14 @@ where self.offset.y += 1; EventResult::Consumed(None) } + Event::Ctrl(Key::Left) | Event::Key(Key::Left) if self.enabled.x && self.offset.x > 0 => { self.offset.x -= 1; EventResult::Consumed(None) } + Event::Ctrl(Key::Right) | Event::Key(Key::Right) if self.enabled.x && (self.offset.x + self.last_size.x @@ -214,7 +219,24 @@ where _ => EventResult::Ignored, } } - other => other, + other => { + // Fix offset? + let important = self.inner.important_area(self.inner_size); + + // The furthest top-left we can go + let top_left = (important.bottom_right() + (1,1)).saturating_sub(self.last_size); + // The furthest bottom-right we can go + let bottom_right = important.top_left(); + + // "top_left < bottom_right" is NOT guaranteed + // if the child is larger than the view. + let offset_min = Vec2::min(top_left, bottom_right); + let offset_max = Vec2::max(top_left, bottom_right); + + self.offset = self.offset.or_max(offset_min).or_min(offset_max); + + other + }, } }