Skip to main content

dear_imnodes/context/editor/
style_io.rs

1use super::super::NodeEditor;
2use crate::sys;
3use dear_imgui_rs::sys as imgui_sys;
4
5impl<'ui> NodeEditor<'ui> {
6    /// Toggle style flags (GridLines, GridLinesPrimary, GridSnapping, NodeOutline)
7    pub fn set_style_flag(&self, flag: crate::StyleFlags, enabled: bool) {
8        let style = self.style_ptr();
9        unsafe {
10            let style = &mut *style;
11            let mut f = style.Flags as i32;
12            let bit = flag.bits();
13            if enabled {
14                f |= bit;
15            } else {
16                f &= !bit;
17            }
18            style.Flags = f;
19        }
20    }
21
22    /// Enable link detach with Ctrl by binding to ImGui IO KeyCtrl
23    pub fn enable_link_detach_with_ctrl(&self) {
24        let io = self.io_ptr();
25        let imgui_io = unsafe { imgui_sys::igGetIO_Nil() };
26        assert!(
27            !imgui_io.is_null(),
28            "dear-imnodes: ImGui IO must be available"
29        );
30        unsafe {
31            (*io).LinkDetachWithModifierClick.Modifier = std::ptr::addr_of!((*imgui_io).KeyCtrl);
32        }
33    }
34    /// Enable multiple select modifier as Ctrl
35    pub fn enable_multiple_select_with_ctrl(&self) {
36        let io = self.io_ptr();
37        let imgui_io = unsafe { imgui_sys::igGetIO_Nil() };
38        assert!(
39            !imgui_io.is_null(),
40            "dear-imnodes: ImGui IO must be available"
41        );
42        unsafe {
43            (*io).MultipleSelectModifier.Modifier = std::ptr::addr_of!((*imgui_io).KeyCtrl);
44        }
45    }
46    /// Enable multiple select modifier as Shift
47    pub fn enable_multiple_select_with_shift(&self) {
48        let io = self.io_ptr();
49        let imgui_io = unsafe { imgui_sys::igGetIO_Nil() };
50        assert!(
51            !imgui_io.is_null(),
52            "dear-imnodes: ImGui IO must be available"
53        );
54        unsafe {
55            (*io).MultipleSelectModifier.Modifier = std::ptr::addr_of!((*imgui_io).KeyShift);
56        }
57    }
58    /// Emulate three-button mouse with Alt
59    pub fn emulate_three_button_mouse_with_alt(&self) {
60        let io = self.io_ptr();
61        let imgui_io = unsafe { imgui_sys::igGetIO_Nil() };
62        assert!(
63            !imgui_io.is_null(),
64            "dear-imnodes: ImGui IO must be available"
65        );
66        unsafe {
67            (*io).EmulateThreeButtonMouse.Modifier = std::ptr::addr_of!((*imgui_io).KeyAlt);
68        }
69    }
70    /// IO tweaks
71    pub fn set_alt_mouse_button(&self, button: i32) {
72        let io = self.io_ptr();
73        unsafe {
74            (*io).AltMouseButton = button;
75        }
76    }
77    pub fn set_auto_panning_speed(&self, speed: f32) {
78        let io = self.io_ptr();
79        unsafe {
80            (*io).AutoPanningSpeed = speed;
81        }
82    }
83    /// Style preset helpers
84    pub fn style_colors_dark(&self) {
85        let style = self.style_ptr();
86        unsafe { sys::imnodes_StyleColorsDark(style) }
87    }
88    pub fn style_colors_classic(&self) {
89        let style = self.style_ptr();
90        unsafe { sys::imnodes_StyleColorsClassic(style) }
91    }
92    pub fn style_colors_light(&self) {
93        let style = self.style_ptr();
94        unsafe { sys::imnodes_StyleColorsLight(style) }
95    }
96
97    // state save/load moved to PostEditor
98
99    /// Node positions in grid space
100    pub fn set_node_pos_grid(&self, node_id: i32, pos: [f32; 2]) {
101        self.bind();
102        unsafe {
103            sys::imnodes_SetNodeGridSpacePos(
104                node_id,
105                sys::ImVec2_c {
106                    x: pos[0],
107                    y: pos[1],
108                },
109            )
110        }
111    }
112
113    pub fn get_node_pos_grid(&self, node_id: i32) -> [f32; 2] {
114        self.bind();
115        let out = unsafe { sys::imnodes_GetNodeGridSpacePos(node_id) };
116        [out.x, out.y]
117    }
118
119    /// Persistent style setters
120    pub fn set_grid_spacing(&self, spacing: f32) {
121        let style = self.style_ptr();
122        unsafe {
123            (*style).GridSpacing = spacing;
124        }
125    }
126    pub fn set_link_thickness(&self, thickness: f32) {
127        let style = self.style_ptr();
128        unsafe {
129            (*style).LinkThickness = thickness;
130        }
131    }
132    pub fn set_node_corner_rounding(&self, rounding: f32) {
133        let style = self.style_ptr();
134        unsafe {
135            (*style).NodeCornerRounding = rounding;
136        }
137    }
138    pub fn set_node_padding(&self, padding: [f32; 2]) {
139        let style = self.style_ptr();
140        unsafe {
141            (*style).NodePadding = sys::ImVec2_c {
142                x: padding[0],
143                y: padding[1],
144            };
145        }
146    }
147    pub fn set_pin_circle_radius(&self, r: f32) {
148        let style = self.style_ptr();
149        unsafe {
150            (*style).PinCircleRadius = r;
151        }
152    }
153    pub fn set_pin_quad_side_length(&self, v: f32) {
154        let style = self.style_ptr();
155        unsafe {
156            (*style).PinQuadSideLength = v;
157        }
158    }
159    pub fn set_pin_triangle_side_length(&self, v: f32) {
160        let style = self.style_ptr();
161        unsafe {
162            (*style).PinTriangleSideLength = v;
163        }
164    }
165    pub fn set_pin_line_thickness(&self, v: f32) {
166        let style = self.style_ptr();
167        unsafe {
168            (*style).PinLineThickness = v;
169        }
170    }
171    pub fn set_pin_hover_radius(&self, v: f32) {
172        let style = self.style_ptr();
173        unsafe {
174            (*style).PinHoverRadius = v;
175        }
176    }
177    pub fn set_pin_offset(&self, offset: f32) {
178        let style = self.style_ptr();
179        unsafe {
180            (*style).PinOffset = offset;
181        }
182    }
183    pub fn set_link_hover_distance(&self, v: f32) {
184        let style = self.style_ptr();
185        unsafe {
186            (*style).LinkHoverDistance = v;
187        }
188    }
189    pub fn set_link_line_segments_per_length(&self, v: f32) {
190        let style = self.style_ptr();
191        unsafe {
192            (*style).LinkLineSegmentsPerLength = v;
193        }
194    }
195    pub fn set_node_border_thickness(&self, v: f32) {
196        let style = self.style_ptr();
197        unsafe {
198            (*style).NodeBorderThickness = v;
199        }
200    }
201    pub fn set_minimap_padding(&self, padding: [f32; 2]) {
202        let style = self.style_ptr();
203        unsafe {
204            (*style).MiniMapPadding = sys::ImVec2_c {
205                x: padding[0],
206                y: padding[1],
207            };
208        }
209    }
210    pub fn set_minimap_offset(&self, offset: [f32; 2]) {
211        let style = self.style_ptr();
212        unsafe {
213            (*style).MiniMapOffset = sys::ImVec2_c {
214                x: offset[0],
215                y: offset[1],
216            };
217        }
218    }
219
220    pub fn set_color(&self, elem: crate::style::ColorElement, color: [f32; 4]) {
221        let style = self.style_ptr();
222        let abgr = unsafe {
223            imgui_sys::igColorConvertFloat4ToU32(imgui_sys::ImVec4 {
224                x: color[0],
225                y: color[1],
226                z: color[2],
227                w: color[3],
228            })
229        };
230        unsafe { (*style).Colors[elem as u32 as usize] = abgr };
231    }
232
233    /// Get a style color as RGBA floats [0,1]
234    pub fn get_color(&self, elem: crate::style::ColorElement) -> [f32; 4] {
235        let style = self.style_ptr();
236        let col = unsafe { (*style).Colors[elem as u32 as usize] };
237        let out = unsafe { imgui_sys::igColorConvertU32ToFloat4(col) };
238        [out.x, out.y, out.z, out.w]
239    }
240
241    /// Node positions in screen/editor space
242    pub fn set_node_pos_screen(&self, node_id: i32, pos: [f32; 2]) {
243        self.bind();
244        unsafe {
245            sys::imnodes_SetNodeScreenSpacePos(
246                node_id,
247                sys::ImVec2_c {
248                    x: pos[0],
249                    y: pos[1],
250                },
251            )
252        }
253    }
254    pub fn set_node_pos_editor(&self, node_id: i32, pos: [f32; 2]) {
255        self.bind();
256        unsafe {
257            sys::imnodes_SetNodeEditorSpacePos(
258                node_id,
259                sys::ImVec2_c {
260                    x: pos[0],
261                    y: pos[1],
262                },
263            )
264        }
265    }
266    pub fn get_node_pos_screen(&self, node_id: i32) -> [f32; 2] {
267        self.bind();
268        let out = unsafe { crate::compat_ffi::imnodes_GetNodeScreenSpacePos(node_id) };
269        [out.x, out.y]
270    }
271    pub fn get_node_pos_editor(&self, node_id: i32) -> [f32; 2] {
272        self.bind();
273        let out = unsafe { crate::compat_ffi::imnodes_GetNodeEditorSpacePos(node_id) };
274        [out.x, out.y]
275    }
276
277    /// Node drag/size helpers
278    pub fn set_node_draggable(&self, node_id: i32, draggable: bool) {
279        self.bind();
280        unsafe { sys::imnodes_SetNodeDraggable(node_id, draggable) }
281    }
282    pub fn snap_node_to_grid(&self, node_id: i32) {
283        self.bind();
284        unsafe { sys::imnodes_SnapNodeToGrid(node_id) }
285    }
286    pub fn get_node_dimensions(&self, node_id: i32) -> [f32; 2] {
287        self.bind();
288        let out = unsafe { crate::compat_ffi::imnodes_GetNodeDimensions(node_id) };
289        [out.x, out.y]
290    }
291}