81 lines
1.9 KiB
Rust
81 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()
|
|
}
|
|
}
|