Skip to main content

dear_imnodes/context/editor/
minimap.rs

1use super::super::{MiniMapCallbackHolder, NodeEditor};
2use crate::sys;
3use std::os::raw::c_void;
4
5impl<'ui> NodeEditor<'ui> {
6    /// Draw a minimap in the editor
7    pub fn minimap(&self, size_fraction: f32, location: crate::MiniMapLocation) {
8        self.bind();
9        unsafe {
10            sys::imnodes_MiniMap(
11                size_fraction,
12                location as sys::ImNodesMiniMapLocation,
13                None,
14                std::ptr::null_mut(),
15            )
16        }
17    }
18
19    /// Draw a minimap with a node-hover callback (invoked during this call)
20    pub fn minimap_with_callback<F>(
21        &mut self,
22        size_fraction: f32,
23        location: crate::MiniMapLocation,
24        callback: F,
25    ) where
26        F: FnMut(i32) + 'ui,
27    {
28        unsafe extern "C" fn trampoline(node_id: i32, user: *mut c_void) {
29            if user.is_null() {
30                return;
31            }
32            let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| unsafe {
33                let holder = &mut *(user as *mut MiniMapCallbackHolder<'_>);
34                (holder.callback)(node_id);
35            }));
36            if res.is_err() {
37                eprintln!("dear-imnodes: panic in minimap callback");
38                std::process::abort();
39            }
40        }
41
42        // ImNodes may invoke the callback during EndNodeEditor(). Keep the closure alive for the
43        // whole editor frame by storing it inside the NodeEditor token.
44        self.bind();
45        self.minimap_callbacks.push(Box::new(MiniMapCallbackHolder {
46            callback: Box::new(callback),
47        }));
48        let user_ptr = self
49            .minimap_callbacks
50            .last_mut()
51            .map(|b| b.as_mut() as *mut MiniMapCallbackHolder<'ui> as *mut c_void)
52            .unwrap_or(std::ptr::null_mut());
53        unsafe {
54            sys::imnodes_MiniMap(
55                size_fraction,
56                location as sys::ImNodesMiniMapLocation,
57                Some(trampoline),
58                user_ptr,
59            )
60        }
61    }
62}