From 191a346545c76f944ac06dcf85d7ab15905a4f68 Mon Sep 17 00:00:00 2001 From: Jack Mac Date: Sun, 26 Sep 2021 21:07:45 -0400 Subject: [PATCH] init significant changes --- imgui/src/context.rs | 23 +++--- imgui/src/input/mouse.rs | 54 ++++++------- imgui/src/lib.rs | 53 ++++++++----- imgui/src/stacks.rs | 166 ++++++++++++++++++++++++++------------- imgui/src/string.rs | 10 +-- imgui/src/utils.rs | 5 +- imgui/src/widget/drag.rs | 4 +- 7 files changed, 195 insertions(+), 120 deletions(-) diff --git a/imgui/src/context.rs b/imgui/src/context.rs index 592ed88..a42aed6 100644 --- a/imgui/src/context.rs +++ b/imgui/src/context.rs @@ -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, } } } diff --git a/imgui/src/input/mouse.rs b/imgui/src/input/mouse.rs index 7aa66ab..218b56c 100644 --- a/imgui/src/input/mouse.rs +++ b/imgui/src/input/mouse.rs @@ -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]); diff --git a/imgui/src/lib.rs b/imgui/src/lib.rs index 7bfca42..05fe3f2 100644 --- a/imgui/src/lib.rs +++ b/imgui/src/lib.rs @@ -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>, - // imgui isn't mutli-threaded -- so no one will ever access twice. - buffer: std::cell::UnsafeCell, + 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 = + 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 { + &BUFFER + } + /// Internal method to push a single text to our scratch buffer. fn scratch_txt(&self, txt: impl AsRef) -> *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>) -> *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, ) -> (*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>, ) -> (*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); diff --git a/imgui/src/stacks.rs b/imgui/src/stacks.rs index 94fad58..44e9632 100644 --- a/imgui/src/stacks.rs +++ b/imgui/src/stacks.rs @@ -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>, + mem::Discriminant, +); + +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, - _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!(); + } } } } diff --git a/imgui/src/string.rs b/imgui/src/string.rs index d124d85..af6557b 100644 --- a/imgui/src/string.rs +++ b/imgui/src/string.rs @@ -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, - max_len: usize, +pub struct UiBuffer { + pub buffer: Vec, + 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, } } diff --git a/imgui/src/utils.rs b/imgui/src/utils.rs index b977c6d..f819c26 100644 --- a/imgui/src/utils.rs +++ b/imgui/src/utils.rs @@ -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) } } diff --git a/imgui/src/widget/drag.rs b/imgui/src/widget/drag.rs index a861365..4b962ba 100644 --- a/imgui/src/widget/drag.rs +++ b/imgui/src/widget/drag.rs @@ -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);