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 = self.run_with_bound_context(|| unsafe {
44 sys::igBeginCombo(label_ptr, preview_ptr, options.raw())
45 });
46
47 if should_render {
48 Some(ComboBoxToken::new(self))
49 } else {
50 None
51 }
52 }
53
54 #[must_use]
61 #[doc(alias = "BeginCombo")]
62 pub fn begin_combo_no_preview(&self, label: impl AsRef<str>) -> Option<ComboBoxToken<'_>> {
63 self.begin_combo_no_preview_with_flags(label, ComboBoxFlags::NONE)
64 }
65
66 #[must_use]
73 #[doc(alias = "BeginCombo")]
74 pub fn begin_combo_no_preview_with_flags(
75 &self,
76 label: impl AsRef<str>,
77 flags: impl Into<ComboBoxOptions>,
78 ) -> Option<ComboBoxToken<'_>> {
79 let mut options = flags.into();
80 options.preview_mode = ComboBoxPreviewMode::NoPreview;
81 options.validate("Ui::begin_combo_no_preview_with_flags()");
82 let label_ptr = self.scratch_txt(label);
83
84 let should_render = self.run_with_bound_context(|| unsafe {
85 sys::igBeginCombo(label_ptr, std::ptr::null(), options.raw())
86 });
87
88 if should_render {
89 Some(ComboBoxToken::new(self))
90 } else {
91 None
92 }
93 }
94
95 #[doc(alias = "Combo")]
97 pub fn combo<V, L>(
98 &self,
99 label: impl AsRef<str>,
100 current_item: &mut usize,
101 items: &[V],
102 label_fn: L,
103 ) -> bool
104 where
105 for<'b> L: Fn(&'b V) -> Cow<'b, str>,
106 {
107 let label_fn = &label_fn;
108 let mut result = false;
109 let preview_value = items.get(*current_item).map(label_fn);
110
111 if let Some(combo_token) = self.begin_combo(
112 label,
113 preview_value.as_ref().map(|s| s.as_ref()).unwrap_or(""),
114 ) {
115 for (idx, item) in items.iter().enumerate() {
116 let is_selected = idx == *current_item;
117 let clicked = self
118 .selectable_config(label_fn(item).as_ref())
119 .selected(is_selected)
120 .build();
121 if is_selected {
122 self.set_item_default_focus();
123 }
124
125 if clicked {
126 *current_item = idx;
127 result = true;
128 }
129 }
130 combo_token.end();
131 }
132
133 result
134 }
135
136 #[doc(alias = "Combo")]
141 pub fn combo_i32<V, L>(
142 &self,
143 label: impl AsRef<str>,
144 current_item: &mut i32,
145 items: &[V],
146 label_fn: L,
147 ) -> bool
148 where
149 for<'b> L: Fn(&'b V) -> Cow<'b, str>,
150 {
151 let label_fn = &label_fn;
152 let mut result = false;
153
154 let preview_value = if *current_item >= 0 {
155 items.get(*current_item as usize).map(|v| label_fn(v))
156 } else {
157 None
158 };
159
160 if let Some(combo_token) = self.begin_combo(
161 label,
162 preview_value.as_ref().map(|s| s.as_ref()).unwrap_or(""),
163 ) {
164 for (idx, item) in items.iter().enumerate() {
165 if idx > i32::MAX as usize {
166 break;
167 }
168 let idx_i32 = idx as i32;
169 let is_selected = idx_i32 == *current_item;
170 let clicked = self
171 .selectable_config(label_fn(item).as_ref())
172 .selected(is_selected)
173 .build();
174 if is_selected {
175 self.set_item_default_focus();
176 }
177 if clicked {
178 *current_item = idx_i32;
179 result = true;
180 }
181 }
182 combo_token.end();
183 }
184
185 result
186 }
187
188 #[doc(alias = "Combo")]
190 pub fn combo_simple_string(
191 &self,
192 label: impl AsRef<str>,
193 current_item: &mut usize,
194 items: &[impl AsRef<str>],
195 ) -> bool {
196 self.combo(label, current_item, items, |s| Cow::Borrowed(s.as_ref()))
197 }
198
199 #[doc(alias = "Combo")]
201 pub fn combo_simple_string_i32(
202 &self,
203 label: impl AsRef<str>,
204 current_item: &mut i32,
205 items: &[impl AsRef<str>],
206 ) -> bool {
207 self.combo_i32(label, current_item, items, |s| Cow::Borrowed(s.as_ref()))
208 }
209
210 #[doc(alias = "SetItemDefaultFocus")]
212 pub fn set_item_default_focus(&self) {
213 self.run_with_bound_context(|| unsafe { sys::igSetItemDefaultFocus() });
214 }
215}