mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-10 03:10:41 +00:00
Scrollview: move offset to keep important area in view
This commit is contained in:
parent
2088d5de2a
commit
94504ae91b
@ -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<S: Into<Vec2>>(&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;
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user