dear_imgui_rs/widget/combo/
ui.rs1use std::borrow::Cow;
2
3use crate::sys;
4use crate::ui::Ui;
5
6use super::{ComboBoxFlags, ComboBoxOptions, ComboBoxPreviewMode, ComboBoxToken};
7
8impl Ui {
10 #[must_use]
17 #[doc(alias = "BeginCombo")]
18 pub fn begin_combo(
19 &self,
20 label: impl AsRef<str>,
21 preview_value: impl AsRef<str>,
22 ) -> Option<ComboBoxToken<'_>> {
23 self.begin_combo_with_flags(label, preview_value, ComboBoxFlags::NONE)
24 }
25
26 #[must_use]
32 #[doc(alias = "BeginCombo")]
33 pub fn begin_combo_with_flags(
34 &self,
35 label: impl AsRef<str>,
36 preview_value: impl AsRef<str>,
37 flags: impl Into<ComboBoxOptions>,
38 ) -> Option<ComboBoxToken<'_>> {
39 let options = flags.into();
40 options.validate("Ui::begin_combo_with_flags()");
41 let (label_ptr, preview_ptr) = self.scratch_txt_two(label, preview_value);
42
43 let should_render = unsafe { sys::igBeginCombo(label_ptr, preview_ptr, options.raw()) };
44
45 if should_render {
46 Some(ComboBoxToken::new(self))
47 } else {
48 None
49 }
50 }
51
52 #[must_use]
59 #[doc(alias = "BeginCombo")]
60 pub fn begin_combo_no_preview(&self, label: impl AsRef<str>) -> Option<ComboBoxToken<'_>> {
61 self.begin_combo_no_preview_with_flags(label, ComboBoxFlags::NONE)
62 }
63
64 #[must_use]
71 #[doc(alias = "BeginCombo")]
72 pub fn begin_combo_no_preview_with_flags(
73 &self,
74 label: impl AsRef<str>,
75 flags: impl Into<ComboBoxOptions>,
76 ) -> Option<ComboBoxToken<'_>> {
77 let mut options = flags.into();
78 options.preview_mode = ComboBoxPreviewMode::NoPreview;
79 options.validate("Ui::begin_combo_no_preview_with_flags()");
80 let label_ptr = self.scratch_txt(label);
81
82 let should_render =
83 unsafe { sys::igBeginCombo(label_ptr, std::ptr::null(), options.raw()) };
84
85 if should_render {
86 Some(ComboBoxToken::new(self))
87 } else {
88 None
89 }
90 }
91
92 #[doc(alias = "Combo")]
94 pub fn combo<V, L>(
95 &self,
96 label: impl AsRef<str>,
97 current_item: &mut usize,
98 items: &[V],
99 label_fn: L,
100 ) -> bool
101 where
102 for<'b> L: Fn(&'b V) -> Cow<'b, str>,
103 {
104 let label_fn = &label_fn;
105 let mut result = false;
106 let preview_value = items.get(*current_item).map(label_fn);
107
108 if let Some(combo_token) = self.begin_combo(
109 label,
110 preview_value.as_ref().map(|s| s.as_ref()).unwrap_or(""),
111 ) {
112 for (idx, item) in items.iter().enumerate() {
113 let is_selected = idx == *current_item;
114 if is_selected {
115 self.set_item_default_focus();
116 }
117
118 let clicked = self.selectable(label_fn(item).as_ref());
119
120 if clicked {
121 *current_item = idx;
122 result = true;
123 }
124 }
125 combo_token.end();
126 }
127
128 result
129 }
130
131 #[doc(alias = "Combo")]
136 pub fn combo_i32<V, L>(
137 &self,
138 label: impl AsRef<str>,
139 current_item: &mut i32,
140 items: &[V],
141 label_fn: L,
142 ) -> bool
143 where
144 for<'b> L: Fn(&'b V) -> Cow<'b, str>,
145 {
146 let label_fn = &label_fn;
147 let mut result = false;
148
149 let preview_value = if *current_item >= 0 {
150 items.get(*current_item as usize).map(|v| label_fn(v))
151 } else {
152 None
153 };
154
155 if let Some(combo_token) = self.begin_combo(
156 label,
157 preview_value.as_ref().map(|s| s.as_ref()).unwrap_or(""),
158 ) {
159 for (idx, item) in items.iter().enumerate() {
160 if idx > i32::MAX as usize {
161 break;
162 }
163 let idx_i32 = idx as i32;
164 let is_selected = idx_i32 == *current_item;
165 if is_selected {
166 self.set_item_default_focus();
167 }
168
169 let clicked = self.selectable(label_fn(item).as_ref());
170 if clicked {
171 *current_item = idx_i32;
172 result = true;
173 }
174 }
175 combo_token.end();
176 }
177
178 result
179 }
180
181 #[doc(alias = "Combo")]
183 pub fn combo_simple_string(
184 &self,
185 label: impl AsRef<str>,
186 current_item: &mut usize,
187 items: &[impl AsRef<str>],
188 ) -> bool {
189 self.combo(label, current_item, items, |s| Cow::Borrowed(s.as_ref()))
190 }
191
192 #[doc(alias = "Combo")]
194 pub fn combo_simple_string_i32(
195 &self,
196 label: impl AsRef<str>,
197 current_item: &mut i32,
198 items: &[impl AsRef<str>],
199 ) -> bool {
200 self.combo_i32(label, current_item, items, |s| Cow::Borrowed(s.as_ref()))
201 }
202
203 pub fn set_item_default_focus(&self) {
205 unsafe {
206 sys::igSetItemDefaultFocus();
207 }
208 }
209}