Skip to main content

dear_imgui_rs/context/
suspended.rs

1use std::ptr;
2use std::rc::Rc;
3
4use crate::clipboard::ClipboardContext;
5use crate::fonts::SharedFontAtlas;
6use crate::sys;
7
8use super::Context;
9use super::binding::{CTX_MUTEX, clear_current_context, no_current_context};
10
11impl Context {
12    /// Suspends this context so another context can be the active context
13    pub fn suspend(self) -> SuspendedContext {
14        let _guard = CTX_MUTEX.lock();
15        assert!(
16            self.is_current_context(),
17            "context to be suspended is not the active context"
18        );
19        clear_current_context();
20        SuspendedContext(self)
21    }
22}
23
24/// A suspended Dear ImGui context
25///
26/// A suspended context retains its state, but is not usable without activating it first.
27#[derive(Debug)]
28pub struct SuspendedContext(pub(super) Context);
29
30impl SuspendedContext {
31    /// Tries to create a new suspended Dear ImGui context
32    pub fn try_create() -> crate::error::ImGuiResult<Self> {
33        Self::try_create_internal(None)
34    }
35
36    /// Tries to create a new suspended Dear ImGui context with a shared font atlas
37    pub fn try_create_with_shared_font_atlas(
38        shared_font_atlas: SharedFontAtlas,
39    ) -> crate::error::ImGuiResult<Self> {
40        Self::try_create_internal(Some(shared_font_atlas))
41    }
42
43    /// Creates a new suspended Dear ImGui context (panics on error)
44    pub fn create() -> Self {
45        Self::try_create().expect("Failed to create Dear ImGui context")
46    }
47
48    /// Creates a new suspended Dear ImGui context with a shared font atlas (panics on error)
49    pub fn create_with_shared_font_atlas(shared_font_atlas: SharedFontAtlas) -> Self {
50        Self::try_create_with_shared_font_atlas(shared_font_atlas)
51            .expect("Failed to create Dear ImGui context")
52    }
53
54    // removed legacy create_or_panic variants (use create()/try_create())
55
56    fn try_create_internal(
57        mut shared_font_atlas: Option<SharedFontAtlas>,
58    ) -> crate::error::ImGuiResult<Self> {
59        let _guard = CTX_MUTEX.lock();
60
61        let shared_font_atlas_ptr = match &mut shared_font_atlas {
62            Some(atlas) => atlas.as_ptr_mut(),
63            None => ptr::null_mut(),
64        };
65
66        let raw = unsafe { sys::igCreateContext(shared_font_atlas_ptr) };
67        if raw.is_null() {
68            return Err(crate::error::ImGuiError::ContextCreation {
69                reason: "ImGui_CreateContext returned null".to_string(),
70            });
71        }
72
73        let alive = Rc::new(());
74        let ui = crate::ui::Ui::new(raw, super::core::ContextAliveToken::new(&alive));
75
76        let ctx = Context {
77            raw,
78            alive,
79            shared_font_atlas,
80            ini_filename: None,
81            log_filename: None,
82            platform_name: None,
83            renderer_name: None,
84            clipboard_ctx: Box::new(ClipboardContext::dummy()),
85            ui,
86        };
87
88        // If the context was activated during creation, deactivate it
89        if ctx.is_current_context() {
90            clear_current_context();
91        }
92
93        Ok(SuspendedContext(ctx))
94    }
95
96    /// Attempts to activate this suspended context
97    ///
98    /// If there is no active context, this suspended context is activated and `Ok` is returned.
99    /// If there is already an active context, nothing happens and `Err` is returned.
100    pub fn activate(self) -> Result<Context, SuspendedContext> {
101        let _guard = CTX_MUTEX.lock();
102        if no_current_context() {
103            unsafe {
104                sys::igSetCurrentContext(self.0.raw);
105            }
106            Ok(self.0)
107        } else {
108            Err(self)
109        }
110    }
111}