mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-11 05:28:35 +00:00
transmogrified the Id struct
This commit is contained in:
parent
203780c884
commit
074c40e927
@ -10,6 +10,8 @@
|
||||
|
||||
- BREAKING: `SharedFontAtlas` now hides an `Rc` within its wrapper -- this simplifies the codebase and more accurately reflects how we expect `SharedFontAtlas` to be used (ie, you're probably going to set it up once, and then give it around, rather than constantly edit it). `SharedFontAtlas` users, if this change is very bad for you, please let us know with issues!
|
||||
|
||||
- BREAKING: `Id` is now a simpler facade, but requires the `Ui` struct to generate. `push_id`, equally, has been split into multiple functions for simplicity.
|
||||
|
||||
## [0.8.0] - 2021-09-17
|
||||
|
||||
Welcome to the `0.8.0` update. This is one of the largest updates imgui-rs has ever seen; it will generate errors in a `0.7` project, but hopefully it should be both quick to fix, and enjoyable to update. See our [release page](https://github.com/imgui-rs/imgui-rs/releases/tag/v0.8.0) for more information and a list of contributors to this cycle. Thank you to everyone who uses `imgui-rs`, files issues, and spend their time and effort to PR new changes into the codebase. Because of all that effort, this is by far the best `imgui-rs` has looked!
|
||||
|
||||
@ -33,7 +33,7 @@ fn main() {
|
||||
let _label_id = ui.push_id(it);
|
||||
ui.text(it);
|
||||
for num in 0..5 {
|
||||
let _num_id = ui.push_id(num);
|
||||
let _num_id = ui.push_id_usize(num);
|
||||
ui.same_line();
|
||||
if ui.button("Example") {
|
||||
println!("{}: {}", it, num);
|
||||
|
||||
165
imgui/src/lib.rs
165
imgui/src/lib.rs
@ -5,7 +5,7 @@
|
||||
pub extern crate imgui_sys as sys;
|
||||
|
||||
use std::cell;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
use std::os::raw::c_char;
|
||||
|
||||
pub use self::clipboard::*;
|
||||
pub use self::color::ImColor32;
|
||||
@ -269,69 +269,124 @@ impl Ui {
|
||||
}
|
||||
}
|
||||
|
||||
/// Unique ID used by widgets
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Id<'a> {
|
||||
Int(i32),
|
||||
Str(&'a str),
|
||||
Ptr(*const c_void),
|
||||
}
|
||||
/// Unique ID used by widgets.
|
||||
///
|
||||
/// This represents a hash of the current stack of Ids used in ImGui + the
|
||||
/// input provided. It is only used in a few places directly in the
|
||||
/// codebase, but you can think of it as effectively allowing you to
|
||||
/// run your Id hashing yourself.
|
||||
///
|
||||
/// Previously, this was erroneously constructed with `From` implementations.
|
||||
/// Now, however, it is made from the `Ui` object directly, with a few
|
||||
/// deprecated helper methods here.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
|
||||
pub struct Id(pub(crate) u32);
|
||||
|
||||
impl From<i32> for Id<'static> {
|
||||
#[inline]
|
||||
fn from(i: i32) -> Self {
|
||||
Id::Int(i)
|
||||
impl Id {
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Int(input: i32, ui: &Ui) -> Self {
|
||||
ui.new_id_int(input)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Str(input: impl AsRef<str>, ui: &Ui) -> Self {
|
||||
ui.new_id_str(input)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Ptr<T>(input: &T, ui: &Ui) -> Self {
|
||||
ui.new_id_ptr(input)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized + AsRef<str>> From<&'a T> for Id<'a> {
|
||||
#[inline]
|
||||
fn from(s: &'a T) -> Self {
|
||||
Id::Str(s.as_ref())
|
||||
impl Ui {
|
||||
pub fn new_id(&self, input: usize) -> Id {
|
||||
let p = input as *const std::os::raw::c_void;
|
||||
let value = unsafe { sys::igGetID_Ptr(p) };
|
||||
|
||||
Id(value)
|
||||
}
|
||||
|
||||
pub fn new_id_int(&self, input: i32) -> Id {
|
||||
let p = input as *const std::os::raw::c_void;
|
||||
let value = unsafe { sys::igGetID_Ptr(p) };
|
||||
Id(value)
|
||||
}
|
||||
|
||||
pub fn new_id_ptr<T>(&self, input: &T) -> Id {
|
||||
let p = input as *const T as *const sys::cty::c_void;
|
||||
let value = unsafe { sys::igGetID_Ptr(p) };
|
||||
Id(value)
|
||||
}
|
||||
|
||||
pub fn new_id_str(&self, s: impl AsRef<str>) -> Id {
|
||||
let s = s.as_ref();
|
||||
|
||||
let s1 = s.as_ptr() as *const std::os::raw::c_char;
|
||||
let value = unsafe {
|
||||
let s2 = s1.add(s.len());
|
||||
sys::igGetID_StrStr(s1, s2)
|
||||
};
|
||||
Id(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<*const T> for Id<'static> {
|
||||
#[inline]
|
||||
fn from(p: *const T) -> Self {
|
||||
Id::Ptr(p as *const c_void)
|
||||
}
|
||||
}
|
||||
// /// Unique ID used by widgets
|
||||
// pub enum Id<'a> {
|
||||
// Int(i32),
|
||||
// Str(&'a str),
|
||||
// Ptr(*const c_void),
|
||||
// }
|
||||
|
||||
impl<T> From<*mut T> for Id<'static> {
|
||||
#[inline]
|
||||
fn from(p: *mut T) -> Self {
|
||||
Id::Ptr(p as *const T as *const c_void)
|
||||
}
|
||||
}
|
||||
// impl From<i32> for Id<'static> {
|
||||
// #[inline]
|
||||
// fn from(i: i32) -> Self {
|
||||
// Id::Int(i)
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<'a> Id<'a> {
|
||||
// this is used in the tables-api and possibly elsewhere,
|
||||
// but not with just default features...
|
||||
#[allow(dead_code)]
|
||||
fn as_imgui_id(&self) -> sys::ImGuiID {
|
||||
unsafe {
|
||||
match self {
|
||||
Id::Ptr(p) => sys::igGetID_Ptr(*p),
|
||||
Id::Str(s) => {
|
||||
let s1 = s.as_ptr() as *const std::os::raw::c_char;
|
||||
let s2 = s1.add(s.len());
|
||||
sys::igGetID_StrStr(s1, s2)
|
||||
}
|
||||
Id::Int(i) => {
|
||||
let p = *i as *const std::os::raw::c_void;
|
||||
sys::igGetID_Ptr(p)
|
||||
} // Id::ImGuiID(n) => *n,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// impl<'a, T: ?Sized + AsRef<str>> From<&'a T> for Id<'a> {
|
||||
// #[inline]
|
||||
// fn from(s: &'a T) -> Self {
|
||||
// Id::Str(s.as_ref())
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<'a> Default for Id<'a> {
|
||||
fn default() -> Self {
|
||||
Self::Int(0)
|
||||
}
|
||||
}
|
||||
// impl<T> From<*const T> for Id<'static> {
|
||||
// #[inline]
|
||||
// fn from(p: *const T) -> Self {
|
||||
// Id::Ptr(p as *const c_void)
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl<T> From<*mut T> for Id<'static> {
|
||||
// #[inline]
|
||||
// fn from(p: *mut T) -> Self {
|
||||
// Id::Ptr(p as *const T as *const c_void)
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl<'a> Id<'a> {
|
||||
// // this is used in the tables-api and possibly elsewhere,
|
||||
// // but not with just default features...
|
||||
// #[allow(dead_code)]
|
||||
// fn as_imgui_id(&self) -> sys::ImGuiID {
|
||||
// unsafe {
|
||||
// match self {
|
||||
// Id::Ptr(p) => sys::igGetID_Ptr(*p),
|
||||
// Id::Str(s) => {
|
||||
// let s1 = s.as_ptr() as *const std::os::raw::c_char;
|
||||
// let s2 = s1.add(s.len());
|
||||
// sys::igGetID_StrStr(s1, s2)
|
||||
// }
|
||||
// Id::Int(i) => {
|
||||
// let p = *i as *const std::os::raw::c_void;
|
||||
// sys::igGetID_Ptr(p)
|
||||
// } // Id::ImGuiID(n) => *n,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
impl Ui {
|
||||
/// # Windows
|
||||
@ -390,7 +445,7 @@ impl Ui {
|
||||
///
|
||||
/// Use child windows to begin into a self-contained independent scrolling/clipping
|
||||
/// regions within a host window. Child windows can embed their own child.
|
||||
pub fn child_window_id(&self, id: Id<'_>) -> ChildWindow<'_> {
|
||||
pub fn child_window_id(&self, id: Id) -> ChildWindow<'_> {
|
||||
ChildWindow::new_id(self, id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,9 +3,9 @@ use crate::internal::RawCast;
|
||||
use crate::math::MintVec4;
|
||||
use crate::style::{StyleColor, StyleVar};
|
||||
use crate::sys;
|
||||
use crate::{Id, Ui};
|
||||
use crate::Ui;
|
||||
use std::mem;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
use std::os::raw::c_char;
|
||||
|
||||
/// # Parameter stacks (shared)
|
||||
impl Ui {
|
||||
@ -386,7 +386,6 @@ impl IdStackToken<'_> {
|
||||
/// # ID stack
|
||||
impl<'ui> Ui {
|
||||
/// Pushes an identifier to the ID stack.
|
||||
/// This can be called with an integer, a string, or a pointer.
|
||||
///
|
||||
/// Returns an `IdStackToken` that can be popped by calling `.end()`
|
||||
/// or by dropping manually.
|
||||
@ -462,20 +461,55 @@ impl<'ui> Ui {
|
||||
/// });
|
||||
/// ```
|
||||
#[doc(alias = "PushId")]
|
||||
pub fn push_id<'a, I: Into<Id<'a>>>(&'ui self, id: I) -> IdStackToken<'ui> {
|
||||
let id = id.into();
|
||||
|
||||
pub fn push_id(&self, s: impl AsRef<str>) -> IdStackToken<'_> {
|
||||
unsafe {
|
||||
match id {
|
||||
Id::Int(i) => sys::igPushID_Int(i),
|
||||
Id::Str(s) => {
|
||||
let start = s.as_ptr() as *const c_char;
|
||||
let end = start.add(s.len());
|
||||
sys::igPushID_StrStr(start, end)
|
||||
}
|
||||
Id::Ptr(p) => sys::igPushID_Ptr(p as *const c_void),
|
||||
}
|
||||
let s = s.as_ref();
|
||||
let start = s.as_ptr() as *const c_char;
|
||||
let end = start.add(s.len());
|
||||
sys::igPushID_StrStr(start, end)
|
||||
}
|
||||
IdStackToken::new(self)
|
||||
}
|
||||
|
||||
/// Pushes a `usize` to the ID stack.
|
||||
///
|
||||
/// Returns an `IdStackToken` that can be popped by calling `.end()`
|
||||
/// or by dropping manually.
|
||||
///
|
||||
/// See [push_id] for more information.
|
||||
///
|
||||
/// [push_id]: Self::push_id
|
||||
#[doc(alias = "PushId")]
|
||||
pub fn push_id_usize(&self, id: usize) -> IdStackToken<'_> {
|
||||
unsafe { sys::igPushID_Ptr(id as *const _) }
|
||||
IdStackToken::new(self)
|
||||
}
|
||||
|
||||
/// Pushes an `i32` to the ID stack.
|
||||
///
|
||||
/// Returns an `IdStackToken` that can be popped by calling `.end()`
|
||||
/// or by dropping manually.
|
||||
///
|
||||
/// See [push_id] for more information.
|
||||
///
|
||||
/// [push_id]: Self::push_id
|
||||
#[doc(alias = "PushId")]
|
||||
pub fn push_id_int(&self, id: i32) -> IdStackToken<'_> {
|
||||
unsafe { sys::igPushID_Int(id) }
|
||||
IdStackToken::new(self)
|
||||
}
|
||||
|
||||
/// Pushes a `ptr` to the ID stack.
|
||||
///
|
||||
/// Returns an `IdStackToken` that can be popped by calling `.end()`
|
||||
/// or by dropping manually.
|
||||
///
|
||||
/// See [push_id] for more information.
|
||||
///
|
||||
/// [push_id]: Self::push_id
|
||||
#[doc(alias = "PushId")]
|
||||
pub fn push_id_ptr<T>(&self, value: &T) -> IdStackToken<'_> {
|
||||
unsafe { sys::igPushID_Ptr(value as *const T as *const _) }
|
||||
IdStackToken::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,10 +320,10 @@ impl Ui {
|
||||
/// Takes an array of table header information, the length of which determines
|
||||
/// how many columns will be created.
|
||||
#[must_use = "if return is dropped immediately, table is ended immediately."]
|
||||
pub fn begin_table_header<'a, Name: AsRef<str>, const N: usize>(
|
||||
pub fn begin_table_header<Name: AsRef<str>, const N: usize>(
|
||||
&self,
|
||||
str_id: impl AsRef<str>,
|
||||
column_data: [TableColumnSetup<'a, Name>; N],
|
||||
column_data: [TableColumnSetup<Name>; N],
|
||||
) -> Option<TableToken<'_>> {
|
||||
self.begin_table_header_with_flags(str_id, column_data, TableFlags::empty())
|
||||
}
|
||||
@ -333,10 +333,10 @@ impl Ui {
|
||||
/// Takes an array of table header information, the length of which determines
|
||||
/// how many columns will be created.
|
||||
#[must_use = "if return is dropped immediately, table is ended immediately."]
|
||||
pub fn begin_table_header_with_flags<'a, Name: AsRef<str>, const N: usize>(
|
||||
pub fn begin_table_header_with_flags<Name: AsRef<str>, const N: usize>(
|
||||
&self,
|
||||
str_id: impl AsRef<str>,
|
||||
column_data: [TableColumnSetup<'a, Name>; N],
|
||||
column_data: [TableColumnSetup<Name>; N],
|
||||
flags: TableFlags,
|
||||
) -> Option<TableToken<'_>> {
|
||||
self.begin_table_header_with_sizing(str_id, column_data, flags, [0.0, 0.0], 0.0)
|
||||
@ -347,10 +347,10 @@ impl Ui {
|
||||
/// Takes an array of table header information, the length of which determines
|
||||
/// how many columns will be created.
|
||||
#[must_use = "if return is dropped immediately, table is ended immediately."]
|
||||
pub fn begin_table_header_with_sizing<'a, Name: AsRef<str>, const N: usize>(
|
||||
pub fn begin_table_header_with_sizing<Name: AsRef<str>, const N: usize>(
|
||||
&self,
|
||||
str_id: impl AsRef<str>,
|
||||
column_data: [TableColumnSetup<'a, Name>; N],
|
||||
column_data: [TableColumnSetup<Name>; N],
|
||||
flags: TableFlags,
|
||||
outer_size: [f32; 2],
|
||||
inner_width: f32,
|
||||
@ -533,13 +533,13 @@ impl Ui {
|
||||
/// row and automatically submit a table header for each column.
|
||||
/// Headers are required to perform: reordering, sorting, and opening the context menu (though,
|
||||
/// the context menu can also be made available in columns body using [TableFlags::CONTEXT_MENU_IN_BODY].
|
||||
pub fn table_setup_column_with<N: AsRef<str>>(&self, data: TableColumnSetup<'_, N>) {
|
||||
pub fn table_setup_column_with<N: AsRef<str>>(&self, data: TableColumnSetup<N>) {
|
||||
unsafe {
|
||||
sys::igTableSetupColumn(
|
||||
self.scratch_txt(data.name),
|
||||
data.flags.bits() as i32,
|
||||
data.init_width_or_weight,
|
||||
data.user_id.as_imgui_id(),
|
||||
data.user_id.0,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -733,7 +733,7 @@ impl Ui {
|
||||
/// A struct containing all the data needed to setup a table column header
|
||||
/// via [begin_table_header](Ui::begin_table_header) or [table_setup_column](Ui::table_setup_column).
|
||||
#[derive(Debug, Default)]
|
||||
pub struct TableColumnSetup<'a, Name> {
|
||||
pub struct TableColumnSetup<Name> {
|
||||
/// The name of column to be displayed to users.
|
||||
pub name: Name,
|
||||
/// The flags this column will have.
|
||||
@ -741,16 +741,16 @@ pub struct TableColumnSetup<'a, Name> {
|
||||
/// The width or weight of the given column.
|
||||
pub init_width_or_weight: f32,
|
||||
/// A user_id, primarily used in sorting operations.
|
||||
pub user_id: Id<'a>,
|
||||
pub user_id: Id,
|
||||
}
|
||||
|
||||
impl<'a, Name: AsRef<str>> TableColumnSetup<'a, Name> {
|
||||
impl<'a, Name: AsRef<str>> TableColumnSetup<Name> {
|
||||
pub fn new(name: Name) -> Self {
|
||||
Self {
|
||||
name,
|
||||
flags: TableColumnFlags::empty(),
|
||||
init_width_or_weight: 0.0,
|
||||
user_id: Id::Int(0),
|
||||
user_id: Id::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,16 +23,16 @@ impl<'ui> ChildWindow<'ui> {
|
||||
/// Creates a new child window builder with the str.
|
||||
#[doc(alias = "BeginChildID")]
|
||||
pub fn new(ui: &'ui Ui, name: impl AsRef<str>) -> Self {
|
||||
let id = Id::Str(name.as_ref());
|
||||
let id = ui.new_id_str(name);
|
||||
Self::new_id(ui, id)
|
||||
}
|
||||
|
||||
/// Creates a new child window builder with the given imgui id.
|
||||
#[doc(alias = "BeginChildID")]
|
||||
pub fn new_id(ui: &'ui Ui, id: Id<'_>) -> Self {
|
||||
pub fn new_id(ui: &'ui Ui, id: Id) -> Self {
|
||||
Self {
|
||||
ui,
|
||||
id: id.as_imgui_id(),
|
||||
id: id.0,
|
||||
flags: WindowFlags::empty(),
|
||||
size: [0.0, 0.0],
|
||||
content_size: [0.0, 0.0],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user