1use crate::{StyleColor, from_vec2, sys, vec2, vec4};
2
3#[derive(Clone, Debug, PartialEq)]
4pub struct NodeEditorStyle {
5 pub node_padding: [f32; 4],
6 pub node_rounding: f32,
7 pub node_border_width: f32,
8 pub hovered_node_border_width: f32,
9 pub hovered_node_border_offset: f32,
10 pub selected_node_border_width: f32,
11 pub selected_node_border_offset: f32,
12 pub pin_rounding: f32,
13 pub pin_border_width: f32,
14 pub link_strength: f32,
15 pub source_direction: [f32; 2],
16 pub target_direction: [f32; 2],
17 pub scroll_duration: f32,
18 pub flow_marker_distance: f32,
19 pub flow_speed: f32,
20 pub flow_duration: f32,
21 pub pivot_alignment: [f32; 2],
22 pub pivot_size: [f32; 2],
23 pub pivot_scale: [f32; 2],
24 pub pin_corners: f32,
25 pub pin_radius: f32,
26 pub pin_arrow_size: f32,
27 pub pin_arrow_width: f32,
28 pub group_rounding: f32,
29 pub group_border_width: f32,
30 pub highlight_connected_links: f32,
31 pub snap_link_to_pin_dir: f32,
32 pub colors: [[f32; 4]; StyleColor::COUNT],
33}
34
35impl NodeEditorStyle {
36 #[doc(alias = "GetStyle")]
37 pub(crate) fn current() -> Self {
38 let mut colors = [[0.0; 4]; StyleColor::COUNT];
39 for color in StyleColor::ALL {
40 colors[color.index()] = from_vec4(unsafe { sys::dne_get_style_color(color.raw()) });
41 }
42
43 Self {
44 node_padding: from_vec4(unsafe { sys::dne_get_style_node_padding() }),
45 node_rounding: unsafe { sys::dne_get_style_node_rounding() },
46 node_border_width: unsafe { sys::dne_get_style_node_border_width() },
47 hovered_node_border_width: unsafe { sys::dne_get_style_hovered_node_border_width() },
48 hovered_node_border_offset: unsafe { sys::dne_get_style_hovered_node_border_offset() },
49 selected_node_border_width: unsafe { sys::dne_get_style_selected_node_border_width() },
50 selected_node_border_offset: unsafe {
51 sys::dne_get_style_selected_node_border_offset()
52 },
53 pin_rounding: unsafe { sys::dne_get_style_pin_rounding() },
54 pin_border_width: unsafe { sys::dne_get_style_pin_border_width() },
55 link_strength: unsafe { sys::dne_get_style_link_strength() },
56 source_direction: from_vec2(unsafe { sys::dne_get_style_source_direction() }),
57 target_direction: from_vec2(unsafe { sys::dne_get_style_target_direction() }),
58 scroll_duration: unsafe { sys::dne_get_style_scroll_duration() },
59 flow_marker_distance: unsafe { sys::dne_get_style_flow_marker_distance() },
60 flow_speed: unsafe { sys::dne_get_style_flow_speed() },
61 flow_duration: unsafe { sys::dne_get_style_flow_duration() },
62 pivot_alignment: from_vec2(unsafe { sys::dne_get_style_pivot_alignment() }),
63 pivot_size: from_vec2(unsafe { sys::dne_get_style_pivot_size() }),
64 pivot_scale: from_vec2(unsafe { sys::dne_get_style_pivot_scale() }),
65 pin_corners: unsafe { sys::dne_get_style_pin_corners() },
66 pin_radius: unsafe { sys::dne_get_style_pin_radius() },
67 pin_arrow_size: unsafe { sys::dne_get_style_pin_arrow_size() },
68 pin_arrow_width: unsafe { sys::dne_get_style_pin_arrow_width() },
69 group_rounding: unsafe { sys::dne_get_style_group_rounding() },
70 group_border_width: unsafe { sys::dne_get_style_group_border_width() },
71 highlight_connected_links: unsafe { sys::dne_get_style_highlight_connected_links() },
72 snap_link_to_pin_dir: unsafe { sys::dne_get_style_snap_link_to_pin_dir() },
73 colors,
74 }
75 }
76
77 pub(crate) fn apply(&self) {
78 validate_style(self);
79 unsafe {
80 sys::dne_set_style_node_padding(vec4(self.node_padding));
81 sys::dne_set_style_node_rounding(self.node_rounding);
82 sys::dne_set_style_node_border_width(self.node_border_width);
83 sys::dne_set_style_hovered_node_border_width(self.hovered_node_border_width);
84 sys::dne_set_style_hovered_node_border_offset(self.hovered_node_border_offset);
85 sys::dne_set_style_selected_node_border_width(self.selected_node_border_width);
86 sys::dne_set_style_selected_node_border_offset(self.selected_node_border_offset);
87 sys::dne_set_style_pin_rounding(self.pin_rounding);
88 sys::dne_set_style_pin_border_width(self.pin_border_width);
89 sys::dne_set_style_link_strength(self.link_strength);
90 sys::dne_set_style_source_direction(vec2(self.source_direction));
91 sys::dne_set_style_target_direction(vec2(self.target_direction));
92 sys::dne_set_style_scroll_duration(self.scroll_duration);
93 sys::dne_set_style_flow_marker_distance(self.flow_marker_distance);
94 sys::dne_set_style_flow_speed(self.flow_speed);
95 sys::dne_set_style_flow_duration(self.flow_duration);
96 sys::dne_set_style_pivot_alignment(vec2(self.pivot_alignment));
97 sys::dne_set_style_pivot_size(vec2(self.pivot_size));
98 sys::dne_set_style_pivot_scale(vec2(self.pivot_scale));
99 sys::dne_set_style_pin_corners(self.pin_corners);
100 sys::dne_set_style_pin_radius(self.pin_radius);
101 sys::dne_set_style_pin_arrow_size(self.pin_arrow_size);
102 sys::dne_set_style_pin_arrow_width(self.pin_arrow_width);
103 sys::dne_set_style_group_rounding(self.group_rounding);
104 sys::dne_set_style_group_border_width(self.group_border_width);
105 sys::dne_set_style_highlight_connected_links(self.highlight_connected_links);
106 sys::dne_set_style_snap_link_to_pin_dir(self.snap_link_to_pin_dir);
107 for color in StyleColor::ALL {
108 sys::dne_set_style_color(color.raw(), vec4(self.colors[color.index()]));
109 }
110 }
111 }
112
113 pub fn color(&self, color: StyleColor) -> [f32; 4] {
114 self.colors[color.index()]
115 }
116
117 pub fn set_color(&mut self, color: StyleColor, value: [f32; 4]) {
118 assert_finite_vec4("NodeEditorStyle::set_color()", "value", value);
119 self.colors[color.index()] = value;
120 }
121}
122
123pub(crate) fn current_style_color(color: StyleColor) -> [f32; 4] {
124 from_vec4(unsafe { sys::dne_get_style_color(color.raw()) })
125}
126
127pub(crate) fn apply_style_color(color: StyleColor, value: [f32; 4]) {
128 assert_finite_vec4("EditorContext::set_style_color()", "value", value);
129 unsafe { sys::dne_set_style_color(color.raw(), vec4(value)) };
130}
131
132fn validate_style(style: &NodeEditorStyle) {
133 assert_finite_vec4(
134 "NodeEditorStyle::apply()",
135 "node_padding",
136 style.node_padding,
137 );
138 for (name, value) in [
139 ("node_rounding", style.node_rounding),
140 ("node_border_width", style.node_border_width),
141 ("hovered_node_border_width", style.hovered_node_border_width),
142 (
143 "hovered_node_border_offset",
144 style.hovered_node_border_offset,
145 ),
146 (
147 "selected_node_border_width",
148 style.selected_node_border_width,
149 ),
150 (
151 "selected_node_border_offset",
152 style.selected_node_border_offset,
153 ),
154 ("pin_rounding", style.pin_rounding),
155 ("pin_border_width", style.pin_border_width),
156 ("link_strength", style.link_strength),
157 ("scroll_duration", style.scroll_duration),
158 ("flow_marker_distance", style.flow_marker_distance),
159 ("flow_speed", style.flow_speed),
160 ("flow_duration", style.flow_duration),
161 ("pin_corners", style.pin_corners),
162 ("pin_radius", style.pin_radius),
163 ("pin_arrow_size", style.pin_arrow_size),
164 ("pin_arrow_width", style.pin_arrow_width),
165 ("group_rounding", style.group_rounding),
166 ("group_border_width", style.group_border_width),
167 ("highlight_connected_links", style.highlight_connected_links),
168 ("snap_link_to_pin_dir", style.snap_link_to_pin_dir),
169 ] {
170 assert_finite_f32("NodeEditorStyle::apply()", name, value);
171 }
172 assert_finite_vec2(
173 "NodeEditorStyle::apply()",
174 "source_direction",
175 style.source_direction,
176 );
177 assert_finite_vec2(
178 "NodeEditorStyle::apply()",
179 "target_direction",
180 style.target_direction,
181 );
182 assert_finite_vec2(
183 "NodeEditorStyle::apply()",
184 "pivot_alignment",
185 style.pivot_alignment,
186 );
187 assert_finite_vec2("NodeEditorStyle::apply()", "pivot_size", style.pivot_size);
188 assert_finite_vec2("NodeEditorStyle::apply()", "pivot_scale", style.pivot_scale);
189 for color in style.colors {
190 assert_finite_vec4("NodeEditorStyle::apply()", "color", color);
191 }
192}
193
194fn assert_finite_f32(caller: &str, name: &str, value: f32) {
195 assert!(value.is_finite(), "{caller} {name} must be finite");
196}
197
198fn assert_finite_vec2(caller: &str, name: &str, value: [f32; 2]) {
199 assert!(
200 value.iter().all(|component| component.is_finite()),
201 "{caller} {name} components must be finite"
202 );
203}
204
205fn assert_finite_vec4(caller: &str, name: &str, value: [f32; 4]) {
206 assert!(
207 value.iter().all(|component| component.is_finite()),
208 "{caller} {name} components must be finite"
209 );
210}
211
212fn from_vec4(value: sys::ImVec4_c) -> [f32; 4] {
213 [value.x, value.y, value.z, value.w]
214}