mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +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?
|
// We don't want people to start calling prints in parallel?
|
||||||
/// Prints some text at the given position relative to the window.
|
/// Prints some text at the given position relative to the window.
|
||||||
pub fn print<S: Into<Vec2>>(&self, start: S, text: &str) {
|
pub fn print<S: Into<Vec2>>(&self, start: S, text: &str) {
|
||||||
|
// Where we are asked to start printing. Oh boy.
|
||||||
let start = start.into();
|
let start = start.into();
|
||||||
|
|
||||||
// We accept requests between `content_offset` and
|
// We accept requests between `content_offset` and
|
||||||
// `content_offset + size`
|
// `content_offset + output_size`.
|
||||||
if start >= self.output_size + self.content_offset {
|
if !(start < (self.output_size + self.content_offset)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ use event::*;
|
|||||||
use theme::ColorStyle;
|
use theme::ColorStyle;
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
|
use rect::Rect;
|
||||||
use view::View;
|
use view::View;
|
||||||
use {Cursive, Printer, With};
|
use {Cursive, Printer, With};
|
||||||
|
|
||||||
@ -139,8 +140,7 @@ impl View for Button {
|
|||||||
ColorStyle::highlight()
|
ColorStyle::highlight()
|
||||||
};
|
};
|
||||||
|
|
||||||
let offset =
|
let offset = HAlign::Center.get_offset(self.label.width(), printer.size.x);
|
||||||
HAlign::Center.get_offset(self.label.len(), printer.size.x);
|
|
||||||
|
|
||||||
printer.with_color(style, |printer| {
|
printer.with_color(style, |printer| {
|
||||||
printer.print((offset, 0), &self.label);
|
printer.print((offset, 0), &self.label);
|
||||||
@ -175,4 +175,11 @@ impl View for Button {
|
|||||||
fn take_focus(&mut self, _: Direction) -> bool {
|
fn take_focus(&mut self, _: Direction) -> bool {
|
||||||
self.enabled
|
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 => {
|
EventResult::Ignored => {
|
||||||
// If it's an arrow, try to scroll in the given direction.
|
// If it's an arrow, try to scroll in the given direction.
|
||||||
// If it's a mouse scroll, try to scroll as well.
|
// If it's a mouse scroll, try to scroll as well.
|
||||||
|
// Also allow Ctrl+arrow to move the view without moving selection.
|
||||||
match event {
|
match event {
|
||||||
|
Event::Ctrl(Key::Up) |
|
||||||
Event::Key(Key::Up)
|
Event::Key(Key::Up)
|
||||||
if self.enabled.y && self.offset.y > 0 =>
|
if self.enabled.y && self.offset.y > 0 =>
|
||||||
{
|
{
|
||||||
self.offset.y -= 1;
|
self.offset.y -= 1;
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
|
Event::Ctrl(Key::Down) |
|
||||||
Event::Key(Key::Down)
|
Event::Key(Key::Down)
|
||||||
if self.enabled.y
|
if self.enabled.y
|
||||||
&& (self.offset.y + self.last_size.y
|
&& (self.offset.y + self.last_size.y
|
||||||
@ -197,12 +200,14 @@ where
|
|||||||
self.offset.y += 1;
|
self.offset.y += 1;
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
|
Event::Ctrl(Key::Left) |
|
||||||
Event::Key(Key::Left)
|
Event::Key(Key::Left)
|
||||||
if self.enabled.x && self.offset.x > 0 =>
|
if self.enabled.x && self.offset.x > 0 =>
|
||||||
{
|
{
|
||||||
self.offset.x -= 1;
|
self.offset.x -= 1;
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
|
Event::Ctrl(Key::Right) |
|
||||||
Event::Key(Key::Right)
|
Event::Key(Key::Right)
|
||||||
if self.enabled.x
|
if self.enabled.x
|
||||||
&& (self.offset.x + self.last_size.x
|
&& (self.offset.x + self.last_size.x
|
||||||
@ -214,7 +219,24 @@ where
|
|||||||
_ => EventResult::Ignored,
|
_ => 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