Skip to main content

tui/components/
mod.rs

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