diff --git a/imgui-examples/examples/test_window_impl.rs b/imgui-examples/examples/test_window_impl.rs index 867b848..211a699 100644 --- a/imgui-examples/examples/test_window_impl.rs +++ b/imgui-examples/examples/test_window_impl.rs @@ -480,7 +480,7 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) { ui.separator(); ui.label_text(im_str!("label"), im_str!("Value")); - ComboBox::new(im_str!("combo")).build_simple_string(ui, + ComboBox::new(&"combo").build_simple_string(ui, &mut state.item, &[ im_str!("aaaa"), @@ -515,7 +515,7 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) { im_str!("Tilefish"), ]; - ListBox::new(im_str!("selectables list")).build(ui, || { + ListBox::new("selectables list").build(ui, || { for (index, name) in names.iter().enumerate() { let selected = matches!(state.selected_fish2, Some(i) if i == index ); if Selectable::new(name).selected(selected).build(ui) { diff --git a/imgui/src/widget/combo_box.rs b/imgui/src/widget/combo_box.rs index a412fc5..e321f83 100644 --- a/imgui/src/widget/combo_box.rs +++ b/imgui/src/widget/combo_box.rs @@ -1,6 +1,5 @@ use bitflags::bitflags; use std::borrow::Cow; -use std::ptr; use crate::sys; use crate::Ui; @@ -55,16 +54,16 @@ pub struct ComboBoxFlags: u32 { /// Builder for a combo box widget #[derive(Copy, Clone, Debug)] #[must_use] -pub struct ComboBox<'a> { - label: &'a ImStr, - preview_value: Option<&'a ImStr>, +pub struct ComboBox { + label: T, + preview_value: Option

, flags: ComboBoxFlags, } -impl<'a> ComboBox<'a> { +impl<'a, T: AsRef, P: AsRef> ComboBox { /// Constructs a new combo box builder. #[doc(alias = "BeginCombo")] - pub const fn new(label: &'a ImStr) -> ComboBox<'a> { + pub fn new(label: T) -> Self { ComboBox { label, preview_value: None, @@ -74,14 +73,14 @@ impl<'a> ComboBox<'a> { /// Sets the preview value displayed in the preview box (if visible). #[inline] - pub const fn preview_value(mut self, preview_value: &'a ImStr) -> Self { + pub fn preview_value(mut self, preview_value: P) -> Self { self.preview_value = Some(preview_value); self } /// Replaces all current settings with the given flags. #[inline] - pub const fn flags(mut self, flags: ComboBoxFlags) -> Self { + pub fn flags(mut self, flags: ComboBoxFlags) -> Self { self.flags = flags; self } @@ -141,11 +140,13 @@ impl<'a> ComboBox<'a> { #[must_use] pub fn begin<'ui>(self, ui: &Ui<'ui>) -> Option> { let should_render = unsafe { - sys::igBeginCombo( - self.label.as_ptr(), - self.preview_value.map(ImStr::as_ptr).unwrap_or(ptr::null()), - self.flags.bits() as i32, - ) + if let Some(preview_value) = self.preview_value { + let (ptr_one, ptr_two) = ui.scratch_txt_two(self.label, preview_value); + sys::igBeginCombo(ptr_one, ptr_two, self.flags.bits() as i32) + } else { + let ptr_one = ui.scratch_txt(self.label); + sys::igBeginCombo(ptr_one, std::ptr::null(), self.flags.bits() as i32) + } }; if should_render { Some(ComboBoxToken::new(ui)) @@ -157,7 +158,7 @@ impl<'a> ComboBox<'a> { /// Returns the result of the closure, if it is called. /// /// Note: the closure is not called if the combo box is not open. - pub fn build T>(self, ui: &Ui, f: F) -> Option { + pub fn build R>(self, ui: &Ui, f: F) -> Option { self.begin(ui).map(|_combo| f()) } } @@ -172,29 +173,28 @@ create_token!( ); /// # Convenience functions -impl<'a> ComboBox<'a> { +impl<'a, T: AsRef + Clone> ComboBox> { /// Builds a simple combo box for choosing from a slice of values #[doc(alias = "BeginCombo")] - pub fn build_simple( - self, + pub fn build_simple( + mut self, ui: &Ui, current_item: &mut usize, - items: &[T], + items: &'a [V], label_fn: &L, ) -> bool where - for<'b> L: Fn(&'b T) -> Cow<'b, ImStr>, + for<'b> L: Fn(&'b V) -> Cow<'b, str>, { use crate::widget::selectable::Selectable; let mut result = false; - let mut cb = self; let preview_value = items.get(*current_item).map(label_fn); - if cb.preview_value.is_none() { - if let Some(preview_value) = preview_value.as_ref() { - cb = cb.preview_value(preview_value); + if self.preview_value.is_none() { + if let Some(preview_value) = preview_value { + self = self.preview_value(preview_value); } } - if let Some(_cb) = cb.begin(ui) { + if let Some(_cb) = self.begin(ui) { for (idx, item) in items.iter().enumerate() { let text = label_fn(item); let selected = idx == *current_item; @@ -213,7 +213,7 @@ impl<'a> ComboBox<'a> { #[doc(alias = "BeginCombo")] pub fn build_simple_string(self, ui: &Ui, current_item: &mut usize, items: &[&S]) -> bool where - S: AsRef + ?Sized, + S: AsRef + ?Sized, { self.build_simple(ui, current_item, items, &|&s| s.as_ref().into()) } diff --git a/imgui/src/widget/list_box.rs b/imgui/src/widget/list_box.rs index 60482f9..70fbce5 100644 --- a/imgui/src/widget/list_box.rs +++ b/imgui/src/widget/list_box.rs @@ -1,21 +1,20 @@ use std::borrow::Cow; -use crate::string::ImStr; use crate::sys; use crate::Ui; /// Builder for a list box widget #[derive(Copy, Clone, Debug)] #[must_use] -pub struct ListBox<'a> { - label: &'a ImStr, +pub struct ListBox { + label: T, size: sys::ImVec2, } -impl<'a> ListBox<'a> { +impl> ListBox { /// Constructs a new list box builder. #[doc(alias = "ListBoxHeaderVec2", alias = "ListBoxHeaderInt")] - pub const fn new(label: &'a ImStr) -> ListBox<'a> { + pub fn new(label: T) -> ListBox { ListBox { label, size: sys::ImVec2::zero(), @@ -29,7 +28,7 @@ impl<'a> ListBox<'a> { /// /// Default: [0.0, 0.0], in which case the combobox calculates a sensible width and height #[inline] - pub const fn size(mut self, size: [f32; 2]) -> Self { + pub fn size(mut self, size: [f32; 2]) -> Self { self.size = sys::ImVec2::new(size[0], size[1]); self } @@ -41,7 +40,7 @@ impl<'a> ListBox<'a> { /// Returns `None` if the list box is not open and no content should be rendered. #[must_use] pub fn begin<'ui>(self, ui: &Ui<'ui>) -> Option> { - let should_render = unsafe { sys::igBeginListBox(self.label.as_ptr(), self.size) }; + let should_render = unsafe { sys::igBeginListBox(ui.scratch_txt(self.label), self.size) }; if should_render { Some(ListBoxToken::new(ui)) } else { @@ -52,7 +51,7 @@ impl<'a> ListBox<'a> { /// Returns the result of the closure, if it is called. /// /// Note: the closure is not called if the list box is not open. - pub fn build T>(self, ui: &Ui<'_>, f: F) -> Option { + pub fn build R>(self, ui: &Ui<'_>, f: F) -> Option { self.begin(ui).map(|_list| f()) } } @@ -67,17 +66,17 @@ create_token!( ); /// # Convenience functions -impl<'a> ListBox<'a> { +impl> ListBox { /// Builds a simple list box for choosing from a slice of values - pub fn build_simple( + pub fn build_simple( self, ui: &Ui, current_item: &mut usize, - items: &[T], + items: &[V], label_fn: &L, ) -> bool where - for<'b> L: Fn(&'b T) -> Cow<'b, ImStr>, + for<'b> L: Fn(&'b V) -> Cow<'b, str>, { use crate::widget::selectable::Selectable; let mut result = false; diff --git a/imgui/src/widget/selectable.rs b/imgui/src/widget/selectable.rs index 398fe37..83fd455 100644 --- a/imgui/src/widget/selectable.rs +++ b/imgui/src/widget/selectable.rs @@ -1,6 +1,5 @@ use bitflags::bitflags; -use crate::string::ImStr; use crate::sys; use crate::Ui; @@ -25,7 +24,7 @@ bitflags!( #[derive(Copy, Clone, Debug)] #[must_use] pub struct Selectable<'a> { - label: &'a ImStr, + label: &'a str, selected: bool, flags: SelectableFlags, size: [f32; 2], @@ -35,9 +34,9 @@ impl<'a> Selectable<'a> { /// Constructs a new selectable builder. #[inline] #[doc(alias = "Selectable")] - pub const fn new(label: &ImStr) -> Selectable { + pub fn new(label: &'a impl AsRef) -> Selectable<'a> { Selectable { - label, + label: label.as_ref(), selected: false, flags: SelectableFlags::empty(), size: [0.0, 0.0], @@ -108,10 +107,10 @@ impl<'a> Selectable<'a> { /// Builds the selectable. /// /// Returns true if the selectable was clicked. - pub fn build(self, _: &Ui) -> bool { + pub fn build(self, ui: &Ui) -> bool { unsafe { sys::igSelectableBool( - self.label.as_ptr(), + ui.scratch_txt(self.label), self.selected, self.flags.bits() as i32, self.size.into(),