libnotcurses_sys/widgets/selector/
builder.rs

1use core::cmp::min;
2
3#[cfg(not(feature = "std"))]
4use alloc::{vec, vec::Vec};
5
6use crate::{
7    widgets::{NcSelector, NcSelectorItem, NcSelectorOptions},
8    NcChannels, NcPlane, NcResult, NcString,
9};
10
11/// A handy builder for [`NcSelector`].
12///
13#[derive(Default, Debug)]
14pub struct NcSelectorBuilder {
15    title: Option<NcString>,
16    secondary: Option<NcString>,
17    footer: Option<NcString>,
18    items: Vec<(NcString, NcString)>,
19    default_item: u32,
20    max_display: u32,
21    channels: [NcChannels; 5],
22    flags: u64,
23}
24
25impl NcSelectorBuilder {
26    /// New `NcSelectorBuilder`.
27    pub fn new() -> Self {
28        Self::default()
29    }
30
31    /// Adds an item.
32    pub fn item(mut self, o: &str, d: &str) -> Self {
33        self.items.push((NcString::new(o), NcString::new(d)));
34        self
35    }
36
37    /// Selects the default item
38    ///
39    /// It is selected at the start and must be between 0 and itemcount-1.
40    //
41    // TODO: check when finish it's n-1 at max
42    pub fn default_item(mut self, item: u32) -> Self {
43        self.default_item = item;
44        self
45    }
46
47    /// Selects the maximum number of items to display at once.
48    ///
49    /// 0 uses all available space.
50    pub fn max_display(mut self, max: u32) -> Self {
51        self.max_display = max;
52        self
53    }
54
55    /// Sets the title string.
56    pub fn title(mut self, title: &str) -> Self {
57        self.title = Some(NcString::new(title));
58        self
59    }
60
61    /// Sets the secondary title string.
62    pub fn secondary(mut self, secondary: &str) -> Self {
63        self.secondary = Some(NcString::new(secondary));
64        self
65    }
66
67    /// Sets the footer string.
68    pub fn footer(mut self, footer: &str) -> Self {
69        self.footer = Some(NcString::new(footer));
70        self
71    }
72
73    /// Sets the flags.
74    pub fn flags(mut self, flags: u64) -> Self {
75        self.flags = flags;
76        self
77    }
78
79    /// Sets all the `NcChannels`.
80    pub fn all_channels(
81        mut self,
82        item_opt: impl Into<NcChannels>,
83        item_desc: impl Into<NcChannels>,
84        seltitle: impl Into<NcChannels>,
85        selfooter: impl Into<NcChannels>,
86        selbox: impl Into<NcChannels>,
87    ) -> Self {
88        self.channels = [
89            item_opt.into(),
90            item_desc.into(),
91            seltitle.into(),
92            selfooter.into(),
93            selbox.into(),
94        ];
95        self
96    }
97
98    /// Sets the `NcChannels` for the item.
99    pub fn item_channels(
100        mut self,
101        opt: impl Into<NcChannels>,
102        desc: impl Into<NcChannels>,
103    ) -> Self {
104        self.channels[0] = opt.into();
105        self.channels[1] = desc.into();
106        self
107    }
108
109    /// Sets the `NcChannels` for the title.
110    pub fn title_channels(mut self, title: impl Into<NcChannels>) -> Self {
111        self.channels[2] = title.into();
112        self
113    }
114
115    /// Sets the `NcChannels` for the secondary title and the footer.
116    pub fn secondary_channels(mut self, secondary: impl Into<NcChannels>) -> Self {
117        self.channels[3] = secondary.into();
118        self
119    }
120
121    /// Sets the `NcChannels` for the box title.
122    pub fn box_channels(mut self, r#box: impl Into<NcChannels>) -> Self {
123        self.channels[4] = r#box.into();
124        self
125    }
126
127    /// Finishes the builder and returns the `NcSelector`.
128    pub fn finish(self, plane: &mut NcPlane) -> NcResult<&mut NcSelector> {
129        let mut selitems = vec![];
130        for (o, d) in self.items.iter() {
131            selitems.push(NcSelectorItem::new(o, d));
132        }
133        selitems.push(NcSelectorItem::new_empty());
134
135        let default_item = min(self.default_item, selitems.len() as u32 - 1);
136
137        let options = NcSelectorOptions::with_all_options(
138            self.title.as_ref(),
139            self.secondary.as_ref(),
140            self.footer.as_ref(),
141            &selitems,
142            default_item,
143            self.max_display,
144            self.channels[0],
145            self.channels[1],
146            self.channels[2],
147            self.channels[3],
148            self.channels[4],
149        );
150
151        NcSelector::new(plane, &options)
152    }
153}