Pull first part of 0.1 context API

This commit is contained in:
Joonas Javanainen 2019-06-27 18:18:57 +03:00
parent f7f9deb321
commit 9516e622be
No known key found for this signature in database
GPG Key ID: D39CCA5CB19B9179
11 changed files with 402 additions and 98 deletions

View File

@ -15,6 +15,8 @@ travis-ci = { repository = "Gekkio/imgui-rs" }
[dependencies]
imgui-sys = { version = "0.0.24-pre", path = "imgui-sys" }
lazy_static = "1.1"
parking_lot = "0.7"
[dev-dependencies]
memoffset = "0.3"

View File

@ -356,6 +356,8 @@ name = "imgui"
version = "0.0.24-pre"
dependencies = [
"imgui-sys 0.0.24-pre",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]

View File

@ -1,4 +1,4 @@
use imgui::{FontGlyphRange, ImFontConfig, ImGui, Ui};
use imgui::{FontGlyphRange, ImFontConfig, Context, Ui};
use imgui_gfx_renderer::{Renderer, Shaders};
use imgui_winit_support;
use std::time::Instant;
@ -42,7 +42,7 @@ pub fn run<F: FnMut(&Ui) -> bool>(title: String, clear_color: [f32; 4], mut run_
}
};
let mut imgui = ImGui::init();
let mut imgui = Context::create();
{
// Fix incorrect colors with sRGB framebuffer
fn imgui_gamma_to_linear(col: [f32; 4]) -> [f32; 4] {

View File

@ -4,7 +4,7 @@ use gfx::pso::{PipelineData, PipelineState};
use gfx::texture::{FilterMethod, SamplerInfo, WrapMode};
use gfx::traits::FactoryExt;
use gfx::{CommandBuffer, Encoder, Factory, IntoIndexBuffer, Rect, Resources, Slice};
use imgui::{DrawList, FrameSize, ImDrawIdx, ImDrawVert, ImGui, ImTexture, Textures, Ui};
use imgui::{Context, DrawList, FrameSize, ImDrawIdx, ImDrawVert, ImTexture, Textures, Ui};
pub type RendererResult<T> = Result<T, RendererError>;
@ -190,7 +190,7 @@ pub struct Renderer<R: Resources> {
impl<R: Resources> Renderer<R> {
pub fn init<F: Factory<R>>(
imgui: &mut ImGui,
imgui: &mut Context,
factory: &mut F,
shaders: Shaders,
out: RenderTargetView<R, gfx::format::Rgba8>,

View File

@ -372,6 +372,8 @@ name = "imgui"
version = "0.0.24-pre"
dependencies = [
"imgui-sys 0.0.24-pre",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]

View File

@ -2,7 +2,7 @@ use glium::{
backend::{Context, Facade},
Texture2d,
};
use imgui::{FontGlyphRange, ImFontConfig, ImGui, Ui};
use imgui::{FontGlyphRange, ImFontConfig, self, Ui};
use imgui_winit_support;
use std::rc::Rc;
use std::time::Instant;
@ -26,7 +26,7 @@ where
let gl_window = display.gl_window();
let window = gl_window.window();
let mut imgui = ImGui::init();
let mut imgui = imgui::Context::create();
imgui.set_ini_filename(None);
// In the examples we only use integer DPI factors, because the UI can get very blurry

View File

@ -4,7 +4,7 @@ use glium::program;
use glium::texture;
use glium::vertex;
use glium::{uniform, DrawError, IndexBuffer, Program, Surface, Texture2d, VertexBuffer};
use imgui::{DrawList, FrameSize, ImGui, ImTexture, Textures, Ui};
use imgui::{self, DrawList, FrameSize, ImTexture, Textures, Ui};
use std::borrow::Cow;
use std::fmt;
use std::rc::Rc;
@ -71,7 +71,7 @@ pub struct Renderer {
}
impl Renderer {
pub fn init<F: Facade>(imgui: &mut ImGui, ctx: &F) -> RendererResult<Renderer> {
pub fn init<F: Facade>(imgui: &mut imgui::Context, ctx: &F) -> RendererResult<Renderer> {
let device_objects = DeviceObjects::init(imgui, ctx)?;
Ok(Renderer {
ctx: Rc::clone(ctx.get_context()),
@ -222,7 +222,7 @@ fn compile_default_program<F: Facade>(
}
impl DeviceObjects {
pub fn init<F: Facade>(im_gui: &mut ImGui, ctx: &F) -> RendererResult<DeviceObjects> {
pub fn init<F: Facade>(im_gui: &mut imgui::Context, ctx: &F) -> RendererResult<DeviceObjects> {
use glium::texture::{ClientFormat, RawImage2d};
let program = compile_default_program(ctx)?;

View File

@ -5,10 +5,10 @@
//! In your initialization code call `configure_keys`:
//!
//! ```rust,no_run
//! use imgui::ImGui;
//! use imgui::Context;
//!
//! # fn main() {
//! let mut imgui = ImGui::init();
//! let mut imgui = Context::create();
//! imgui_winit_support::configure_keys(&mut imgui);
//! # }
//! ```
@ -17,11 +17,11 @@
//! you need to do is pass each event to `imgui_winit_support` as well:
//!
//! ```rust,no_run
//! # use imgui::ImGui;
//! # use imgui::Context;
//! # use winit::EventsLoop;
//! # fn main() {
//! # let mut events_loop = EventsLoop::new();
//! # let mut imgui = ImGui::init();
//! # let mut imgui = Context::create();
//! # let window_hidpi_factor = 1.0;
//! # let app_hidpi_factor = 1.0;
//! events_loop.poll_events(|event| {
@ -45,11 +45,11 @@
//! For example, you might want to customize mouse wheel line scrolling amount:
//!
//! ```rust,no_run
//! # use imgui::ImGui;
//! # use imgui::Context;
//! # use winit::{EventsLoop, Event, WindowEvent, MouseScrollDelta, TouchPhase};
//! # fn main() {
//! # let mut events_loop = EventsLoop::new();
//! # let mut imgui = ImGui::init();
//! # let mut imgui = Context::create();
//! # let window_hidpi_factor = 1.0;
//! # let app_hidpi_factor = 1.0;
//! events_loop.poll_events(|event| {
@ -81,14 +81,14 @@
//! # }
//! ```
use imgui::{FrameSize, ImGui, ImGuiKey, ImGuiMouseCursor};
use imgui::{Context, FrameSize, ImGuiKey, ImGuiMouseCursor};
use winit::{
ElementState, Event, KeyboardInput, ModifiersState, MouseButton, MouseCursor, MouseScrollDelta,
TouchPhase, VirtualKeyCode, Window, WindowEvent,
};
/// Configure imgui key map with winit `VirtualKeyCode` values
pub fn configure_keys(imgui: &mut ImGui) {
pub fn configure_keys(imgui: &mut Context) {
imgui.set_imgui_key(ImGuiKey::Tab, VirtualKeyCode::Tab as _);
imgui.set_imgui_key(ImGuiKey::LeftArrow, VirtualKeyCode::Left as _);
imgui.set_imgui_key(ImGuiKey::RightArrow, VirtualKeyCode::Right as _);
@ -111,7 +111,7 @@ pub fn configure_keys(imgui: &mut ImGui) {
}
/// Update imgui keyboard state
pub fn handle_keyboard_input(imgui: &mut ImGui, event: KeyboardInput) {
pub fn handle_keyboard_input(imgui: &mut Context, event: KeyboardInput) {
handle_modifiers(imgui, event.modifiers);
if let Some(key) = event.virtual_keycode {
let state_bool = event.state == ElementState::Pressed;
@ -127,7 +127,7 @@ pub fn handle_keyboard_input(imgui: &mut ImGui, event: KeyboardInput) {
}
/// Update imgui keyboard modifier state
pub fn handle_modifiers(imgui: &mut ImGui, modifiers: ModifiersState) {
pub fn handle_modifiers(imgui: &mut Context, modifiers: ModifiersState) {
imgui.set_key_shift(modifiers.shift);
imgui.set_key_ctrl(modifiers.ctrl);
imgui.set_key_alt(modifiers.alt);
@ -136,7 +136,7 @@ pub fn handle_modifiers(imgui: &mut ImGui, modifiers: ModifiersState) {
/// Update imgui mouse wheel position
pub fn handle_mouse_scroll_delta(
imgui: &mut ImGui,
imgui: &mut Context,
delta: MouseScrollDelta,
window_hidpi_factor: f64,
app_hidpi_factor: f64,
@ -153,7 +153,7 @@ pub fn handle_mouse_scroll_delta(
}
/// Update imgui mouse button state
pub fn handle_mouse_button_state(imgui: &mut ImGui, button: MouseButton, state: ElementState) {
pub fn handle_mouse_button_state(imgui: &mut Context, button: MouseButton, state: ElementState) {
let mut states = imgui.mouse_down();
let state_bool = state == ElementState::Pressed;
match button {
@ -168,7 +168,7 @@ pub fn handle_mouse_button_state(imgui: &mut ImGui, button: MouseButton, state:
/// Update imgui state from winit event
pub fn handle_event(
imgui: &mut ImGui,
imgui: &mut Context,
event: &Event,
window_hidpi_factor: f64,
app_hidpi_factor: f64,
@ -180,7 +180,7 @@ pub fn handle_event(
/// Update imgui state from winit window event
pub fn handle_window_event(
imgui: &mut ImGui,
imgui: &mut Context,
event: &WindowEvent,
window_hidpi_factor: f64,
app_hidpi_factor: f64,
@ -223,7 +223,7 @@ pub fn handle_window_event(
}
/// Update winit window mouse cursor state
pub fn update_mouse_cursor(imgui: &ImGui, window: &Window) {
pub fn update_mouse_cursor(imgui: &Context, window: &Window) {
let mouse_cursor = imgui.mouse_cursor();
if imgui.mouse_draw_cursor() || mouse_cursor == ImGuiMouseCursor::None {
// Hide OS cursor

338
src/context.rs Normal file
View File

@ -0,0 +1,338 @@
use parking_lot::ReentrantMutex;
use std::cell::RefCell;
use std::ffi::CStr;
use std::ops::Drop;
use std::ptr;
use std::rc::Rc;
use crate::string::{ImStr, ImString};
use crate::style::Style;
use crate::sys;
use crate::Ui;
/// An imgui-rs context.
///
/// A context needs to be created to access most library functions. Due to current Dear ImGui
/// design choices, at most one active Context can exist at any time. This limitation will likely
/// be removed in a future Dear ImGui version.
///
/// If you need more than one context, you can use suspended contexts. As long as only one context
/// is active at a time, it's possible to have multiple independent contexts.
///
/// # Examples
///
/// Creating a new active context:
/// ```
/// let ctx = imgui::Context::create();
/// // ctx is dropped naturally when it goes out of scope, which deactivates and destroys the
/// // context
/// ```
///
/// Never try to create an active context when another one is active:
///
/// ```should_panic
/// let ctx1 = imgui::Context::create();
///
/// let ctx2 = imgui::Context::create(); // PANIC
/// ```
///
/// Suspending an active context allows you to create another active context:
///
/// ```
/// let ctx1 = imgui::Context::create();
/// let suspended1 = ctx1.suspend();
/// let ctx2 = imgui::Context::create(); // this is now OK
/// ```
#[derive(Debug)]
pub struct Context {
raw: *mut sys::ImGuiContext,
ini_filename: Option<ImString>,
log_filename: Option<ImString>,
platform_name: Option<ImString>,
renderer_name: Option<ImString>,
}
lazy_static! {
// This mutex needs to be used to guard all public functions that can affect the underlying
// Dear ImGui active context
static ref CTX_MUTEX: ReentrantMutex<()> = ReentrantMutex::new(());
}
fn clear_current_context() {
unsafe {
sys::igSetCurrentContext(ptr::null_mut());
}
}
fn no_current_context() -> bool {
let ctx = unsafe { sys::igGetCurrentContext() };
ctx.is_null()
}
impl Context {
/// Creates a new active imgui-rs context.
///
/// # Panics
///
/// Panics if an active context already exists
pub fn create() -> Self {
Self::create_internal()
}
/// Suspends this context so another context can be the active context.
pub fn suspend(self) -> SuspendedContext {
let _guard = CTX_MUTEX.lock();
assert!(
self.is_current_context(),
"context to be suspended is not the active context"
);
clear_current_context();
SuspendedContext(self)
}
pub fn ini_filename(&self) -> Option<&ImStr> {
let io = self.io();
if io.IniFilename.is_null() {
None
} else {
unsafe { Some(ImStr::from_ptr_unchecked(io.IniFilename)) }
}
}
pub fn set_ini_filename<T: Into<Option<ImString>>>(&mut self, ini_filename: T) {
let ini_filename = ini_filename.into();
self.io_mut().IniFilename = ini_filename
.as_ref()
.map(|x| x.as_ptr())
.unwrap_or(ptr::null());
self.ini_filename = ini_filename;
}
pub fn log_filename(&self) -> Option<&ImStr> {
let io = self.io();
if io.LogFilename.is_null() {
None
} else {
unsafe { Some(ImStr::from_ptr_unchecked(io.LogFilename)) }
}
}
pub fn set_log_filename<T: Into<Option<ImString>>>(&mut self, log_filename: T) {
let log_filename = log_filename.into();
self.io_mut().LogFilename = log_filename
.as_ref()
.map(|x| x.as_ptr())
.unwrap_or(ptr::null());
self.log_filename = log_filename;
}
pub fn platform_name(&self) -> Option<&ImStr> {
let io = self.io();
if io.BackendPlatformName.is_null() {
None
} else {
unsafe { Some(ImStr::from_ptr_unchecked(io.BackendPlatformName)) }
}
}
pub fn set_platform_name<T: Into<Option<ImString>>>(&mut self, platform_name: T) {
let platform_name = platform_name.into();
self.io_mut().BackendPlatformName = platform_name
.as_ref()
.map(|x| x.as_ptr())
.unwrap_or(ptr::null());
self.platform_name = platform_name;
}
pub fn renderer_name(&self) -> Option<&ImStr> {
let io = self.io();
if io.BackendRendererName.is_null() {
None
} else {
unsafe { Some(ImStr::from_ptr_unchecked(io.BackendRendererName)) }
}
}
pub fn set_renderer_name<T: Into<Option<ImString>>>(&mut self, renderer_name: T) {
let renderer_name = renderer_name.into();
self.io_mut().BackendRendererName = renderer_name
.as_ref()
.map(|x| x.as_ptr())
.unwrap_or(ptr::null());
self.renderer_name = renderer_name;
}
pub fn load_ini_settings(&mut self, data: &str) {
unsafe { sys::igLoadIniSettingsFromMemory(data.as_ptr() as *const _, data.len()) }
}
pub fn save_ini_settings(&mut self, buf: &mut String) {
let data = unsafe { CStr::from_ptr(sys::igSaveIniSettingsToMemory(ptr::null_mut())) };
buf.push_str(&data.to_string_lossy());
}
fn create_internal() -> Self {
let _guard = CTX_MUTEX.lock();
assert!(
no_current_context(),
"A new active context cannot be created, because another one already exists"
);
// Dear ImGui implicitly sets the current context during igCreateContext if the current
// context doesn't exist
let raw = unsafe { sys::igCreateContext(ptr::null_mut()) };
Context {
raw,
ini_filename: None,
log_filename: None,
platform_name: None,
renderer_name: None,
}
}
fn is_current_context(&self) -> bool {
let ctx = unsafe { sys::igGetCurrentContext() };
self.raw == ctx
}
}
impl Drop for Context {
fn drop(&mut self) {
let _guard = CTX_MUTEX.lock();
// If this context is the active context, Dear ImGui automatically deactivates it during
// destruction
unsafe {
sys::igDestroyContext(self.raw);
}
}
}
/// A suspended imgui-rs context.
///
/// A suspended context retains its state, but is not usable without activating it first.
///
/// # Examples
///
/// Suspended contexts are not directly very useful, but you can activate them:
///
/// ```
/// let suspended = imgui::SuspendedContext::create();
/// match suspended.activate() {
/// Ok(ctx) => {
/// // ctx is now the active context
/// },
/// Err(suspended) => {
/// // activation failed, so you get the suspended context back
/// }
/// }
/// ```
#[derive(Debug)]
pub struct SuspendedContext(Context);
impl SuspendedContext {
/// Creates a new suspended imgui-rs context.
pub fn create() -> Self {
Self::create_internal()
}
/// Attempts to activate this suspended context.
///
/// If there is no active context, this suspended context is activated and `Ok` is returned,
/// containing the activated context.
/// If there is already an active context, nothing happens and `Err` is returned, containing
/// the original suspended context.
pub fn activate(self) -> Result<Context, SuspendedContext> {
let _guard = CTX_MUTEX.lock();
if no_current_context() {
unsafe {
sys::igSetCurrentContext(self.0.raw);
}
Ok(self.0)
} else {
Err(self)
}
}
fn create_internal() -> Self {
let _guard = CTX_MUTEX.lock();
let raw = unsafe { sys::igCreateContext(ptr::null_mut()) };
let ctx = Context {
raw,
ini_filename: None,
log_filename: None,
platform_name: None,
renderer_name: None,
};
if ctx.is_current_context() {
// Oops, the context was activated -> deactivate
clear_current_context();
}
SuspendedContext(ctx)
}
}
#[test]
fn test_one_context() {
let _guard = crate::test::TEST_MUTEX.lock();
let _ctx = Context::create();
assert!(!no_current_context());
}
#[test]
fn test_drop_clears_current_context() {
let _guard = crate::test::TEST_MUTEX.lock();
{
let _ctx1 = Context::create();
assert!(!no_current_context());
}
assert!(no_current_context());
{
let _ctx2 = Context::create();
assert!(!no_current_context());
}
assert!(no_current_context());
}
#[test]
fn test_new_suspended() {
let _guard = crate::test::TEST_MUTEX.lock();
let ctx = Context::create();
let _suspended = SuspendedContext::create();
assert!(ctx.is_current_context());
::std::mem::drop(_suspended);
assert!(ctx.is_current_context());
}
#[test]
fn test_suspend() {
let _guard = crate::test::TEST_MUTEX.lock();
let ctx = Context::create();
assert!(!no_current_context());
let _suspended = ctx.suspend();
assert!(no_current_context());
let _ctx2 = Context::create();
}
#[test]
fn test_drop_suspended() {
let _guard = crate::test::TEST_MUTEX.lock();
let suspended = Context::create().suspend();
assert!(no_current_context());
let ctx2 = Context::create();
::std::mem::drop(suspended);
assert!(ctx2.is_current_context());
}
#[test]
fn test_suspend_activate() {
let _guard = crate::test::TEST_MUTEX.lock();
let suspended = Context::create().suspend();
assert!(no_current_context());
let ctx = suspended.activate().unwrap();
assert!(ctx.is_current_context());
}
#[test]
fn test_suspend_failure() {
let _guard = crate::test::TEST_MUTEX.lock();
let suspended = Context::create().suspend();
let _ctx = Context::create();
assert!(suspended.activate().is_err());
}
#[test]
fn test_ini_load_save() {
let (_guard, mut ctx) = crate::test::test_ctx();
let data = "[Window][Debug##Default]
Pos=60,60
Size=400,400
Collapsed=0";
ctx.load_ini_settings(&data);
let mut buf = String::new();
ctx.save_ini_settings(&mut buf);
assert_eq!(data.trim(), buf.trim());
}

View File

@ -1,4 +1,6 @@
pub extern crate imgui_sys as sys;
#[macro_use]
extern crate lazy_static;
use std::ffi::CStr;
use std::mem;
@ -13,6 +15,7 @@ pub use self::color_editors::{
ColorButton, ColorEdit, ColorEditMode, ColorFormat, ColorPicker, ColorPickerMode, ColorPreview,
EditableColor,
};
pub use self::context::*;
pub use self::drag::{
DragFloat, DragFloat2, DragFloat3, DragFloat4, DragFloatRange2, DragInt, DragInt2, DragInt3,
DragInt4, DragIntRange2,
@ -46,6 +49,7 @@ use internal::RawCast;
mod child_frame;
mod color_editors;
mod context;
mod drag;
mod fonts;
mod image;
@ -59,17 +63,12 @@ mod progressbar;
mod sliders;
mod string;
mod style;
#[cfg(test)]
mod test;
mod trees;
mod window;
mod window_draw_list;
pub struct ImGui {
// We need to keep ownership of the ImStr values to ensure the *const char pointer
// lives long enough in case the ImStr contains a Cow::Owned
ini_filename: Option<ImString>,
log_filename: Option<ImString>,
}
pub struct TextureHandle<'a> {
pub width: u32,
pub height: u32,
@ -108,16 +107,7 @@ impl FrameSize {
}
}
impl ImGui {
pub fn init() -> ImGui {
unsafe {
sys::igCreateContext(ptr::null_mut());
}
ImGui {
ini_filename: None,
log_filename: None,
}
}
impl Context {
fn io(&self) -> &sys::ImGuiIO {
unsafe { &*sys::igGetIO() }
}
@ -160,26 +150,6 @@ impl ImGui {
pub fn set_font_texture_id(&mut self, value: ImTexture) {
self.fonts().set_texture_id(value.id());
}
pub fn set_ini_filename(&mut self, value: Option<ImString>) {
{
let io = self.io_mut();
io.IniFilename = match value {
Some(ref x) => x.as_ptr(),
None => ptr::null(),
}
}
self.ini_filename = value;
}
pub fn set_log_filename(&mut self, value: Option<ImString>) {
{
let io = self.io_mut();
io.LogFilename = match value {
Some(ref x) => x.as_ptr(),
None => ptr::null(),
}
}
self.log_filename = value;
}
pub fn set_ini_saving_rate(&mut self, value: f32) {
let io = self.io_mut();
io.IniSavingRate = value;
@ -391,31 +361,14 @@ impl ImGui {
}
unsafe {
sys::igNewFrame();
CURRENT_UI = Some(Ui {
imgui: mem::transmute(self as &'a ImGui),
frame_size,
needs_cleanup: false,
});
}
Ui {
imgui: self,
frame_size,
needs_cleanup: true,
}
}
}
impl Drop for ImGui {
fn drop(&mut self) {
unsafe {
CURRENT_UI = None;
sys::igDestroyContext(ptr::null_mut());
}
}
}
static mut CURRENT_UI: Option<Ui<'static>> = None;
pub struct DrawData<'a> {
raw: &'a mut sys::ImDrawData,
}
@ -493,9 +446,8 @@ pub struct DrawList<'a> {
}
pub struct Ui<'ui> {
imgui: &'ui ImGui,
imgui: &'ui Context,
frame_size: FrameSize,
needs_cleanup: bool,
}
static FMT: &'static [u8] = b"%s\0";
@ -508,7 +460,7 @@ impl<'ui> Ui<'ui> {
pub fn frame_size(&self) -> FrameSize {
self.frame_size
}
pub fn imgui(&self) -> &ImGui {
pub fn imgui(&self) -> &Context {
self.imgui
}
pub fn want_capture_mouse(&self) -> bool {
@ -579,21 +531,14 @@ impl<'ui> Ui<'ui> {
impl<'a> Drop for Ui<'a> {
fn drop(&mut self) {
if self.needs_cleanup && !thread::panicking() {
if !thread::panicking() {
unsafe {
sys::igEndFrame();
CURRENT_UI = None;
}
}
}
}
impl<'a> Ui<'a> {
pub unsafe fn current_ui() -> Option<&'a Ui<'a>> {
CURRENT_UI.as_ref()
}
}
// Window
impl<'ui> Ui<'ui> {
pub fn window<'p>(&self, name: &'p ImStr) -> Window<'ui, 'p> {
@ -1222,7 +1167,7 @@ impl<'ui> Ui<'ui> {
/// # Example
/// ```rust,no_run
/// # use imgui::*;
/// # let mut imgui = ImGui::init();
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame(FrameSize::new(100.0, 100.0, 1.0), 0.1);
/// if ui.button(im_str!("Show modal"), (0.0, 0.0)) {
/// ui.open_popup(im_str!("modal"));
@ -1302,7 +1247,7 @@ impl<'ui> Ui<'ui> {
/// # Example
/// ```rust,no_run
/// # use imgui::*;
/// # let mut imgui = ImGui::init();
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame(FrameSize::new(100.0, 100.0, 1.0), 0.1);
/// # let mut selected_radio_value = 2;
/// ui.radio_button(im_str!("Item 1"), &mut selected_radio_value, 1);
@ -1319,7 +1264,7 @@ impl<'ui> Ui<'ui> {
/// # Example
/// ```rust,no_run
/// # use imgui::*;
/// # let mut imgui = ImGui::init();
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame(FrameSize::new(100.0, 100.0, 1.0), 0.1);
/// # let mut radio_button_test = "cats".to_string();
/// if ui.radio_button_bool(im_str!("Cats"), radio_button_test == "cats") {
@ -1412,7 +1357,7 @@ impl<'ui> Ui<'ui> {
/// # Example
/// ```rust,no_run
/// # use imgui::*;
/// # let mut imgui = ImGui::init();
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame(FrameSize::new(100.0, 100.0, 1.0), 0.1);
/// ui.progress_bar(0.6)
/// .size((100.0, 12.0))
@ -1430,7 +1375,7 @@ impl<'ui> Ui<'ui> {
/// # Example
/// ```rust,no_run
/// # use imgui::*;
/// # let mut imgui = ImGui::init();
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame(FrameSize::new(100.0, 100.0, 1.0), 0.1);
/// ui.window(im_str!("ChatWindow"))
/// .title_bar(true)
@ -1460,7 +1405,7 @@ impl<'ui> Ui<'ui> {
/// # Example
/// ```rust,no_run
/// # use imgui::*;
/// # let mut imgui = ImGui::init();
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame(FrameSize::new(100.0, 100.0, 1.0), 0.1);
/// ui.with_style_var(StyleVar::Alpha(0.2), || {
/// ui.text(im_str!("AB"));
@ -1478,7 +1423,7 @@ impl<'ui> Ui<'ui> {
/// # Example
/// ```rust,no_run
/// # use imgui::*;
/// # let mut imgui = ImGui::init();
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame(FrameSize::new(100.0, 100.0, 1.0), 0.1);
/// # let styles = [StyleVar::Alpha(0.2), StyleVar::WindowPadding([1.0, 1.0])];
/// ui.with_style_vars(&styles, || {
@ -1578,7 +1523,7 @@ impl<'ui> Ui<'ui> {
/// # Example
/// ```rust,no_run
/// # use imgui::*;
/// # let mut imgui = ImGui::init();
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame(FrameSize::new(100.0, 100.0, 1.0), 0.1);
/// ui.with_color_var(StyleColor::Text, [1.0, 0.0, 0.0, 1.0], || {
/// ui.text_wrapped(im_str!("AB"));
@ -1604,7 +1549,7 @@ impl<'ui> Ui<'ui> {
/// # Example
/// ```rust,no_run
/// # use imgui::*;
/// # let mut imgui = ImGui::init();
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame(FrameSize::new(100.0, 100.0, 1.0), 0.1);
/// let red = [1.0, 0.0, 0.0, 1.0];
/// let green = [0.0, 1.0, 0.0, 1.0];

15
src/test.rs Normal file
View File

@ -0,0 +1,15 @@
use parking_lot::{ReentrantMutex, ReentrantMutexGuard};
use std::ptr;
use crate::context::Context;
lazy_static! {
pub static ref TEST_MUTEX: ReentrantMutex<()> = ReentrantMutex::new(());
}
pub fn test_ctx() -> (ReentrantMutexGuard<'static, ()>, Context) {
let guard = TEST_MUTEX.lock();
let mut ctx = Context::create();
ctx.io_mut().IniFilename = ptr::null();
(guard, ctx)
}