Skip to main content

dear_imgui_rs/draw/
counts.rs

1use bitflags::bitflags;
2use std::num::NonZeroUsize;
3
4use crate::sys;
5
6use super::util::count_to_i32;
7
8// Removed legacy local Vec2 in favor of passing `impl Into<sys::ImVec2>` and using arrays/tuples.
9bitflags! {
10    /// Draw list flags
11    #[repr(transparent)]
12    pub struct DrawListFlags: i32 {
13        /// No flags
14        const NONE = sys::ImDrawListFlags_None as i32;
15        /// Enable anti-aliased lines/borders
16        const ANTI_ALIASED_LINES = sys::ImDrawListFlags_AntiAliasedLines as i32;
17        /// Enable anti-aliased lines/borders using textures where possible
18        const ANTI_ALIASED_LINES_USE_TEX = sys::ImDrawListFlags_AntiAliasedLinesUseTex as i32;
19        /// Enable anti-aliased edge around filled shapes
20        const ANTI_ALIASED_FILL = sys::ImDrawListFlags_AntiAliasedFill as i32;
21        /// Can emit 'VtxOffset > 0' to allow large meshes
22        const ALLOW_VTX_OFFSET = sys::ImDrawListFlags_AllowVtxOffset as i32;
23    }
24}
25
26/// Segment count for draw-list APIs where Dear ImGui accepts `0` as "auto".
27#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
28pub struct DrawSegmentCount(Option<NonZeroUsize>);
29
30impl DrawSegmentCount {
31    /// Let Dear ImGui choose the tessellation count.
32    pub const AUTO: Self = Self(None);
33
34    #[inline]
35    pub const fn auto() -> Self {
36        Self::AUTO
37    }
38
39    /// Create an explicit positive segment count.
40    #[inline]
41    pub const fn new(count: usize) -> Option<Self> {
42        if count > 0 && count <= i32::MAX as usize {
43            match NonZeroUsize::new(count) {
44                Some(count) => Some(Self(Some(count))),
45                None => None,
46            }
47        } else {
48            None
49        }
50    }
51
52    /// Create an explicit positive segment count.
53    ///
54    /// Panics if `count` is zero or exceeds Dear ImGui's `int` range.
55    #[inline]
56    pub const fn count(count: usize) -> Self {
57        match Self::new(count) {
58            Some(count) => count,
59            None => {
60                panic!(
61                    "DrawSegmentCount::count() requires a positive count within Dear ImGui's i32 range"
62                )
63            }
64        }
65    }
66
67    /// Return the explicit segment count, or `None` for automatic tessellation.
68    #[inline]
69    pub const fn get(self) -> Option<usize> {
70        match self.0 {
71            Some(count) => Some(count.get()),
72            None => None,
73        }
74    }
75
76    #[inline]
77    pub(super) fn into_i32(self, caller: &str) -> i32 {
78        match self.0 {
79            Some(count) => count_to_i32(caller, "num_segments", count.get()),
80            None => 0,
81        }
82    }
83}
84
85impl From<NonZeroUsize> for DrawSegmentCount {
86    #[inline]
87    fn from(value: NonZeroUsize) -> Self {
88        Self::new(value.get()).expect("segment count exceeded Dear ImGui's i32 range")
89    }
90}
91
92/// Segment count for regular n-gon drawing. Dear ImGui requires at least three sides.
93#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
94pub struct DrawNgonSegmentCount(usize);
95
96impl DrawNgonSegmentCount {
97    #[inline]
98    pub fn new(count: usize) -> Option<Self> {
99        (count >= 3 && count <= i32::MAX as usize).then_some(Self(count))
100    }
101
102    #[inline]
103    pub const fn get(self) -> usize {
104        self.0
105    }
106
107    #[inline]
108    pub(super) fn into_i32(self, caller: &str) -> i32 {
109        assert!(self.0 >= 3, "{caller} num_segments must be at least 3");
110        count_to_i32(caller, "num_segments", self.0)
111    }
112}
113
114impl TryFrom<usize> for DrawNgonSegmentCount {
115    type Error = ();
116
117    #[inline]
118    fn try_from(value: usize) -> Result<Self, Self::Error> {
119        Self::new(value).ok_or(())
120    }
121}
122
123bitflags! {
124    /// Flags accepted by `AddPolyline()` and `PathStroke()`.
125    #[repr(transparent)]
126    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
127    pub struct PolylineFlags: u32 {
128        const NONE = sys::ImDrawFlags_None as u32;
129        const CLOSED = sys::ImDrawFlags_Closed as u32;
130    }
131}
132
133impl Default for PolylineFlags {
134    fn default() -> Self {
135        Self::NONE
136    }
137}
138
139bitflags! {
140    /// Corner rounding flags accepted by rectangle and rounded-image drawing APIs.
141    ///
142    /// Dear ImGui uses zero as "default to all corners" when `rounding > 0`.
143    /// Use [`DrawCornerFlags::NO_ROUNDING`] to explicitly disable rounding.
144    #[repr(transparent)]
145    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
146    pub struct DrawCornerFlags: u32 {
147        const DEFAULT = sys::ImDrawFlags_None as u32;
148        const TOP_LEFT = sys::ImDrawFlags_RoundCornersTopLeft as u32;
149        const TOP_RIGHT = sys::ImDrawFlags_RoundCornersTopRight as u32;
150        const BOTTOM_LEFT = sys::ImDrawFlags_RoundCornersBottomLeft as u32;
151        const BOTTOM_RIGHT = sys::ImDrawFlags_RoundCornersBottomRight as u32;
152        const TOP = sys::ImDrawFlags_RoundCornersTop as u32;
153        const BOTTOM = sys::ImDrawFlags_RoundCornersBottom as u32;
154        const LEFT = sys::ImDrawFlags_RoundCornersLeft as u32;
155        const RIGHT = sys::ImDrawFlags_RoundCornersRight as u32;
156        const ALL = sys::ImDrawFlags_RoundCornersAll as u32;
157        const NO_ROUNDING = sys::ImDrawFlags_RoundCornersNone as u32;
158    }
159}
160
161impl Default for DrawCornerFlags {
162    fn default() -> Self {
163        Self::DEFAULT
164    }
165}