1use crate::context::ImNodesScope;
2use crate::sys;
3use dear_imgui_rs::sys as imgui_sys;
4use std::marker::PhantomData;
5
6#[repr(u32)]
7#[derive(Copy, Clone, Debug, PartialEq, Eq)]
8pub enum ColorElement {
9 NodeBackground = sys::ImNodesCol_NodeBackground as u32,
10 NodeBackgroundHovered = sys::ImNodesCol_NodeBackgroundHovered as u32,
11 NodeBackgroundSelected = sys::ImNodesCol_NodeBackgroundSelected as u32,
12 NodeOutline = sys::ImNodesCol_NodeOutline as u32,
13 TitleBar = sys::ImNodesCol_TitleBar as u32,
14 TitleBarHovered = sys::ImNodesCol_TitleBarHovered as u32,
15 TitleBarSelected = sys::ImNodesCol_TitleBarSelected as u32,
16 Link = sys::ImNodesCol_Link as u32,
17 LinkHovered = sys::ImNodesCol_LinkHovered as u32,
18 LinkSelected = sys::ImNodesCol_LinkSelected as u32,
19 Pin = sys::ImNodesCol_Pin as u32,
20 PinHovered = sys::ImNodesCol_PinHovered as u32,
21 BoxSelector = sys::ImNodesCol_BoxSelector as u32,
22 BoxSelectorOutline = sys::ImNodesCol_BoxSelectorOutline as u32,
23 GridBackground = sys::ImNodesCol_GridBackground as u32,
24 GridLine = sys::ImNodesCol_GridLine as u32,
25 GridLinePrimary = sys::ImNodesCol_GridLinePrimary as u32,
26 MiniMapBackground = sys::ImNodesCol_MiniMapBackground as u32,
27 MiniMapBackgroundHovered = sys::ImNodesCol_MiniMapBackgroundHovered as u32,
28 MiniMapOutline = sys::ImNodesCol_MiniMapOutline as u32,
29 MiniMapOutlineHovered = sys::ImNodesCol_MiniMapOutlineHovered as u32,
30 MiniMapNodeBackground = sys::ImNodesCol_MiniMapNodeBackground as u32,
31 MiniMapNodeBackgroundHovered = sys::ImNodesCol_MiniMapNodeBackgroundHovered as u32,
32 MiniMapNodeBackgroundSelected = sys::ImNodesCol_MiniMapNodeBackgroundSelected as u32,
33 MiniMapNodeOutline = sys::ImNodesCol_MiniMapNodeOutline as u32,
34 MiniMapLink = sys::ImNodesCol_MiniMapLink as u32,
35 MiniMapLinkSelected = sys::ImNodesCol_MiniMapLinkSelected as u32,
36 MiniMapCanvas = sys::ImNodesCol_MiniMapCanvas as u32,
37 MiniMapCanvasOutline = sys::ImNodesCol_MiniMapCanvasOutline as u32,
38}
39
40pub struct ColorToken<'a> {
41 scope: ImNodesScope,
42 _phantom: PhantomData<&'a crate::Context>,
43}
44impl<'a> ColorToken<'a> {
45 pub fn pop(self) {}
46}
47impl Drop for ColorToken<'_> {
48 fn drop(&mut self) {
49 unsafe {
50 self.scope.bind();
51 sys::imnodes_PopColorStyle();
52 }
53 }
54}
55
56pub struct StyleVarToken<'a> {
57 scope: ImNodesScope,
58 _phantom: PhantomData<&'a crate::Context>,
59}
60impl<'a> StyleVarToken<'a> {
61 pub fn pop(self) {}
62}
63impl Drop for StyleVarToken<'_> {
64 fn drop(&mut self) {
65 unsafe {
66 self.scope.bind();
67 sys::imnodes_PopStyleVar(1);
68 }
69 }
70}
71
72pub enum StyleVarValue {
73 Float(f32),
74 Vec2([f32; 2]),
75}
76
77pub struct AttributeFlagToken<'a> {
78 scope: ImNodesScope,
79 _phantom: PhantomData<&'a crate::Context>,
80}
81impl<'a> AttributeFlagToken<'a> {
82 pub fn pop(self) {}
83}
84impl Drop for AttributeFlagToken<'_> {
85 fn drop(&mut self) {
86 unsafe {
87 self.scope.bind();
88 sys::imnodes_PopAttributeFlag();
89 }
90 }
91}
92
93impl<'ui> crate::NodeEditor<'ui> {
95 pub fn push_attribute_flag(&self, flag: crate::AttributeFlags) -> AttributeFlagToken<'_> {
96 self.bind();
97 unsafe { sys::imnodes_PushAttributeFlag(flag.bits()) };
98 AttributeFlagToken {
99 scope: self.scope(),
100 _phantom: PhantomData,
101 }
102 }
103
104 pub fn push_color(&self, elem: ColorElement, color: [f32; 4]) -> ColorToken<'_> {
105 self.bind();
106 let col = unsafe {
108 imgui_sys::igColorConvertFloat4ToU32(imgui_sys::ImVec4 {
109 x: color[0],
110 y: color[1],
111 z: color[2],
112 w: color[3],
113 })
114 };
115 unsafe { sys::imnodes_PushColorStyle(elem as i32, col) };
116 ColorToken {
117 scope: self.scope(),
118 _phantom: PhantomData,
119 }
120 }
121
122 pub fn push_style_var(&self, var: crate::StyleVar, value: StyleVarValue) -> StyleVarToken<'_> {
123 self.bind();
124 match value {
125 StyleVarValue::Float(v) => unsafe { sys::imnodes_PushStyleVar_Float(var as i32, v) },
126 StyleVarValue::Vec2(v) => unsafe {
127 sys::imnodes_PushStyleVar_Vec2(var as i32, sys::ImVec2_c { x: v[0], y: v[1] })
128 },
129 }
130 StyleVarToken {
131 scope: self.scope(),
132 _phantom: PhantomData,
133 }
134 }
135
136 pub fn push_style_var_f32(&self, var: i32, value: f32) -> StyleVarToken<'_> {
137 let max = sys::ImNodesStyleVar_COUNT as i32;
138 assert!(
139 (0..max).contains(&var),
140 "dear-imnodes: invalid style var index {var}"
141 );
142 self.bind();
143 unsafe { sys::imnodes_PushStyleVar_Float(var, value) };
144 StyleVarToken {
145 scope: self.scope(),
146 _phantom: PhantomData,
147 }
148 }
149
150 pub fn push_style_var_vec2(&self, var: i32, value: [f32; 2]) -> StyleVarToken<'_> {
151 let max = sys::ImNodesStyleVar_COUNT as i32;
152 assert!(
153 (0..max).contains(&var),
154 "dear-imnodes: invalid style var index {var}"
155 );
156 self.bind();
157 unsafe {
158 sys::imnodes_PushStyleVar_Vec2(
159 var,
160 sys::ImVec2_c {
161 x: value[0],
162 y: value[1],
163 },
164 )
165 };
166 StyleVarToken {
167 scope: self.scope(),
168 _phantom: PhantomData,
169 }
170 }
171}
172
173pub fn rgba_to_abgr_u32(rgba: [f32; 4]) -> u32 {
175 unsafe {
176 imgui_sys::igColorConvertFloat4ToU32(imgui_sys::ImVec4 {
177 x: rgba[0],
178 y: rgba[1],
179 z: rgba[2],
180 w: rgba[3],
181 }) as u32
182 }
183}
184
185pub fn abgr_u32_to_rgba(col: u32) -> [f32; 4] {
187 let out = unsafe { imgui_sys::igColorConvertU32ToFloat4(col) };
188 [out.x, out.y, out.z, out.w]
189}