implot/
context.rs

1//! Module for handling the ImPlot context. This is modeled quite directly after how
2//! this is dealt with in imgui-rs, because it follows the same concepts and doing this
3//! also helps readability if one is already familiar with the imgui code.
4
5use parking_lot::ReentrantMutex;
6
7use crate::sys;
8use crate::PlotUi;
9/// An implot context.
10///
11/// A context is required to do most of the things this library provides. While this was created
12/// implicitly in earlier versions of the library, it is now created explicitly. These contexts
13/// cannot currently be disabled through the high level API. This could be implemented though,
14/// if you need multiple contexts that you can switch around between, file an issue.
15#[rustversion::attr(since(1.48), doc(alias = "ImPlotContext"))]
16pub struct Context {
17    raw: *mut sys::ImPlotContext,
18}
19
20// This mutex is used to guard any accesses to the context
21static CTX_MUTEX: ReentrantMutex<()> = parking_lot::const_reentrant_mutex(());
22
23/// Check if there is no current context defined by calling into the C++ API
24fn no_current_context() -> bool {
25    let ctx = unsafe { sys::ImPlot_GetCurrentContext() };
26    ctx.is_null()
27}
28
29impl Context {
30    /// Create a context. This will also activate the context in ImPlot, and hence creating
31    /// a second context when one already exists is an error and will panic.
32    pub fn create() -> Self {
33        let _guard = CTX_MUTEX.lock();
34        assert!(
35            no_current_context(),
36            "A new active context cannot be created, because another one already exists"
37        );
38
39        let ctx = unsafe { sys::ImPlot_CreateContext() };
40        unsafe {
41            sys::ImPlot_SetCurrentContext(ctx);
42        }
43        Self { raw: ctx }
44    }
45
46    /// Get a "plot ui" struct, this will be used to build actual plots and is quite
47    /// analogous to imgui-rs' "Ui" struct.
48    pub fn get_plot_ui(&self) -> PlotUi {
49        PlotUi { context: self }
50    }
51
52    /// Use light colors for the implot style.
53    ///
54    /// This will eventually be exposed more thoroughly in the form of ImPlotStyle,
55    /// but for now this allows one to at least easily set the color preset.
56    pub fn use_light_colors(&self) {
57        unsafe {
58            let style = sys::ImPlot_GetStyle();
59            assert_ne!(style, std::ptr::null_mut());
60            sys::ImPlot_StyleColorsLight(style);
61        }
62    }
63
64    /// Use dark colors for the implot style.
65    ///
66    /// This will eventually be exposed more thoroughly in the form of ImPlotStyle,
67    /// but for now this allows one to at least easily set the color preset.
68    pub fn use_dark_colors(&self) {
69        unsafe {
70            let style = sys::ImPlot_GetStyle();
71            assert_ne!(style, std::ptr::null_mut());
72            sys::ImPlot_StyleColorsDark(style);
73        }
74    }
75
76    /// Use classic colors for the implot style.
77    ///
78    /// This will eventually be exposed more thoroughly in the form of ImPlotStyle,
79    /// but for now this allows one to at least easily set the color preset.
80    pub fn use_classic_colors(&self) {
81        unsafe {
82            let style = sys::ImPlot_GetStyle();
83            assert_ne!(style, std::ptr::null_mut());
84            sys::ImPlot_StyleColorsClassic(style);
85        }
86    }
87}
88
89impl Drop for Context {
90    fn drop(&mut self) {
91        let _guard = CTX_MUTEX.lock();
92        unsafe {
93            sys::ImPlot_DestroyContext(self.raw);
94        }
95    }
96}