libnotcurses_sys/widgets/selector/
methods.rs1use core::{
2 ffi::c_char,
3 ptr::{null, null_mut},
4};
5
6#[cfg(not(feature = "std"))]
7use alloc::string::{String, ToString};
8
9use crate::{
10 c_api, cstring, error, error_ref_mut, error_str,
11 widgets::{NcSelector, NcSelectorBuilder, NcSelectorItem, NcSelectorOptions},
12 NcChannels, NcInput, NcPlane, NcResult, NcString,
13};
14
15impl NcSelector {
16 pub fn new<'a>(plane: &mut NcPlane, options: &NcSelectorOptions) -> NcResult<&'a mut Self> {
20 error_ref_mut![
21 unsafe { c_api::ncselector_create(plane, options) },
22 "ncselector_create"
23 ]
24 }
25
26 pub fn builder() -> NcSelectorBuilder {
28 NcSelectorBuilder::new()
29 }
30
31 pub fn offer_input(&mut self, input: impl Into<NcInput>) -> bool {
42 unsafe { c_api::ncselector_offer_input(self, &input.into()) }
43 }
44
45 pub fn destroy(&mut self) -> NcResult<()> {
52 unsafe { c_api::ncselector_destroy(self, null_mut()) };
53 Ok(())
54 }
55
56 pub fn additem(&mut self, item: NcSelectorItem) -> NcResult<i32> {
60 error![
61 unsafe { c_api::ncselector_additem(self, &item) },
62 "Calling selector.additem", -1
63 ]
64 }
65
66 pub fn delitem(&mut self, item: &str) -> NcResult<i32> {
70 let cs = cstring![item];
71 error![
72 unsafe { c_api::ncselector_delitem(self, cs.as_ptr()) },
73 "Calling selector.delitem", -1
74 ]
75 }
76
77 pub fn selected(&mut self) -> Option<String> {
81 let res = unsafe { c_api::ncselector_selected(self) };
83 if res.is_null() {
84 None
85 } else {
86 Some(crate::rstring!(res).to_string())
87 }
88 }
89
90 pub fn nextitem(&mut self) -> NcResult<String> {
99 let cstr: *const c_char = unsafe { c_api::ncselector_nextitem(self) };
100 error_str![cstr, "Calling selector.nextitem"]
101 }
102
103 pub fn previtem(&mut self) -> NcResult<String> {
106 let cstr: *const c_char = unsafe { c_api::ncselector_previtem(self) };
107 error_str![cstr, "Calling selector.previtem"]
108 }
109}
110
111impl NcSelectorItem {
112 pub fn new(option: &NcString, desc: &NcString) -> Self {
114 Self { option: option.as_ptr(), desc: desc.as_ptr() }
115 }
116
117 pub fn new_empty() -> Self {
119 Self { option: null(), desc: null() }
120 }
121}
122
123impl NcSelectorOptions {
125 pub fn new(items: &[NcSelectorItem]) -> Self {
127 Self {
128 title: null(),
129 secondary: null(),
130 footer: null(),
131 items: items.as_ptr(),
132 defidx: 0,
133 maxdisplay: 0,
134 opchannels: 0,
135 descchannels: 0,
136 titlechannels: 0,
137 footchannels: 0,
138 boxchannels: 0,
139 flags: 0,
140 }
141 }
142
143 pub fn with_all_options(
145 title: Option<&NcString>,
146 secondary: Option<&NcString>,
147 footer: Option<&NcString>,
148 items: &[NcSelectorItem],
149 default: u32,
150 max_display: u32,
151 opchannels: impl Into<NcChannels>,
152 descchannels: impl Into<NcChannels>,
153 titlechannels: impl Into<NcChannels>,
154 footchannels: impl Into<NcChannels>,
155 boxchannels: impl Into<NcChannels>,
156 ) -> Self {
157 assert![!items.is_empty()]; let title_ptr = if let Some(s) = title { s.as_ptr() } else { null() };
160 let secondary_ptr = if let Some(s) = secondary { s.as_ptr() } else { null() };
161 let footer_ptr = if let Some(s) = footer { s.as_ptr() } else { null() };
162
163 Self {
164 title: title_ptr,
165 secondary: secondary_ptr,
166 footer: footer_ptr,
167 items: items.as_ptr(),
169 defidx: default,
171 maxdisplay: max_display,
174 opchannels: opchannels.into().into(),
176 descchannels: descchannels.into().into(),
177 titlechannels: titlechannels.into().into(),
178 footchannels: footchannels.into().into(),
179 boxchannels: boxchannels.into().into(),
180 flags: 0x0,
181 }
182 }
183}