ratatui-markdown 0.3.6

Markdown rendering, syntax highlighting, collapsible trees, and rich scroll widgets for ratatui
Documentation
use super::HybridScrollView;

impl HybridScrollView {
    pub(super) fn check_engage_down(&mut self) {
        let center = self.viewport_center();
        for (i, region) in self.regions.iter().enumerate() {
            if region.items.is_empty() {
                continue;
            }
            let first_item_center = region.item_center(0);
            if center >= first_item_center && self.last_center < first_item_center {
                self.engaged_region = Some(i);
                self.cursor_item = 0;
                self.center_on_item(i, 0);
                return;
            }
        }
        self.last_center = center;
    }

    pub(super) fn check_engage_up(&mut self) {
        let center = self.viewport_center();
        for (i, region) in self.regions.iter().enumerate() {
            if region.items.is_empty() {
                continue;
            }
            let last_idx = region.items.len() - 1;
            let last_item_center = region.item_center(last_idx);
            if center <= last_item_center && self.last_center > last_item_center {
                self.engaged_region = Some(i);
                self.cursor_item = last_idx;
                self.center_on_item(i, last_idx);
                return;
            }
        }
        self.last_center = center;
    }

    pub fn scroll_down(&mut self) {
        if self.lines.is_empty() {
            return;
        }

        if let Some(region_idx) = self.engaged_region {
            let item_count = self.regions[region_idx].items.len();
            if self.cursor_item < item_count - 1 {
                self.cursor_item += 1;
                self.center_on_item(region_idx, self.cursor_item);
            } else {
                let is_last_region = region_idx == self.regions.len() - 1;
                if is_last_region {
                    if self.scroll_offset < self.max_offset() {
                        self.scroll_offset += 1;
                        self.last_center = self.viewport_center();
                    }
                } else {
                    self.engaged_region = None;
                    self.last_center = self.viewport_center();
                    if self.scroll_offset < self.max_offset() {
                        self.scroll_offset += 1;
                        self.last_center = self.viewport_center();
                    }
                }
            }
        } else if self.scroll_offset < self.max_offset() {
            self.scroll_offset += 1;
            self.check_engage_down();
        }
    }

    pub fn scroll_up(&mut self) {
        if self.lines.is_empty() {
            return;
        }

        if let Some(region_idx) = self.engaged_region {
            if self.cursor_item > 0 {
                self.cursor_item -= 1;
                self.center_on_item(region_idx, self.cursor_item);
            } else {
                let is_first_region = region_idx == 0;
                if is_first_region {
                    if self.scroll_offset > 0 {
                        self.scroll_offset -= 1;
                        self.last_center = self.viewport_center();
                    }
                } else {
                    self.engaged_region = None;
                    self.last_center = self.viewport_center();
                    if self.scroll_offset > 0 {
                        self.scroll_offset -= 1;
                        self.last_center = self.viewport_center();
                    }
                }
            }
        } else if self.scroll_offset > 0 {
            self.scroll_offset -= 1;
            self.check_engage_up();
        }
    }

    pub fn engage_first(&mut self) {
        for (i, region) in self.regions.iter().enumerate() {
            if !region.items.is_empty() {
                self.engaged_region = Some(i);
                self.cursor_item = 0;
                self.center_on_item(i, 0);
                return;
            }
        }
    }

    pub fn engage_by_id(&mut self, id: &str) -> bool {
        for (ri, region) in self.regions.iter().enumerate() {
            for (ci, item) in region.items.iter().enumerate() {
                if item.id == id {
                    self.engaged_region = Some(ri);
                    self.cursor_item = ci;
                    return true;
                }
            }
        }
        false
    }

    pub fn set_scroll_offset(&mut self, offset: usize) {
        self.scroll_offset = offset;
        self.last_center = self.viewport_center();
    }

    pub fn scroll_to_top(&mut self) {
        self.scroll_offset = 0;
        self.engaged_region = None;
        self.cursor_item = 0;
        self.last_center = self.viewport_center();
    }

    pub fn scroll_to_bottom(&mut self) {
        self.scroll_offset = self.max_offset();
        self.engaged_region = None;
        self.cursor_item = 0;
        self.last_center = self.viewport_center();
    }

    pub fn page_down(&mut self, lines: usize) {
        for _ in 0..lines {
            self.scroll_down();
        }
    }

    pub fn page_up(&mut self, lines: usize) {
        for _ in 0..lines {
            self.scroll_up();
        }
    }
}