mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Remove internal scrolling from list_view
This commit is contained in:
parent
46181fabcc
commit
49e1d1d15e
@ -74,7 +74,8 @@ fn main() {
|
|||||||
EditView::new(),
|
EditView::new(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
|
.scrollable(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ impl<'a, 'b> Printer<'a, 'b> {
|
|||||||
|
|
||||||
// Here again, we can abort if we're trying to print too far right or
|
// Here again, we can abort if we're trying to print too far right or
|
||||||
// too low.
|
// too low.
|
||||||
if !start.fits_in(self.output_size + self.content_offset) {
|
if !(start < (self.output_size + self.content_offset)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +212,7 @@ impl<'a, 'b> Printer<'a, 'b> {
|
|||||||
let start = start.into();
|
let start = start.into();
|
||||||
|
|
||||||
// Nothing to be done if the start if too far to the bottom/right
|
// Nothing to be done if the start if too far to the bottom/right
|
||||||
if !start.fits_in(self.output_size + self.content_offset) {
|
if !(start < (self.output_size + self.content_offset)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
use direction;
|
use direction;
|
||||||
use event::{
|
use event::{AnyCb, Callback, Event, EventResult, Key};
|
||||||
AnyCb, Callback, Event, EventResult, Key, MouseButton, MouseEvent,
|
|
||||||
};
|
|
||||||
use rect::Rect;
|
use rect::Rect;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
use view::{ScrollBase, Selector, View};
|
use view::{Selector, View};
|
||||||
use Cursive;
|
use Cursive;
|
||||||
use Printer;
|
use Printer;
|
||||||
use With;
|
use With;
|
||||||
@ -37,10 +35,9 @@ impl ListChild {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Displays a scrollable list of elements.
|
/// Displays a list of elements.
|
||||||
pub struct ListView {
|
pub struct ListView {
|
||||||
children: Vec<ListChild>,
|
children: Vec<ListChild>,
|
||||||
scrollbase: ScrollBase,
|
|
||||||
focus: usize,
|
focus: usize,
|
||||||
// This callback is called when the selection is changed.
|
// This callback is called when the selection is changed.
|
||||||
on_select: Option<Rc<Fn(&mut Cursive, &String)>>,
|
on_select: Option<Rc<Fn(&mut Cursive, &String)>>,
|
||||||
@ -54,7 +51,6 @@ impl ListView {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
ListView {
|
ListView {
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
scrollbase: ScrollBase::new(),
|
|
||||||
focus: 0,
|
focus: 0,
|
||||||
on_select: None,
|
on_select: None,
|
||||||
last_size: Vec2::zero(),
|
last_size: Vec2::zero(),
|
||||||
@ -192,7 +188,6 @@ impl ListView {
|
|||||||
return EventResult::Ignored;
|
return EventResult::Ignored;
|
||||||
};
|
};
|
||||||
self.focus = i;
|
self.focus = i;
|
||||||
self.scrollbase.scroll_to(self.focus);
|
|
||||||
|
|
||||||
EventResult::Consumed(self.on_select.clone().map(|cb| {
|
EventResult::Consumed(self.on_select.clone().map(|cb| {
|
||||||
let i = self.focus();
|
let i = self.focus();
|
||||||
@ -226,14 +221,10 @@ impl ListView {
|
|||||||
Some(pos) => pos,
|
Some(pos) => pos,
|
||||||
};
|
};
|
||||||
|
|
||||||
if position.y > self.scrollbase.view_height {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// eprintln!("Rel pos: {:?}", position);
|
// eprintln!("Rel pos: {:?}", position);
|
||||||
|
|
||||||
// Now that we have a relative position, checks for buttons?
|
// Now that we have a relative position, checks for buttons?
|
||||||
let focus = position.y + self.scrollbase.start_line;
|
let focus = position.y;
|
||||||
if focus >= self.children.len() {
|
if focus >= self.children.len() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -269,16 +260,17 @@ impl View for ListView {
|
|||||||
let offset = self.labels_width() + 1;
|
let offset = self.labels_width() + 1;
|
||||||
|
|
||||||
debug!("Offset: {}", offset);
|
debug!("Offset: {}", offset);
|
||||||
self.scrollbase
|
for (i, child) in self.children.iter().enumerate() {
|
||||||
.draw(printer, |printer, i| match self.children[i] {
|
match child {
|
||||||
ListChild::Row(ref label, ref view) => {
|
ListChild::Row(ref label, ref view) => {
|
||||||
printer.print((0, 0), label);
|
printer.print((0, i), label);
|
||||||
view.draw(
|
view.draw(
|
||||||
&printer.offset((offset, 0)).focused(i == self.focus),
|
&printer.offset((offset, i)).focused(i == self.focus),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ListChild::Delimiter => (),
|
ListChild::Delimiter => (),
|
||||||
});
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn required_size(&mut self, req: Vec2) -> Vec2 {
|
fn required_size(&mut self, req: Vec2) -> Vec2 {
|
||||||
@ -299,17 +291,11 @@ impl View for ListView {
|
|||||||
.max()
|
.max()
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
if self.children.len() > req.y {
|
|
||||||
// Include a scroll bar
|
|
||||||
Vec2::new(label_width + 1 + view_size + 2, req.y)
|
|
||||||
} else {
|
|
||||||
Vec2::new(label_width + 1 + view_size, self.children.len())
|
Vec2::new(label_width + 1 + view_size, self.children.len())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(&mut self, size: Vec2) {
|
fn layout(&mut self, size: Vec2) {
|
||||||
self.last_size = size;
|
self.last_size = size;
|
||||||
self.scrollbase.set_heights(size.y, self.children.len());
|
|
||||||
|
|
||||||
// We'll show 2 columns: the labels, and the views.
|
// We'll show 2 columns: the labels, and the views.
|
||||||
let label_width = self
|
let label_width = self
|
||||||
@ -321,11 +307,8 @@ impl View for ListView {
|
|||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
let spacing = 1;
|
let spacing = 1;
|
||||||
let scrollbar_width = if self.children.len() > size.y { 2 } else { 0 };
|
|
||||||
|
|
||||||
let available = size
|
let available = size.x.saturating_sub(label_width + spacing);
|
||||||
.x
|
|
||||||
.saturating_sub(label_width + spacing + scrollbar_width);
|
|
||||||
|
|
||||||
debug!("Available: {}", available);
|
debug!("Available: {}", available);
|
||||||
|
|
||||||
@ -339,46 +322,6 @@ impl View for ListView {
|
|||||||
return EventResult::Ignored;
|
return EventResult::Ignored;
|
||||||
}
|
}
|
||||||
|
|
||||||
// First: some events can directly affect the ListView
|
|
||||||
match event {
|
|
||||||
Event::Mouse {
|
|
||||||
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) =>
|
|
||||||
{
|
|
||||||
return EventResult::Consumed(None);
|
|
||||||
}
|
|
||||||
Event::Mouse {
|
|
||||||
event: MouseEvent::Hold(MouseButton::Left),
|
|
||||||
position,
|
|
||||||
offset,
|
|
||||||
}
|
|
||||||
if self.scrollbase.is_dragging() =>
|
|
||||||
{
|
|
||||||
let position = position.saturating_sub(offset);
|
|
||||||
self.scrollbase.drag(position);
|
|
||||||
return EventResult::Consumed(None);
|
|
||||||
}
|
|
||||||
Event::Mouse {
|
|
||||||
event: MouseEvent::Release(MouseButton::Left),
|
|
||||||
..
|
|
||||||
}
|
|
||||||
if self.scrollbase.is_dragging() =>
|
|
||||||
{
|
|
||||||
self.scrollbase.release_grab();
|
|
||||||
return EventResult::Consumed(None);
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then: some events can move the focus around.
|
|
||||||
self.check_focus_grab(&event);
|
self.check_focus_grab(&event);
|
||||||
|
|
||||||
// Send the event to the focused child.
|
// Send the event to the focused child.
|
||||||
@ -386,15 +329,12 @@ impl View for ListView {
|
|||||||
if let ListChild::Row(_, ref mut view) = self.children[self.focus] {
|
if let ListChild::Row(_, ref mut view) = self.children[self.focus] {
|
||||||
// If self.focus < self.scrollbase.start_line, it means the focus is not
|
// If self.focus < self.scrollbase.start_line, it means the focus is not
|
||||||
// in view. Something's fishy, so don't send the event.
|
// in view. Something's fishy, so don't send the event.
|
||||||
if let Some(y) = self.focus.checked_sub(self.scrollbase.start_line)
|
let offset = (labels_width + 1, self.focus);
|
||||||
{
|
|
||||||
let offset = (labels_width + 1, y);
|
|
||||||
let result = view.on_event(event.relativized(offset));
|
let result = view.on_event(event.relativized(offset));
|
||||||
if result.is_consumed() {
|
if result.is_consumed() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If the child ignored this event, change the focus.
|
// If the child ignored this event, change the focus.
|
||||||
match event {
|
match event {
|
||||||
@ -420,24 +360,6 @@ impl View for ListView {
|
|||||||
Event::Shift(Key::Tab) => {
|
Event::Shift(Key::Tab) => {
|
||||||
self.move_focus(1, direction::Direction::back())
|
self.move_focus(1, direction::Direction::back())
|
||||||
}
|
}
|
||||||
Event::Mouse {
|
|
||||||
event: MouseEvent::WheelDown,
|
|
||||||
..
|
|
||||||
}
|
|
||||||
if self.scrollbase.can_scroll_down() =>
|
|
||||||
{
|
|
||||||
self.scrollbase.scroll_down(5);
|
|
||||||
EventResult::Consumed(None)
|
|
||||||
}
|
|
||||||
Event::Mouse {
|
|
||||||
event: MouseEvent::WheelUp,
|
|
||||||
..
|
|
||||||
}
|
|
||||||
if self.scrollbase.can_scroll_up() =>
|
|
||||||
{
|
|
||||||
self.scrollbase.scroll_up(5);
|
|
||||||
EventResult::Consumed(None)
|
|
||||||
}
|
|
||||||
_ => EventResult::Ignored,
|
_ => EventResult::Ignored,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -455,7 +377,6 @@ impl View for ListView {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
self.focus = i;
|
self.focus = i;
|
||||||
self.scrollbase.scroll_to(self.focus);
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user