dear-imgui-rs 0.17.0

High-level Rust bindings to Dear ImGui v1.92.9b with docking, WGPU/GL backends, and extensions (ImPlot/ImPlot3D, ImNodes, ImGuizmo, file browser, reflection-based UI)
Documentation
use super::validation::assert_finite_vec2;
use crate::Ui;
use crate::scope::{NativeScopePop, NativeScopeToken};
use crate::sys;

/// Tracks a pushed clip rect that will be popped on drop.
///
/// Tokens for the same draw list must be ended in LIFO order. Prefer
/// [`Ui::with_clip_rect`] for ordinary scoped use.
#[must_use]
pub struct ClipRectToken<'ui> {
    scope: NativeScopeToken<'ui>,
}

impl ClipRectToken<'_> {
    /// Pops a clip rect pushed with [`Ui::push_clip_rect`].
    ///
    /// # Panics
    ///
    /// Panics before FFI if a later UI clip token for the same draw list is active or the token is
    /// no longer in its originating window `Begin` scope.
    pub fn end(self) {}
}

impl Drop for ClipRectToken<'_> {
    fn drop(&mut self) {
        self.scope.finish();
    }
}

impl Ui {
    /// Push a clipping rectangle in screen space.
    #[doc(alias = "PushClipRect")]
    pub fn push_clip_rect(
        &self,
        min: impl Into<[f32; 2]>,
        max: impl Into<[f32; 2]>,
        intersect_with_current: bool,
    ) -> ClipRectToken<'_> {
        let min = min.into();
        let max = max.into();
        assert_finite_vec2("Ui::push_clip_rect()", "min", min);
        assert_finite_vec2("Ui::push_clip_rect()", "max", max);
        let min_v = sys::ImVec2 {
            x: min[0],
            y: min[1],
        };
        let max_v = sys::ImVec2 {
            x: max[0],
            y: max[1],
        };
        let draw_list = self.run_with_bound_context(|| unsafe {
            sys::igPushClipRect(min_v, max_v, intersect_with_current);
            sys::igGetWindowDrawList()
        });
        assert!(
            !draw_list.is_null(),
            "Ui::push_clip_rect() requires a current window draw list"
        );
        ClipRectToken {
            scope: self
                .begin_native_scope(NativeScopePop::PopUiClipRect(draw_list), "ClipRectToken"),
        }
    }

    /// Run a closure with a clip rect pushed and automatically popped.
    pub fn with_clip_rect<R>(
        &self,
        min: impl Into<[f32; 2]>,
        max: impl Into<[f32; 2]>,
        intersect_with_current: bool,
        f: impl FnOnce() -> R,
    ) -> R {
        let token = self.push_clip_rect(min, max, intersect_with_current);
        let result = f();
        drop(token);
        result
    }

    /// Returns true if the specified rectangle (min,max) is visible (not clipped).
    #[doc(alias = "IsRectVisible")]
    pub fn is_rect_visible_min_max(
        &self,
        rect_min: impl Into<[f32; 2]>,
        rect_max: impl Into<[f32; 2]>,
    ) -> bool {
        let mn = rect_min.into();
        let mx = rect_max.into();
        assert_finite_vec2("Ui::is_rect_visible_min_max()", "rect_min", mn);
        assert_finite_vec2("Ui::is_rect_visible_min_max()", "rect_max", mx);
        let mn_v = sys::ImVec2 { x: mn[0], y: mn[1] };
        let mx_v = sys::ImVec2 { x: mx[0], y: mx[1] };
        self.run_with_bound_context(|| unsafe { sys::igIsRectVisible_Vec2(mn_v, mx_v) })
    }

    /// Returns true if a rectangle of given size at the current cursor pos is visible.
    #[doc(alias = "IsRectVisible")]
    pub fn is_rect_visible_with_size(&self, size: impl Into<[f32; 2]>) -> bool {
        let s = size.into();
        assert_finite_vec2("Ui::is_rect_visible_with_size()", "size", s);
        let v = sys::ImVec2 { x: s[0], y: s[1] };
        self.run_with_bound_context(|| unsafe { sys::igIsRectVisible_Nil(v) })
    }
}