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}