diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 14d3031..b12abda 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -17,6 +17,7 @@ - Glium renderer re-exports imgui and glium - Gfx renderer re-exports imgui and gfx - These functions now take/return PathBuf: log_filename, set_log_filename, ini_filename, set_logfilename +- ID stack manipulation now uses stack tokens ### Removed diff --git a/src/legacy.rs b/src/legacy.rs index a387c82..e67e106 100644 --- a/src/legacy.rs +++ b/src/legacy.rs @@ -6,7 +6,7 @@ use crate::string::ImStr; use crate::widget::color_editors::*; use crate::widget::progress_bar::ProgressBar; use crate::window::{Window, WindowFlags}; -use crate::Ui; +use crate::{Id, Ui}; #[deprecated(since = "0.2.0", note = "use ColorEditFlags instead")] pub type ImGuiColorEditFlags = ColorEditFlags; @@ -370,3 +370,15 @@ impl<'ui> Ui<'ui> { unsafe { sys::igGetColumnsCount() } } } + +impl<'ui> Ui<'ui> { + #[deprecated(since = "0.2.0", note = "use Ui::push_id instead")] + pub fn with_id<'a, F, I>(&self, id: I, f: F) + where + F: FnOnce(), + I: Into>, + { + let _token = self.push_id(id); + f(); + } +} diff --git a/src/lib.rs b/src/lib.rs index 14e493e..561229f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -205,76 +205,35 @@ impl<'ui> Ui<'ui> { } } -pub enum ImId<'a> { +/// Unique ID used by widgets +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum Id<'a> { Int(i32), Str(&'a str), Ptr(*const c_void), } -impl From for ImId<'static> { +impl From for Id<'static> { fn from(i: i32) -> Self { - ImId::Int(i) + Id::Int(i) } } -impl<'a, T: ?Sized + AsRef> From<&'a T> for ImId<'a> { +impl<'a, T: ?Sized + AsRef> From<&'a T> for Id<'a> { fn from(s: &'a T) -> Self { - ImId::Str(s.as_ref()) + Id::Str(s.as_ref()) } } -impl From<*const T> for ImId<'static> { +impl From<*const T> for Id<'static> { fn from(p: *const T) -> Self { - ImId::Ptr(p as *const c_void) + Id::Ptr(p as *const c_void) } } -impl From<*mut T> for ImId<'static> { +impl From<*mut T> for Id<'static> { fn from(p: *mut T) -> Self { - ImId::Ptr(p as *const T as *const c_void) - } -} - -// ID scopes -impl<'ui> Ui<'ui> { - /// Pushes an identifier to the ID stack. - pub fn push_id<'a, I: Into>>(&self, id: I) { - let id = id.into(); - - unsafe { - match id { - ImId::Int(i) => { - sys::igPushIDInt(i); - } - ImId::Str(s) => { - let start = s.as_ptr() as *const c_char; - let end = start.add(s.len()); - sys::igPushIDRange(start, end); - } - ImId::Ptr(p) => { - sys::igPushIDPtr(p as *const c_void); - } - } - } - } - - /// Pops an identifier from the ID stack. - /// - /// # Aborts - /// The current process is aborted if the ID stack is empty. - pub fn pop_id(&self) { - unsafe { sys::igPopID() }; - } - - /// Runs a function after temporarily pushing a value to the ID stack. - pub fn with_id<'a, F, I>(&self, id: I, f: F) - where - F: FnOnce(), - I: Into>, - { - self.push_id(id); - f(); - self.pop_id(); + Id::Ptr(p as *const T as *const c_void) } } diff --git a/src/stacks.rs b/src/stacks.rs index f08de35..d0c59d1 100644 --- a/src/stacks.rs +++ b/src/stacks.rs @@ -1,11 +1,12 @@ use std::marker::PhantomData; use std::mem; +use std::os::raw::{c_char, c_void}; use crate::fonts::atlas::FontId; use crate::internal::RawCast; use crate::style::{StyleColor, StyleVar}; use crate::sys; -use crate::Ui; +use crate::{Id, Ui}; /// # Parameter stacks (shared) impl<'ui> Ui<'ui> { @@ -301,3 +302,36 @@ impl<'ui> Drop for ItemFlagsStackToken<'ui> { } } } + +/// # ID stack +impl<'ui> Ui<'ui> { + /// Pushes an identifier to the ID stack + #[must_use] + pub fn push_id<'a, I: Into>>(&self, id: I) -> IdStackToken { + let id = id.into(); + + unsafe { + match id { + Id::Int(i) => sys::igPushIDInt(i), + Id::Str(s) => { + let start = s.as_ptr() as *const c_char; + let end = start.add(s.len()); + sys::igPushIDRange(start, end) + } + Id::Ptr(p) => sys::igPushIDPtr(p as *const c_void), + } + } + IdStackToken { _ui: PhantomData } + } +} + +/// Represents a change pushed to the ID stack +pub struct IdStackToken<'ui> { + _ui: PhantomData<&'ui Ui<'ui>>, +} + +impl<'ui> Drop for IdStackToken<'ui> { + fn drop(&mut self) { + unsafe { sys::igPopID() }; + } +}