mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-11 21:48:36 +00:00
Pull string updates from 0.1
This commit is contained in:
parent
92de1588f2
commit
f7f9deb321
@ -371,7 +371,7 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
|
||||
if ui.collapsing_header(im_str!("Widgets")).build() {
|
||||
ui.tree_node(im_str!("Tree")).build(|| {
|
||||
for i in 0..5 {
|
||||
ui.tree_node(im_str!("Child {}", i)).build(|| {
|
||||
ui.tree_node(&im_str!("Child {}", i)).build(|| {
|
||||
ui.text(im_str!("blah blah"));
|
||||
ui.same_line(0.0);
|
||||
if ui.small_button(im_str!("print")) {
|
||||
@ -774,7 +774,7 @@ fn show_example_menu_file<'a>(ui: &Ui<'a>, state: &mut FileMenuState) {
|
||||
});
|
||||
ui.menu(im_str!("Colors")).build(|| {
|
||||
for &col in StyleColor::VARIANTS.iter() {
|
||||
ui.menu_item(im_str!("{:?}", col)).build();
|
||||
ui.menu_item(&im_str!("{:?}", col)).build();
|
||||
}
|
||||
});
|
||||
ui.menu(im_str!("Disabled")).enabled(false).build(|| {
|
||||
@ -849,7 +849,7 @@ My title is the same as window 1, but my identifier is unique.",
|
||||
let ch_idx = (ui.imgui().get_time() / 0.25) as usize & 3;
|
||||
let num = ui.imgui().get_frame_count(); // The C++ version uses rand() here
|
||||
let title = im_str!("Animated title {} {}###AnimatedTitle", chars[ch_idx], num);
|
||||
ui.window(title)
|
||||
ui.window(&title)
|
||||
.position((100.0, 300.0), Condition::FirstUseEver)
|
||||
.build(|| ui.text("This window has a changing title"));
|
||||
}
|
||||
|
||||
15
src/lib.rs
15
src/lib.rs
@ -70,21 +70,6 @@ pub struct ImGui {
|
||||
log_filename: Option<ImString>,
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! im_str {
|
||||
($e:tt) => ({
|
||||
unsafe {
|
||||
$crate::ImStr::from_utf8_with_nul_unchecked(concat!($e, "\0").as_bytes())
|
||||
}
|
||||
});
|
||||
($e:tt, $($arg:tt)*) => ({
|
||||
unsafe {
|
||||
&$crate::ImString::from_utf8_with_nul_unchecked(
|
||||
format!(concat!($e, "\0"), $($arg)*).into_bytes())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub struct TextureHandle<'a> {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
|
||||
@ -1,51 +1,83 @@
|
||||
use std::borrow::Borrow;
|
||||
use std::borrow::{Borrow, Cow};
|
||||
use std::ffi::CStr;
|
||||
use std::fmt;
|
||||
use std::ops::{Deref, Index, RangeFull};
|
||||
use std::os::raw::c_char;
|
||||
use std::str;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! im_str {
|
||||
($e:tt) => ({
|
||||
unsafe {
|
||||
$crate::ImStr::from_utf8_with_nul_unchecked(concat!($e, "\0").as_bytes())
|
||||
}
|
||||
});
|
||||
($e:tt, $($arg:tt)*) => ({
|
||||
unsafe {
|
||||
$crate::ImString::from_utf8_with_nul_unchecked(format!(concat!($e, "\0"), $($arg)*).into_bytes())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// A UTF-8 encoded, growable, implicitly null-terminated string.
|
||||
#[derive(Clone, Hash, Ord, Eq, PartialOrd, PartialEq)]
|
||||
pub struct ImString(pub(crate) Vec<u8>);
|
||||
|
||||
impl ImString {
|
||||
/// Creates a new `ImString` from an existing string.
|
||||
pub fn new<T: Into<String>>(value: T) -> ImString {
|
||||
unsafe { ImString::from_utf8_unchecked(value.into().into_bytes()) }
|
||||
}
|
||||
/// Creates a new empty `ImString` with a particular capacity
|
||||
pub fn with_capacity(capacity: usize) -> ImString {
|
||||
let mut v = Vec::with_capacity(capacity + 1);
|
||||
v.push(b'\0');
|
||||
ImString(v)
|
||||
}
|
||||
/// Converts a vector of bytes to a `ImString` without checking that the string contains valid
|
||||
/// UTF-8
|
||||
pub unsafe fn from_utf8_unchecked(mut v: Vec<u8>) -> ImString {
|
||||
v.push(b'\0');
|
||||
ImString(v)
|
||||
}
|
||||
/// Converts a vector of bytes to a `ImString` without checking that the string contains valid
|
||||
/// UTF-8
|
||||
pub unsafe fn from_utf8_with_nul_unchecked(v: Vec<u8>) -> ImString {
|
||||
ImString(v)
|
||||
}
|
||||
/// Truncates this `ImString`, removing all contents
|
||||
pub fn clear(&mut self) {
|
||||
self.0.clear();
|
||||
self.0.push(b'\0');
|
||||
}
|
||||
/// Appends the given character to the end of this `ImString`
|
||||
pub fn push(&mut self, ch: char) {
|
||||
let mut buf = [0; 4];
|
||||
self.push_str(ch.encode_utf8(&mut buf));
|
||||
}
|
||||
/// Appends a given string slice to the end of this `ImString`
|
||||
pub fn push_str(&mut self, string: &str) {
|
||||
self.refresh_len();
|
||||
self.0.extend_from_slice(string.as_bytes());
|
||||
self.0.push(b'\0');
|
||||
}
|
||||
/// Returns the capacity of this `ImString` in bytes
|
||||
pub fn capacity(&self) -> usize {
|
||||
self.0.capacity() - 1
|
||||
}
|
||||
/// Returns the capacity of this `ImString` in bytes, including the implicit null byte
|
||||
pub fn capacity_with_nul(&self) -> usize {
|
||||
self.0.capacity()
|
||||
}
|
||||
/// Ensures that the capacity of this `ImString` is at least `additional` bytes larger than the
|
||||
/// current length.
|
||||
///
|
||||
/// The capacity may be increased by more than `additional` bytes.
|
||||
pub fn reserve(&mut self, additional: usize) {
|
||||
self.0.reserve(additional);
|
||||
}
|
||||
/// Ensures that the capacity of this `ImString` is at least `additional` bytes larger than the
|
||||
/// current length
|
||||
pub fn reserve_exact(&mut self, additional: usize) {
|
||||
self.0.reserve_exact(additional);
|
||||
}
|
||||
@ -55,7 +87,6 @@ impl ImString {
|
||||
pub fn as_mut_ptr(&mut self) -> *mut c_char {
|
||||
self.0.as_mut_ptr() as *mut _
|
||||
}
|
||||
|
||||
/// Updates the buffer length based on the current contents.
|
||||
///
|
||||
/// Dear imgui accesses pointers directly, so the length doesn't get updated when the contents
|
||||
@ -71,13 +102,25 @@ impl ImString {
|
||||
|
||||
impl<'a> Default for ImString {
|
||||
fn default() -> ImString {
|
||||
unsafe { ImString::from_utf8_with_nul_unchecked(vec![0]) }
|
||||
ImString(vec![b'\0'])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for ImString {
|
||||
fn from(s: String) -> ImString {
|
||||
ImString::new(s)
|
||||
unsafe { ImString::from_utf8_unchecked(s.into_bytes()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<ImString> for Cow<'a, ImStr> {
|
||||
fn from(s: ImString) -> Cow<'a, ImStr> {
|
||||
Cow::Owned(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a ImString> for Cow<'a, ImStr> {
|
||||
fn from(s: &'a ImString) -> Cow<'a, ImStr> {
|
||||
Cow::Borrowed(s)
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,6 +167,12 @@ impl fmt::Debug for ImString {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ImString {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self.to_str(), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for ImString {
|
||||
type Target = ImStr;
|
||||
fn deref(&self) -> &ImStr {
|
||||
@ -135,6 +184,7 @@ impl Deref for ImString {
|
||||
}
|
||||
}
|
||||
|
||||
/// A UTF-8 encoded, implicitly null-terminated string slice.
|
||||
#[derive(Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct ImStr(CStr);
|
||||
|
||||
@ -151,19 +201,39 @@ impl fmt::Debug for ImStr {
|
||||
}
|
||||
}
|
||||
|
||||
impl ImStr {
|
||||
pub fn new<S: AsRef<ImStr> + ?Sized>(s: &S) -> &ImStr {
|
||||
s.as_ref()
|
||||
impl fmt::Display for ImStr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self.to_str(), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ImStr {
|
||||
/// Wraps a raw UTF-8 encoded C string
|
||||
pub unsafe fn from_ptr_unchecked<'a>(ptr: *const c_char) -> &'a ImStr {
|
||||
ImStr::from_cstr_unchecked(CStr::from_ptr(ptr))
|
||||
}
|
||||
/// Converts a slice of bytes to an imgui-rs string slice without checking for valid UTF-8 or
|
||||
/// null termination.
|
||||
pub unsafe fn from_utf8_with_nul_unchecked(bytes: &[u8]) -> &ImStr {
|
||||
&*(bytes as *const [u8] as *const ImStr)
|
||||
}
|
||||
/// Converts a CStr reference to an imgui-rs string slice without checking for valid UTF-8.
|
||||
pub unsafe fn from_cstr_unchecked(value: &CStr) -> &ImStr {
|
||||
&*(value as *const CStr as *const ImStr)
|
||||
}
|
||||
/// Converts an imgui-rs string slice to a raw pointer
|
||||
pub fn as_ptr(&self) -> *const c_char {
|
||||
self.0.as_ptr()
|
||||
}
|
||||
/// Converts an imgui-rs string slice to a normal string slice
|
||||
pub fn to_str(&self) -> &str {
|
||||
// CStr::to_bytes does *not* include the null terminator
|
||||
unsafe { str::from_utf8_unchecked(self.0.to_bytes()) }
|
||||
}
|
||||
/// Returns true if the imgui-rs string slice is empty
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.to_bytes().is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<CStr> for ImStr {
|
||||
@ -184,6 +254,12 @@ impl AsRef<str> for ImStr {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a ImStr> for Cow<'a, ImStr> {
|
||||
fn from(s: &'a ImStr) -> Cow<'a, ImStr> {
|
||||
Cow::Borrowed(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToOwned for ImStr {
|
||||
type Owned = ImString;
|
||||
fn to_owned(&self) -> ImString {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user