Skip to main content

tui/components/
mod.rs

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