mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-13 22:48:34 +00:00
init significant changes
This commit is contained in:
parent
4d183cffa6
commit
191a346545
@ -512,31 +512,36 @@ impl Context {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Starts a new frame.
|
||||
#[deprecated(since = "0.9.0", note = "use `new_frame` instead")]
|
||||
pub fn frame(&mut self) -> Ui<'_> {
|
||||
self.new_frame()
|
||||
}
|
||||
|
||||
/// Starts a new frame and returns an `Ui` instance for constructing a user interface.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the context uses a shared font atlas that is already borrowed
|
||||
/// Panics if the context uses a shared font atlas that is already borrowed.
|
||||
/// Do not attempt to borrow the context afterwards, if you are using a shared font atlas.
|
||||
#[doc(alias = "NewFame")]
|
||||
pub fn frame(&mut self) -> Ui<'_> {
|
||||
pub fn new_frame(&mut self) -> Ui<'_> {
|
||||
// Clear default font if it no longer exists. This could be an error in the future
|
||||
let default_font = self.io().font_default;
|
||||
if !default_font.is_null() && self.fonts().get_font(FontId(default_font)).is_none() {
|
||||
self.io_mut().font_default = ptr::null_mut();
|
||||
}
|
||||
// NewFrame/Render/EndFrame mutate the font atlas so we need exclusive access to it
|
||||
let font_atlas = self
|
||||
.shared_font_atlas
|
||||
.as_ref()
|
||||
.map(|font_atlas| font_atlas.borrow_mut());
|
||||
if let Some(font_atlas) = self.shared_font_atlas.as_ref() {
|
||||
assert!(font_atlas.try_borrow_mut().is_ok());
|
||||
}
|
||||
// TODO: precondition checks
|
||||
unsafe {
|
||||
sys::igNewFrame();
|
||||
}
|
||||
Ui {
|
||||
ctx: self,
|
||||
font_atlas,
|
||||
buffer: crate::UiBuffer::new(1024).into(),
|
||||
phantom_data: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,7 +237,7 @@ fn test_mouse_down_clicked_released() {
|
||||
let (_guard, mut ctx) = crate::test::test_ctx_initialized();
|
||||
{
|
||||
ctx.io_mut().mouse_down = [false; 5];
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_down(button));
|
||||
assert!(!ui.is_any_mouse_down());
|
||||
assert!(!ui.is_mouse_clicked(button));
|
||||
@ -245,14 +245,14 @@ fn test_mouse_down_clicked_released() {
|
||||
}
|
||||
{
|
||||
ctx.io_mut()[button] = true;
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(ui.is_mouse_down(button));
|
||||
assert!(ui.is_any_mouse_down());
|
||||
assert!(ui.is_mouse_clicked(button));
|
||||
assert!(!ui.is_mouse_released(button));
|
||||
}
|
||||
{
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(ui.is_mouse_down(button));
|
||||
assert!(ui.is_any_mouse_down());
|
||||
assert!(!ui.is_mouse_clicked(button));
|
||||
@ -260,14 +260,14 @@ fn test_mouse_down_clicked_released() {
|
||||
}
|
||||
{
|
||||
ctx.io_mut()[button] = false;
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_down(button));
|
||||
assert!(!ui.is_any_mouse_down());
|
||||
assert!(!ui.is_mouse_clicked(button));
|
||||
assert!(ui.is_mouse_released(button));
|
||||
}
|
||||
{
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_down(button));
|
||||
assert!(!ui.is_any_mouse_down());
|
||||
assert!(!ui.is_mouse_clicked(button));
|
||||
@ -287,42 +287,42 @@ fn test_mouse_double_click() {
|
||||
{
|
||||
// Pass one second of time
|
||||
ctx.io_mut().delta_time = 1.0;
|
||||
let _ = ctx.frame();
|
||||
let _ = ctx.new_frame();
|
||||
}
|
||||
// Fast clicks
|
||||
ctx.io_mut().delta_time = 1.0 / 60.0;
|
||||
for &button in MouseButton::VARIANTS.iter() {
|
||||
{
|
||||
ctx.io_mut().mouse_down = [false; 5];
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_clicked(button));
|
||||
assert!(!ui.is_mouse_double_clicked(button));
|
||||
}
|
||||
{
|
||||
ctx.io_mut()[button] = true;
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(ui.is_mouse_clicked(button));
|
||||
assert!(!ui.is_mouse_double_clicked(button));
|
||||
}
|
||||
{
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_clicked(button));
|
||||
assert!(!ui.is_mouse_double_clicked(button));
|
||||
}
|
||||
{
|
||||
ctx.io_mut()[button] = false;
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_clicked(button));
|
||||
assert!(!ui.is_mouse_double_clicked(button));
|
||||
}
|
||||
{
|
||||
ctx.io_mut()[button] = true;
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(ui.is_mouse_clicked(button));
|
||||
assert!(ui.is_mouse_double_clicked(button));
|
||||
}
|
||||
{
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_clicked(button));
|
||||
assert!(!ui.is_mouse_double_clicked(button));
|
||||
}
|
||||
@ -332,35 +332,35 @@ fn test_mouse_double_click() {
|
||||
for &button in MouseButton::VARIANTS.iter() {
|
||||
{
|
||||
ctx.io_mut().mouse_down = [false; 5];
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_clicked(button));
|
||||
assert!(!ui.is_mouse_double_clicked(button));
|
||||
}
|
||||
{
|
||||
ctx.io_mut()[button] = true;
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(ui.is_mouse_clicked(button));
|
||||
assert!(!ui.is_mouse_double_clicked(button));
|
||||
}
|
||||
{
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_clicked(button));
|
||||
assert!(!ui.is_mouse_double_clicked(button));
|
||||
}
|
||||
{
|
||||
ctx.io_mut()[button] = false;
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_clicked(button));
|
||||
assert!(!ui.is_mouse_double_clicked(button));
|
||||
}
|
||||
{
|
||||
ctx.io_mut()[button] = true;
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(ui.is_mouse_clicked(button));
|
||||
assert!(!ui.is_mouse_double_clicked(button));
|
||||
}
|
||||
{
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_clicked(button));
|
||||
assert!(!ui.is_mouse_double_clicked(button));
|
||||
}
|
||||
@ -370,7 +370,7 @@ fn test_mouse_double_click() {
|
||||
#[test]
|
||||
fn test_set_get_mouse_cursor() {
|
||||
let (_guard, mut ctx) = crate::test::test_ctx_initialized();
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
ui.set_mouse_cursor(None);
|
||||
assert_eq!(None, ui.mouse_cursor());
|
||||
ui.set_mouse_cursor(Some(MouseCursor::Hand));
|
||||
@ -384,7 +384,7 @@ fn test_mouse_drags() {
|
||||
{
|
||||
ctx.io_mut().mouse_pos = [0.0, 0.0];
|
||||
ctx.io_mut().mouse_down = [false; 5];
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_dragging(button));
|
||||
assert!(!ui.is_mouse_dragging_with_threshold(button, 200.0));
|
||||
assert_eq!(ui.mouse_drag_delta_with_button(button), [0.0, 0.0]);
|
||||
@ -395,7 +395,7 @@ fn test_mouse_drags() {
|
||||
}
|
||||
{
|
||||
ctx.io_mut()[button] = true;
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_dragging(button));
|
||||
assert!(!ui.is_mouse_dragging_with_threshold(button, 200.0));
|
||||
assert_eq!(ui.mouse_drag_delta_with_button(button), [0.0, 0.0]);
|
||||
@ -406,7 +406,7 @@ fn test_mouse_drags() {
|
||||
}
|
||||
{
|
||||
ctx.io_mut().mouse_pos = [0.0, 100.0];
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(ui.is_mouse_dragging(button));
|
||||
assert!(!ui.is_mouse_dragging_with_threshold(button, 200.0));
|
||||
assert_eq!(ui.mouse_drag_delta_with_button(button), [0.0, 100.0]);
|
||||
@ -417,7 +417,7 @@ fn test_mouse_drags() {
|
||||
}
|
||||
{
|
||||
ctx.io_mut().mouse_pos = [0.0, 200.0];
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(ui.is_mouse_dragging(button));
|
||||
assert!(ui.is_mouse_dragging_with_threshold(button, 200.0));
|
||||
assert_eq!(ui.mouse_drag_delta_with_button(button), [0.0, 200.0]);
|
||||
@ -429,7 +429,7 @@ fn test_mouse_drags() {
|
||||
{
|
||||
ctx.io_mut().mouse_pos = [10.0, 10.0];
|
||||
ctx.io_mut()[button] = false;
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_dragging(button));
|
||||
assert!(!ui.is_mouse_dragging_with_threshold(button, 200.0));
|
||||
assert_eq!(ui.mouse_drag_delta_with_button(button), [10.0, 10.0]);
|
||||
@ -440,7 +440,7 @@ fn test_mouse_drags() {
|
||||
}
|
||||
{
|
||||
ctx.io_mut()[button] = true;
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(!ui.is_mouse_dragging(button));
|
||||
assert!(!ui.is_mouse_dragging_with_threshold(button, 200.0));
|
||||
assert_eq!(ui.mouse_drag_delta_with_button(button), [0.0, 0.0]);
|
||||
@ -451,7 +451,7 @@ fn test_mouse_drags() {
|
||||
}
|
||||
{
|
||||
ctx.io_mut().mouse_pos = [180.0, 180.0];
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(ui.is_mouse_dragging(button));
|
||||
assert!(ui.is_mouse_dragging_with_threshold(button, 200.0));
|
||||
assert_eq!(ui.mouse_drag_delta_with_button(button), [170.0, 170.0]);
|
||||
@ -470,7 +470,7 @@ fn test_mouse_drags() {
|
||||
}
|
||||
{
|
||||
ctx.io_mut().mouse_pos = [200.0, 200.0];
|
||||
let ui = ctx.frame();
|
||||
let ui = ctx.new_frame();
|
||||
assert!(ui.is_mouse_dragging(button));
|
||||
assert!(ui.is_mouse_dragging_with_threshold(button, 200.0));
|
||||
assert_eq!(ui.mouse_drag_delta_with_button(button), [20.0, 20.0]);
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
pub extern crate imgui_sys as sys;
|
||||
|
||||
use std::cell;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
|
||||
pub use self::clipboard::*;
|
||||
@ -118,17 +119,37 @@ impl Context {
|
||||
/// A temporary reference for building the user interface for one frame
|
||||
#[derive(Debug)]
|
||||
pub struct Ui<'ui> {
|
||||
ctx: &'ui Context,
|
||||
font_atlas: Option<std::cell::RefMut<'ui, SharedFontAtlas>>,
|
||||
// imgui isn't mutli-threaded -- so no one will ever access twice.
|
||||
buffer: std::cell::UnsafeCell<string::UiBuffer>,
|
||||
phantom_data: std::marker::PhantomData<&'ui Context>,
|
||||
}
|
||||
|
||||
/// This is our internal buffer that we use for the Ui object.
|
||||
///
|
||||
/// We edit this buffer
|
||||
static mut BUFFER: cell::UnsafeCell<string::UiBuffer> =
|
||||
cell::UnsafeCell::new(string::UiBuffer::new(100));
|
||||
|
||||
impl<'ui> Ui<'ui> {
|
||||
/// This provides access to the backing scratch buffer that we use to write
|
||||
/// strings, along with null-terminators, before we pass normal Rust strs to
|
||||
/// Dear ImGui.
|
||||
///
|
||||
/// This is given as a get-out-of-jail free card if you need to handle the buffer,
|
||||
/// or, for example, resize it for some reason. Generally, you should never need this.
|
||||
///
|
||||
/// ## Safety
|
||||
///
|
||||
/// This uses a **static mut** and we assume it will *never* be passed between threads.
|
||||
/// Do not pass the raw pointer you get between threads at all -- Dear ImGui is single-threaded.
|
||||
/// We otherwise make no assumptions about the size or keep state in this buffer between calls,
|
||||
/// so editing the `UiBuffer` is fine.
|
||||
pub unsafe fn scratch_buffer(&self) -> &cell::UnsafeCell<string::UiBuffer> {
|
||||
&BUFFER
|
||||
}
|
||||
|
||||
/// Internal method to push a single text to our scratch buffer.
|
||||
fn scratch_txt(&self, txt: impl AsRef<str>) -> *const sys::cty::c_char {
|
||||
unsafe {
|
||||
let handle = &mut *self.buffer.get();
|
||||
let handle = &mut *BUFFER.get();
|
||||
handle.scratch_txt(txt)
|
||||
}
|
||||
}
|
||||
@ -136,7 +157,7 @@ impl<'ui> Ui<'ui> {
|
||||
/// Internal method to push an option text to our scratch buffer.
|
||||
fn scratch_txt_opt(&self, txt: Option<impl AsRef<str>>) -> *const sys::cty::c_char {
|
||||
unsafe {
|
||||
let handle = &mut *self.buffer.get();
|
||||
let handle = &mut *BUFFER.get();
|
||||
handle.scratch_txt_opt(txt)
|
||||
}
|
||||
}
|
||||
@ -147,7 +168,7 @@ impl<'ui> Ui<'ui> {
|
||||
txt_1: impl AsRef<str>,
|
||||
) -> (*const sys::cty::c_char, *const sys::cty::c_char) {
|
||||
unsafe {
|
||||
let handle = &mut *self.buffer.get();
|
||||
let handle = &mut *BUFFER.get();
|
||||
handle.scratch_txt_two(txt_0, txt_1)
|
||||
}
|
||||
}
|
||||
@ -158,7 +179,7 @@ impl<'ui> Ui<'ui> {
|
||||
txt_1: Option<impl AsRef<str>>,
|
||||
) -> (*const sys::cty::c_char, *const sys::cty::c_char) {
|
||||
unsafe {
|
||||
let handle = &mut *self.buffer.get();
|
||||
let handle = &mut *BUFFER.get();
|
||||
handle.scratch_txt_with_opt(txt_0, txt_1)
|
||||
}
|
||||
}
|
||||
@ -169,19 +190,13 @@ impl<'ui> Ui<'ui> {
|
||||
unsafe { &*(sys::igGetIO() as *const Io) }
|
||||
}
|
||||
|
||||
/// Returns an immutable reference to the font atlas
|
||||
pub fn fonts(&self) -> FontAtlasRef<'_> {
|
||||
match self.font_atlas {
|
||||
Some(ref font_atlas) => FontAtlasRef::Shared(font_atlas),
|
||||
None => unsafe {
|
||||
let fonts = &*(self.io().fonts as *const FontAtlas);
|
||||
FontAtlasRef::Owned(fonts)
|
||||
},
|
||||
}
|
||||
/// Returns an immutable reference to the font atlas.
|
||||
pub fn fonts(&self) -> &FontAtlas {
|
||||
unsafe { &*(self.io().fonts as *const FontAtlas) }
|
||||
}
|
||||
/// Returns a clone of the user interface style
|
||||
pub fn clone_style(&self) -> Style {
|
||||
*self.ctx.style()
|
||||
unsafe { *self.style() }
|
||||
}
|
||||
/// Renders the frame and returns a reference to the resulting draw data
|
||||
#[doc(alias = "Render", alias = "GetDrawData")]
|
||||
@ -614,7 +629,7 @@ impl<'ui> Ui<'ui> {
|
||||
height_in_items: i32,
|
||||
) -> bool {
|
||||
let (label_ptr, items_inner) = unsafe {
|
||||
let handle = &mut *self.buffer.get();
|
||||
let handle = &mut *self.scratch_buffer().get();
|
||||
|
||||
handle.refresh_buffer();
|
||||
let label_ptr = handle.push(label);
|
||||
|
||||
@ -1,14 +1,11 @@
|
||||
use std::mem;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
use std::ptr;
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::fonts::atlas::FontId;
|
||||
use crate::internal::RawCast;
|
||||
use crate::math::MintVec4;
|
||||
use crate::style::{StyleColor, StyleVar};
|
||||
use crate::sys;
|
||||
use crate::{Id, Ui};
|
||||
use std::mem;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
|
||||
/// # Parameter stacks (shared)
|
||||
impl<'ui> Ui<'ui> {
|
||||
@ -190,9 +187,9 @@ impl<'ui> Ui<'ui> {
|
||||
/// - `< 0.0`: `item_width` pixels relative to the right of window (-1.0 always aligns width to
|
||||
/// the right side)
|
||||
#[doc(alias = "PushItemWith")]
|
||||
pub fn push_item_width(&self, item_width: f32) -> ItemWidthStackToken {
|
||||
pub fn push_item_width(&self, item_width: f32) -> ItemWidthStackToken<'_> {
|
||||
unsafe { sys::igPushItemWidth(item_width) };
|
||||
ItemWidthStackToken { _ctx: self.ctx }
|
||||
ItemWidthStackToken::new(self)
|
||||
}
|
||||
/// Sets the width of the next item.
|
||||
///
|
||||
@ -220,7 +217,7 @@ impl<'ui> Ui<'ui> {
|
||||
///
|
||||
/// Returns a `TextWrapPosStackToken` that may be popped by calling `.pop()`
|
||||
#[doc(alias = "PushTextWrapPos")]
|
||||
pub fn push_text_wrap_pos(&self) -> TextWrapPosStackToken {
|
||||
pub fn push_text_wrap_pos(&self) -> TextWrapPosStackToken<'_> {
|
||||
self.push_text_wrap_pos_with_pos(0.0)
|
||||
}
|
||||
|
||||
@ -232,25 +229,58 @@ impl<'ui> Ui<'ui> {
|
||||
/// - `= 0.0`: wrap to end of window (or column)
|
||||
/// - `< 0.0`: no wrapping
|
||||
#[doc(alias = "PushTextWrapPos")]
|
||||
pub fn push_text_wrap_pos_with_pos(&self, wrap_pos_x: f32) -> TextWrapPosStackToken {
|
||||
pub fn push_text_wrap_pos_with_pos(&self, wrap_pos_x: f32) -> TextWrapPosStackToken<'_> {
|
||||
unsafe { sys::igPushTextWrapPos(wrap_pos_x) };
|
||||
TextWrapPosStackToken { _ctx: self.ctx }
|
||||
TextWrapPosStackToken::new(self)
|
||||
}
|
||||
|
||||
/// Tab stop enable.
|
||||
/// Allow focusing using TAB/Shift-TAB, enabled by default but you can
|
||||
/// disable it for certain widgets
|
||||
///
|
||||
/// Returns a [PushAllowKeyboardFocusToken] that should be dropped.
|
||||
#[doc(alias = "PushAllowKeyboardFocus")]
|
||||
pub fn push_allow_keyboard_focus(&self, allow: bool) -> PushAllowKeyboardFocusToken<'_> {
|
||||
unsafe { sys::igPushAllowKeyboardFocus(allow) };
|
||||
PushAllowKeyboardFocusToken::new(self)
|
||||
}
|
||||
|
||||
/// In 'repeat' mode, button_x functions return repeated true in a typematic
|
||||
/// manner (using io.KeyRepeatDelay/io.KeyRepeatRate setting).
|
||||
/// Note that you can call IsItemActive() after any Button() to tell if the
|
||||
/// button is held in the current frame.
|
||||
///
|
||||
/// Returns a [PushButtonRepeatToken] that should be dropped.
|
||||
#[doc(alias = "PushAllowKeyboardFocus")]
|
||||
pub fn push_button_repeat(&self, allow: bool) -> PushButtonRepeatToken<'_> {
|
||||
unsafe { sys::igPushButtonRepeat(allow) };
|
||||
PushButtonRepeatToken::new(self)
|
||||
}
|
||||
|
||||
/// Changes an item flag by pushing a change to the item flag stack.
|
||||
///
|
||||
/// Returns a `ItemFlagsStackToken` that may be popped by calling `.pop()`
|
||||
#[doc(alias = "PushItemFlag")]
|
||||
pub fn push_item_flag(&self, item_flag: ItemFlag) -> ItemFlagsStackToken {
|
||||
///
|
||||
/// ## Deprecated
|
||||
///
|
||||
/// This was deprecated in `0.9.0` because it isn't part of the dear imgui design,
|
||||
/// and supporting it required a manual implementation of its drop token.
|
||||
///
|
||||
/// Instead, just use [`push_allow_keyboard_focus`] and [`push_button_repeat`].
|
||||
///
|
||||
/// [`push_allow_keyboard_focus`]: Self::push_allow_keyboard_focus
|
||||
/// [`push_button_repeat`]: Self::push_button_repeat
|
||||
#[deprecated(
|
||||
since = "0.9.0",
|
||||
note = "use `push_allow_keyboard_focus` or `push_button_repeat` instead"
|
||||
)]
|
||||
pub fn push_item_flag(&self, item_flag: ItemFlag) -> ItemFlagsStackToken<'_> {
|
||||
use self::ItemFlag::*;
|
||||
match item_flag {
|
||||
AllowKeyboardFocus(v) => unsafe { sys::igPushAllowKeyboardFocus(v) },
|
||||
ButtonRepeat(v) => unsafe { sys::igPushButtonRepeat(v) },
|
||||
}
|
||||
ItemFlagsStackToken {
|
||||
discriminant: mem::discriminant(&item_flag),
|
||||
_ctx: self.ctx,
|
||||
}
|
||||
ItemFlagsStackToken::new(self, item_flag)
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,54 +291,78 @@ pub enum ItemFlag {
|
||||
ButtonRepeat(bool),
|
||||
}
|
||||
|
||||
pub struct ItemWidthStackToken {
|
||||
_ctx: *const Context,
|
||||
}
|
||||
create_token!(
|
||||
/// Tracks a window that can be ended by calling `.end()`
|
||||
/// or by dropping.
|
||||
pub struct ItemWidthStackToken<'ui>;
|
||||
|
||||
impl ItemWidthStackToken {
|
||||
/// Pops a change from the item width stack
|
||||
/// Ends a window
|
||||
#[doc(alias = "PopItemWidth")]
|
||||
pub fn pop(mut self, _: &Ui<'_>) {
|
||||
self._ctx = ptr::null();
|
||||
unsafe { sys::igPopItemWidth() };
|
||||
}
|
||||
}
|
||||
drop { sys::igPopItemWidth() }
|
||||
);
|
||||
|
||||
/// Tracks a change pushed to the text wrap position stack
|
||||
pub struct TextWrapPosStackToken {
|
||||
_ctx: *const Context,
|
||||
}
|
||||
create_token!(
|
||||
/// Tracks a window that can be ended by calling `.end()`
|
||||
/// or by dropping.
|
||||
pub struct TextWrapPosStackToken<'ui>;
|
||||
|
||||
impl TextWrapPosStackToken {
|
||||
/// Pops a change from the text wrap position stack
|
||||
/// Ends a window
|
||||
#[doc(alias = "PopTextWrapPos")]
|
||||
pub fn pop(mut self, _: &Ui<'_>) {
|
||||
self._ctx = ptr::null();
|
||||
unsafe { sys::igPopTextWrapPos() };
|
||||
drop { sys::igPopTextWrapPos() }
|
||||
);
|
||||
|
||||
create_token!(
|
||||
/// Tracks a window that can be ended by calling `.end()`
|
||||
/// or by dropping.
|
||||
pub struct PushAllowKeyboardFocusToken<'ui>;
|
||||
|
||||
/// Ends a window
|
||||
#[doc(alias = "PopAllowKeyboardFocus")]
|
||||
drop { sys::igPopAllowKeyboardFocus() }
|
||||
);
|
||||
|
||||
create_token!(
|
||||
/// Tracks a window that can be ended by calling `.end()`
|
||||
/// or by dropping.
|
||||
pub struct PushButtonRepeatToken<'ui>;
|
||||
|
||||
/// Ends a window
|
||||
#[doc(alias = "PopButtonRepeat")]
|
||||
drop { sys::igPopButtonRepeat() }
|
||||
);
|
||||
|
||||
/// Tracks a change pushed to the item flags stack.
|
||||
///
|
||||
/// The "item flags" stack was a concept invented in imgui-rs that doesn't have an
|
||||
/// ImGui equivalent. We're phasing these out to make imgui-rs feel simpler to use.
|
||||
#[must_use]
|
||||
pub struct ItemFlagsStackToken<'a>(
|
||||
std::marker::PhantomData<Ui<'a>>,
|
||||
mem::Discriminant<ItemFlag>,
|
||||
);
|
||||
|
||||
impl<'a> ItemFlagsStackToken<'a> {
|
||||
/// Creates a new token type.
|
||||
pub(crate) fn new(_: &crate::Ui<'a>, kind: ItemFlag) -> Self {
|
||||
Self(std::marker::PhantomData, mem::discriminant(&kind))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn end(self) {
|
||||
// left empty for drop
|
||||
}
|
||||
}
|
||||
|
||||
/// Tracks a change pushed to the item flags stack
|
||||
pub struct ItemFlagsStackToken {
|
||||
discriminant: mem::Discriminant<ItemFlag>,
|
||||
_ctx: *const Context,
|
||||
}
|
||||
|
||||
impl ItemFlagsStackToken {
|
||||
/// Pops a change from the item flags stack
|
||||
|
||||
#[doc(alias = "PopAllowKeyboardFocus", alias = "PopButtonRepeat")]
|
||||
pub fn pop(mut self, _: &Ui<'_>) {
|
||||
self._ctx = ptr::null();
|
||||
const ALLOW_KEYBOARD_FOCUS: ItemFlag = ItemFlag::AllowKeyboardFocus(true);
|
||||
const BUTTON_REPEAT: ItemFlag = ItemFlag::ButtonRepeat(true);
|
||||
|
||||
if self.discriminant == mem::discriminant(&ALLOW_KEYBOARD_FOCUS) {
|
||||
unsafe { sys::igPopAllowKeyboardFocus() };
|
||||
} else if self.discriminant == mem::discriminant(&BUTTON_REPEAT) {
|
||||
unsafe { sys::igPopButtonRepeat() };
|
||||
} else {
|
||||
unreachable!();
|
||||
impl Drop for ItemFlagsStackToken<'_> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
if self.1 == mem::discriminant(&ItemFlag::AllowKeyboardFocus(true)) {
|
||||
sys::igPopAllowKeyboardFocus();
|
||||
} else if self.1 == mem::discriminant(&ItemFlag::ButtonRepeat(true)) {
|
||||
sys::igPopButtonRepeat();
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,16 +7,16 @@ use std::{fmt, ptr};
|
||||
|
||||
/// this is the unsafe cell upon which we build our abstraction.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct UiBuffer {
|
||||
buffer: Vec<u8>,
|
||||
max_len: usize,
|
||||
pub struct UiBuffer {
|
||||
pub buffer: Vec<u8>,
|
||||
pub max_len: usize,
|
||||
}
|
||||
|
||||
impl UiBuffer {
|
||||
/// Creates a new max buffer with the given length.
|
||||
pub fn new(max_len: usize) -> Self {
|
||||
pub const fn new(max_len: usize) -> Self {
|
||||
Self {
|
||||
buffer: Vec::with_capacity(max_len),
|
||||
buffer: Vec::new(),
|
||||
max_len,
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,7 +177,7 @@ impl<'ui> Ui<'ui> {
|
||||
/// style object.
|
||||
#[doc(alias = "GetStyle")]
|
||||
pub fn style_color(&self, style_color: StyleColor) -> [f32; 4] {
|
||||
self.ctx.style()[style_color]
|
||||
unsafe { self.style() }.colors[style_color as usize]
|
||||
}
|
||||
|
||||
/// Returns a shared reference to the current [`Style`].
|
||||
@ -193,6 +193,7 @@ impl<'ui> Ui<'ui> {
|
||||
/// pop. The [`clone_style`](Ui::clone_style) version may instead be used to avoid `unsafe`.
|
||||
#[doc(alias = "GetStyle")]
|
||||
pub unsafe fn style(&self) -> &Style {
|
||||
self.ctx.style()
|
||||
// safe because Style is a transparent wrapper around sys::ImGuiStyle
|
||||
&*(sys::igGetStyle() as *const Style)
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,7 +215,7 @@ where
|
||||
|
||||
// we do this ourselves the long way...
|
||||
unsafe {
|
||||
let buffer = &mut *ui.buffer.get();
|
||||
let buffer = &mut *ui.scratch_buffer().get();
|
||||
buffer.refresh_buffer();
|
||||
|
||||
label = buffer.push(self.label);
|
||||
@ -258,7 +258,7 @@ where
|
||||
let mut max_display_format = std::ptr::null();
|
||||
|
||||
// we do this ourselves the long way...
|
||||
let buffer = &mut *ui.buffer.get();
|
||||
let buffer = &mut *ui.scratch_buffer().get();
|
||||
buffer.refresh_buffer();
|
||||
|
||||
label = buffer.push(self.label);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user