Skip to main content

dear_imnodes/
style.rs

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
93/// Style helpers available from NodeEditor
94impl<'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        // Use Dear ImGui's helper for packing RGBA -> ABGR (u32)
107        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
173/// Convert RGBA floats [0,1] to ImGui-packed ABGR (u32)
174pub 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
185/// Convert ImGui-packed ABGR (u32) to RGBA floats [0,1]
186pub 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}