|
|
|
@ -20,13 +20,17 @@ impl Default for ListState {
|
|
|
|
|
fn default() -> ListState {
|
|
|
|
|
ListState {
|
|
|
|
|
offset: 0,
|
|
|
|
|
target: None,
|
|
|
|
|
selected: BTreeSet::new(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ListState {
|
|
|
|
|
pub fn offset(mut self, offset: usize) -> Self {
|
|
|
|
|
self.offset = offset;
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn selected(&self) -> &BTreeSet<usize> {
|
|
|
|
|
&self.selected
|
|
|
|
|
}
|
|
|
|
@ -35,13 +39,6 @@ impl ListState {
|
|
|
|
|
self.selected.insert(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn front_selection(&mut self) -> Option<usize> {
|
|
|
|
|
match self.target {
|
|
|
|
|
None => self.selected.iter().next().cloned(),
|
|
|
|
|
Some(target) => Some(target),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn deselect(&mut self, index: usize) {
|
|
|
|
|
self.selected.remove(&index);
|
|
|
|
|
}
|
|
|
|
@ -147,7 +144,6 @@ impl<'a> List<'a> {
|
|
|
|
|
|
|
|
|
|
fn get_items_bounds(
|
|
|
|
|
&self,
|
|
|
|
|
selected: Option<usize>,
|
|
|
|
|
offset: usize,
|
|
|
|
|
max_height: usize,
|
|
|
|
|
) -> (usize, usize) {
|
|
|
|
@ -155,6 +151,7 @@ impl<'a> List<'a> {
|
|
|
|
|
let mut start = offset;
|
|
|
|
|
let mut end = offset;
|
|
|
|
|
let mut height = 0;
|
|
|
|
|
|
|
|
|
|
for item in self.items.iter().skip(offset) {
|
|
|
|
|
if height + item.height() > max_height {
|
|
|
|
|
break;
|
|
|
|
@ -163,23 +160,6 @@ impl<'a> List<'a> {
|
|
|
|
|
end += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let selected = selected.unwrap_or(0).min(self.items.len() - 1);
|
|
|
|
|
while selected >= end {
|
|
|
|
|
height = height.saturating_add(self.items[end].height());
|
|
|
|
|
end += 1;
|
|
|
|
|
while height > max_height {
|
|
|
|
|
height = height.saturating_sub(self.items[start].height());
|
|
|
|
|
start += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while selected < start {
|
|
|
|
|
start -= 1;
|
|
|
|
|
height = height.saturating_add(self.items[start].height());
|
|
|
|
|
while height > max_height {
|
|
|
|
|
end -= 1;
|
|
|
|
|
height = height.saturating_sub(self.items[end].height());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
(start, end)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -207,9 +187,7 @@ impl<'a> StatefulWidget for List<'a> {
|
|
|
|
|
}
|
|
|
|
|
let list_height = list_area.height as usize;
|
|
|
|
|
|
|
|
|
|
let (start, end) =
|
|
|
|
|
self.get_items_bounds(state.front_selection(), state.offset, list_height);
|
|
|
|
|
state.offset = start;
|
|
|
|
|
let (start, end) = self.get_items_bounds(state.offset, list_height);
|
|
|
|
|
|
|
|
|
|
let highlight_symbol = self.highlight_symbol.unwrap_or("");
|
|
|
|
|
let blank_symbol = " ".repeat(highlight_symbol.width());
|
|
|
|
@ -220,7 +198,7 @@ impl<'a> StatefulWidget for List<'a> {
|
|
|
|
|
.items
|
|
|
|
|
.iter_mut()
|
|
|
|
|
.enumerate()
|
|
|
|
|
.skip(state.offset)
|
|
|
|
|
.skip(start)
|
|
|
|
|
.take(end - start)
|
|
|
|
|
{
|
|
|
|
|
let (x, y) = match self.start_corner {
|
|
|
|
|