Update ID stack manipulation to use stack tokens

This commit is contained in:
Joonas Javanainen 2019-07-13 00:17:55 +03:00
parent 54853f4114
commit c71c1ea22d
No known key found for this signature in database
GPG Key ID: D39CCA5CB19B9179
4 changed files with 60 additions and 54 deletions

View File

@ -17,6 +17,7 @@
- Glium renderer re-exports imgui and glium - Glium renderer re-exports imgui and glium
- Gfx renderer re-exports imgui and gfx - Gfx renderer re-exports imgui and gfx
- These functions now take/return PathBuf: log_filename, set_log_filename, ini_filename, set_logfilename - These functions now take/return PathBuf: log_filename, set_log_filename, ini_filename, set_logfilename
- ID stack manipulation now uses stack tokens
### Removed ### Removed

View File

@ -6,7 +6,7 @@ use crate::string::ImStr;
use crate::widget::color_editors::*; use crate::widget::color_editors::*;
use crate::widget::progress_bar::ProgressBar; use crate::widget::progress_bar::ProgressBar;
use crate::window::{Window, WindowFlags}; use crate::window::{Window, WindowFlags};
use crate::Ui; use crate::{Id, Ui};
#[deprecated(since = "0.2.0", note = "use ColorEditFlags instead")] #[deprecated(since = "0.2.0", note = "use ColorEditFlags instead")]
pub type ImGuiColorEditFlags = ColorEditFlags; pub type ImGuiColorEditFlags = ColorEditFlags;
@ -370,3 +370,15 @@ impl<'ui> Ui<'ui> {
unsafe { sys::igGetColumnsCount() } 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<Id<'a>>,
{
let _token = self.push_id(id);
f();
}
}

View File

@ -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), Int(i32),
Str(&'a str), Str(&'a str),
Ptr(*const c_void), Ptr(*const c_void),
} }
impl From<i32> for ImId<'static> { impl From<i32> for Id<'static> {
fn from(i: i32) -> Self { fn from(i: i32) -> Self {
ImId::Int(i) Id::Int(i)
} }
} }
impl<'a, T: ?Sized + AsRef<str>> From<&'a T> for ImId<'a> { impl<'a, T: ?Sized + AsRef<str>> From<&'a T> for Id<'a> {
fn from(s: &'a T) -> Self { fn from(s: &'a T) -> Self {
ImId::Str(s.as_ref()) Id::Str(s.as_ref())
} }
} }
impl<T> From<*const T> for ImId<'static> { impl<T> From<*const T> for Id<'static> {
fn from(p: *const T) -> Self { fn from(p: *const T) -> Self {
ImId::Ptr(p as *const c_void) Id::Ptr(p as *const c_void)
} }
} }
impl<T> From<*mut T> for ImId<'static> { impl<T> From<*mut T> for Id<'static> {
fn from(p: *mut T) -> Self { fn from(p: *mut T) -> Self {
ImId::Ptr(p as *const T as *const c_void) Id::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<ImId<'a>>>(&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<ImId<'a>>,
{
self.push_id(id);
f();
self.pop_id();
} }
} }

View File

@ -1,11 +1,12 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem; use std::mem;
use std::os::raw::{c_char, c_void};
use crate::fonts::atlas::FontId; use crate::fonts::atlas::FontId;
use crate::internal::RawCast; use crate::internal::RawCast;
use crate::style::{StyleColor, StyleVar}; use crate::style::{StyleColor, StyleVar};
use crate::sys; use crate::sys;
use crate::Ui; use crate::{Id, Ui};
/// # Parameter stacks (shared) /// # Parameter stacks (shared)
impl<'ui> Ui<'ui> { 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<Id<'a>>>(&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() };
}
}