use super::types::Selection;
impl Default for Selection {
fn default() -> Self {
Self::new(0)
}
}
impl Selection {
pub fn new(len: usize) -> Self {
Self {
index: 0,
len,
offset: std::cell::Cell::new(0),
visible: std::cell::Cell::new(usize::MAX),
}
}
pub fn next(&mut self) {
if self.len > 0 {
self.index = (self.index + 1) % self.len;
self.ensure_visible();
}
}
pub fn prev(&mut self) {
if self.len > 0 {
self.index = if self.index == 0 {
self.len - 1
} else {
self.index - 1
};
self.ensure_visible();
}
}
pub fn down(&mut self) {
if self.len > 0 && self.index < self.len - 1 {
self.index += 1;
self.ensure_visible();
}
}
pub fn up(&mut self) {
if self.index > 0 {
self.index -= 1;
self.ensure_visible();
}
}
pub fn first(&mut self) {
self.index = 0;
self.offset.set(0);
}
pub fn last(&mut self) {
if self.len > 0 {
self.index = self.len - 1;
self.ensure_visible();
}
}
pub fn set(&mut self, index: usize) {
self.index = index.min(self.len.saturating_sub(1));
self.ensure_visible();
}
pub fn select(&mut self, index: usize) {
self.set(index);
}
pub fn set_len(&mut self, len: usize) {
self.len = len;
if self.index >= len && len > 0 {
self.index = len - 1;
}
self.ensure_visible();
}
pub fn set_visible(&self, visible: usize) {
self.visible.set(visible);
self.ensure_visible();
}
fn ensure_visible(&self) {
let visible = self.visible.get();
if visible == 0 {
return;
}
if visible >= self.len {
self.offset.set(0);
return;
}
let mut offset = self.offset.get();
if self.index >= offset + visible {
offset = self.index.saturating_sub(visible - 1);
}
if self.index < offset {
offset = self.index;
}
let max_offset = self.len.saturating_sub(visible);
self.offset.set(offset.min(max_offset));
}
pub fn offset(&self) -> usize {
self.offset.get()
}
pub fn visible_range(&self) -> std::ops::Range<usize> {
let offset = self.offset.get();
let end = (offset + self.visible.get()).min(self.len);
offset..end
}
pub fn reset_offset(&mut self) {
self.offset.set(0);
}
pub fn is_selected(&self, index: usize) -> bool {
self.index == index
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn page_down(&mut self) {
let visible = self.visible.get();
if visible > 0 && self.len > 0 {
self.index = (self.index + visible).min(self.len - 1);
self.ensure_visible();
}
}
pub fn page_up(&mut self) {
let visible = self.visible.get();
if visible > 0 {
self.index = self.index.saturating_sub(visible);
self.ensure_visible();
}
}
}