Skip to main content

tui/components/
mod.rs

1pub mod checkbox;
2pub mod component;
3pub mod form;
4pub mod gallery;
5pub mod layout;
6pub mod multi_select;
7pub mod number_field;
8pub mod panel;
9pub mod radio_select;
10pub mod select_list;
11pub mod select_option;
12pub mod spinner;
13pub mod split_panel;
14pub mod text_field;
15
16pub use crate::rendering::frame::Cursor;
17pub use crate::rendering::render_context::ViewContext;
18pub use component::{Component, Event, PickerMessage, merge};
19
20/// Wrapping navigation helper for selection indices.
21/// `delta` of -1 moves up, +1 moves down, wrapping at boundaries.
22pub fn wrap_selection(index: &mut usize, len: usize, delta: isize) {
23    if len == 0 {
24        return;
25    }
26    *index = ((*index).cast_signed() + delta).rem_euclid(len.cast_signed()) as usize;
27}
28
29#[cfg(test)]
30mod tests {
31    use super::*;
32
33    #[test]
34    fn wrap_selection_wraps_up_from_zero() {
35        let mut idx = 0;
36        wrap_selection(&mut idx, 3, -1);
37        assert_eq!(idx, 2);
38    }
39
40    #[test]
41    fn wrap_selection_wraps_down_from_last() {
42        let mut idx = 2;
43        wrap_selection(&mut idx, 3, 1);
44        assert_eq!(idx, 0);
45    }
46
47    #[test]
48    fn wrap_selection_noop_on_empty() {
49        let mut idx = 0;
50        wrap_selection(&mut idx, 0, 1);
51        assert_eq!(idx, 0);
52    }
53
54    #[test]
55    fn wrap_selection_moves_normally() {
56        let mut idx = 1;
57        wrap_selection(&mut idx, 5, 1);
58        assert_eq!(idx, 2);
59        wrap_selection(&mut idx, 5, -1);
60        assert_eq!(idx, 1);
61    }
62}