ui/src/tab_control.rs
2023-01-16 10:53:52 +01:00

82 lines
1.9 KiB
Rust

use std::sync::atomic::{AtomicU32, Ordering::SeqCst};
pub struct TabControl<T> {
data: Vec<T>,
pages: u32,
page_size: u32,
current_tab: AtomicU32,
}
impl<T> TabControl<T> {
pub fn new(data: Vec<T>, page_size: u32) -> Self {
let pages = Self::calculate_page_count(page_size, data.len());
Self {
data,
pages,
page_size,
current_tab: AtomicU32::new(0),
}
}
pub fn replace_data(&mut self, data: Vec<T>) {
self.pages = Self::calculate_page_count(self.page_size, data.len());
self.data = data;
if self._current_page() >= self.pages {
self.current_tab.store(self.pages - 1, SeqCst);
}
}
fn calculate_page_count(page_size: u32, element_count: usize) -> u32 {
((element_count as f32 / page_size as f32).ceil() as u32).max(1)
}
fn page_data(&self) -> Vec<&T> {
let start_offset = (self.page_size * self._current_page()) as usize;
let diff = self.data.len() - start_offset;
let end_index = start_offset + diff.min(self.page_size as usize);
(start_offset..end_index).map(|i| &self.data[i]).collect()
}
pub fn next_tab(&self) -> Option<Vec<&T>> {
if self._current_page() < (self.pages - 1) {
self.current_tab.fetch_add(1, SeqCst);
Some(self.page_data())
} else {
None
}
}
pub fn previous_tab(&self) -> Option<Vec<&T>> {
if self._current_page() > 0 {
self.current_tab.fetch_sub(1, SeqCst);
Some(self.page_data())
} else {
None
}
}
pub fn page_count(&self) -> u32 {
self.pages
}
fn _current_page(&self) -> u32 {
self.current_tab.load(SeqCst)
}
pub fn current_page(&self) -> u32 {
self._current_page() + 1
}
pub fn current_data(&self) -> Vec<&T> {
self.page_data()
}
}