gm-tui 0.0.1

TUI-based Ethereum wallet
Documentation
use ratatui::{layout::Offset, widgets::Widget};

pub struct CustomScrollBar {
    pub cursor: usize,
    pub total: usize,
}

impl Widget for CustomScrollBar {
    fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer)
    where
        Self: Sized,
    {
        let capacity = area.height as usize;
        let num_pages = self.total.div_ceil(capacity);
        let current_page = self.cursor / capacity;

        let top = (0..current_page)
            .map(|i| get_page_height(i, capacity, num_pages))
            .sum::<usize>();
        let middle = get_page_height(current_page, capacity, num_pages);
        let bottom = ((current_page + 1)..num_pages)
            .map(|i| get_page_height(i, capacity, num_pages))
            .sum::<usize>();
        assert_eq!(
            top + middle + bottom,
            capacity,
            "self.total = {}, capacity = {}, current_page = {current_page}, num_pages = {num_pages}, top = {top}, middle = {middle}, bottom = {bottom}",
            self.total, capacity
        );

        let mut i = 0;
        for _ in 0..top {
            "".render(area.offset(Offset { x: 0, y: i }), buf);
            i += 1;
        }
        for _ in 0..middle {
            "".render(area.offset(Offset { x: 0, y: i }), buf);
            i += 1;
        }
        for _ in 0..bottom {
            "".render(area.offset(Offset { x: 0, y: i }), buf);
            i += 1;
        }
    }
}

fn get_page_height(i: usize, capacity: usize, num_pages: usize) -> usize {
    let base = capacity / num_pages;
    if i < capacity % num_pages {
        base + 1
    } else {
        base
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_get_page_height() {
        for capacity in 10..100 {
            for num_pages in 1..15 {
                let mut sum = 0;
                for i in 0..num_pages {
                    sum += get_page_height(i, capacity, num_pages);
                }

                if sum != capacity {
                    println!("capacity: {capacity}, num_pages: {num_pages}");
                    for i in 0..num_pages {
                        let h = get_page_height(i, capacity, num_pages);
                        println!("page {i}: {h}");
                    }
                }

                assert_eq!(
                    sum, capacity,
                    "capacity: {capacity}, num_pages: {num_pages}"
                );
            }
        }
    }
}