1use super::*;
2
3#[derive(Debug, Clone, Copy)]
5pub enum ColorStyle {
6 NodeBackground = 0,
7 NodeBackgroundHovered,
8 NodeBackgroundSelected,
9 NodeOutline,
10 TitleBar,
11 TitleBarHovered,
12 TitleBarSelected,
13 Link,
14 LinkHovered,
15 LinkSelected,
16 Pin,
17 PinHovered,
18 BoxSelector,
19 BoxSelectorOutline,
20 GridBackground,
21 GridLine,
22 Count,
23}
24
25#[derive(Debug, Clone, Copy)]
27pub enum StyleVar {
28 GridSpacing = 0,
29 NodeCornerRounding,
30 NodePaddingHorizontal,
31 NodePaddingVertical,
32 NodeBorderThickness,
33 LinkThickness,
34 LinkLineSegmentsPerLength,
35 LinkHoverDistance,
36 PinCircleRadius,
37 PinQuadSideLength,
38 PinTriangleSideLength,
39 PinLineThickness,
40 PinHoverRadius,
41 PinOffset,
42}
43
44#[derive(Debug)]
46pub enum StyleFlags {
47 None = 0,
48 NodeOutline = 1 << 0,
49 GridLines = 1 << 2,
50}
51
52impl ColorStyle {
53 pub fn colors_dark() -> [egui::Color32; ColorStyle::Count as usize] {
55 let mut colors = [egui::Color32::BLACK; ColorStyle::Count as usize];
56 colors[ColorStyle::NodeBackground as usize] =
57 egui::Color32::from_rgba_unmultiplied(50, 50, 50, 255);
58 colors[ColorStyle::NodeBackgroundHovered as usize] =
59 egui::Color32::from_rgba_unmultiplied(75, 75, 75, 255);
60 colors[ColorStyle::NodeBackgroundSelected as usize] =
61 egui::Color32::from_rgba_unmultiplied(75, 75, 75, 255);
62 colors[ColorStyle::NodeOutline as usize] =
63 egui::Color32::from_rgba_unmultiplied(100, 100, 100, 255);
64 colors[ColorStyle::TitleBar as usize] =
65 egui::Color32::from_rgba_unmultiplied(41, 74, 122, 255);
66 colors[ColorStyle::TitleBarHovered as usize] =
67 egui::Color32::from_rgba_unmultiplied(66, 150, 250, 255);
68 colors[ColorStyle::TitleBarSelected as usize] =
69 egui::Color32::from_rgba_unmultiplied(66, 150, 250, 255);
70 colors[ColorStyle::Link as usize] =
71 egui::Color32::from_rgba_unmultiplied(61, 133, 224, 200);
72 colors[ColorStyle::LinkHovered as usize] =
73 egui::Color32::from_rgba_unmultiplied(66, 150, 250, 255);
74 colors[ColorStyle::LinkSelected as usize] =
75 egui::Color32::from_rgba_unmultiplied(66, 150, 250, 255);
76 colors[ColorStyle::Pin as usize] = egui::Color32::from_rgba_unmultiplied(53, 150, 250, 180);
77 colors[ColorStyle::PinHovered as usize] =
78 egui::Color32::from_rgba_unmultiplied(53, 150, 250, 255);
79 colors[ColorStyle::BoxSelector as usize] =
80 egui::Color32::from_rgba_unmultiplied(61, 133, 224, 30);
81 colors[ColorStyle::BoxSelectorOutline as usize] =
82 egui::Color32::from_rgba_unmultiplied(61, 133, 224, 150);
83 colors[ColorStyle::GridBackground as usize] =
84 egui::Color32::from_rgba_unmultiplied(40, 40, 50, 200);
85 colors[ColorStyle::GridLine as usize] =
86 egui::Color32::from_rgba_unmultiplied(200, 200, 200, 40);
87 colors
88 }
89
90 pub fn colors_classic() -> [egui::Color32; ColorStyle::Count as usize] {
92 let mut colors = [egui::Color32::BLACK; ColorStyle::Count as usize];
93 colors[ColorStyle::NodeBackground as usize] =
94 egui::Color32::from_rgba_unmultiplied(50, 50, 50, 255);
95 colors[ColorStyle::NodeBackgroundHovered as usize] =
96 egui::Color32::from_rgba_unmultiplied(75, 75, 75, 255);
97 colors[ColorStyle::NodeBackgroundSelected as usize] =
98 egui::Color32::from_rgba_unmultiplied(75, 75, 75, 255);
99 colors[ColorStyle::NodeOutline as usize] =
100 egui::Color32::from_rgba_unmultiplied(100, 100, 100, 255);
101 colors[ColorStyle::TitleBar as usize] =
102 egui::Color32::from_rgba_unmultiplied(69, 69, 138, 255);
103 colors[ColorStyle::TitleBarHovered as usize] =
104 egui::Color32::from_rgba_unmultiplied(82, 82, 161, 255);
105 colors[ColorStyle::TitleBarSelected as usize] =
106 egui::Color32::from_rgba_unmultiplied(82, 82, 161, 255);
107 colors[ColorStyle::Link as usize] =
108 egui::Color32::from_rgba_unmultiplied(255, 255, 255, 100);
109 colors[ColorStyle::LinkHovered as usize] =
110 egui::Color32::from_rgba_unmultiplied(105, 99, 204, 153);
111 colors[ColorStyle::LinkSelected as usize] =
112 egui::Color32::from_rgba_unmultiplied(105, 99, 204, 153);
113 colors[ColorStyle::Pin as usize] = egui::Color32::from_rgba_unmultiplied(89, 102, 156, 170);
114 colors[ColorStyle::PinHovered as usize] =
115 egui::Color32::from_rgba_unmultiplied(102, 122, 179, 200);
116 colors[ColorStyle::BoxSelector as usize] =
117 egui::Color32::from_rgba_unmultiplied(82, 82, 161, 100);
118 colors[ColorStyle::BoxSelectorOutline as usize] =
119 egui::Color32::from_rgba_unmultiplied(82, 82, 161, 255);
120 colors[ColorStyle::GridBackground as usize] =
121 egui::Color32::from_rgba_unmultiplied(40, 40, 50, 200);
122 colors[ColorStyle::GridLine as usize] =
123 egui::Color32::from_rgba_unmultiplied(200, 200, 200, 40);
124 colors
125 }
126
127 pub fn colors_light() -> [egui::Color32; ColorStyle::Count as usize] {
129 let mut colors = [egui::Color32::BLACK; ColorStyle::Count as usize];
130 colors[ColorStyle::NodeBackground as usize] =
131 egui::Color32::from_rgba_unmultiplied(240, 240, 240, 255);
132 colors[ColorStyle::NodeBackgroundHovered as usize] =
133 egui::Color32::from_rgba_unmultiplied(240, 240, 240, 255);
134 colors[ColorStyle::NodeBackgroundSelected as usize] =
135 egui::Color32::from_rgba_unmultiplied(240, 240, 240, 255);
136 colors[ColorStyle::NodeOutline as usize] =
137 egui::Color32::from_rgba_unmultiplied(100, 100, 100, 255);
138 colors[ColorStyle::TitleBar as usize] =
139 egui::Color32::from_rgba_unmultiplied(248, 248, 248, 255);
140 colors[ColorStyle::TitleBarHovered as usize] =
141 egui::Color32::from_rgba_unmultiplied(209, 209, 209, 255);
142 colors[ColorStyle::TitleBarSelected as usize] =
143 egui::Color32::from_rgba_unmultiplied(209, 209, 209, 255);
144 colors[ColorStyle::Link as usize] =
145 egui::Color32::from_rgba_unmultiplied(66, 150, 250, 100);
146 colors[ColorStyle::LinkHovered as usize] =
147 egui::Color32::from_rgba_unmultiplied(66, 150, 250, 242);
148 colors[ColorStyle::LinkSelected as usize] =
149 egui::Color32::from_rgba_unmultiplied(66, 150, 250, 242);
150 colors[ColorStyle::Pin as usize] = egui::Color32::from_rgba_unmultiplied(66, 150, 250, 160);
151 colors[ColorStyle::PinHovered as usize] =
152 egui::Color32::from_rgba_unmultiplied(66, 150, 250, 255);
153 colors[ColorStyle::BoxSelector as usize] =
154 egui::Color32::from_rgba_unmultiplied(90, 170, 250, 30);
155 colors[ColorStyle::BoxSelectorOutline as usize] =
156 egui::Color32::from_rgba_unmultiplied(90, 170, 250, 150);
157 colors[ColorStyle::GridBackground as usize] =
158 egui::Color32::from_rgba_unmultiplied(225, 225, 225, 255);
159 colors[ColorStyle::GridLine as usize] =
160 egui::Color32::from_rgba_unmultiplied(180, 180, 180, 100);
161 colors
162 }
163}
164
165#[derive(Debug)]
174pub struct Style {
175 pub grid_spacing: f32,
176 pub node_corner_rounding: f32,
177 pub node_padding_horizontal: f32,
178 pub node_padding_vertical: f32,
179 pub node_border_thickness: f32,
180
181 pub link_thickness: f32,
182 pub link_line_segments_per_length: f32,
183 pub link_hover_distance: f32,
184
185 pub pin_circle_radius: f32,
186 pub pin_quad_side_length: f32,
187 pub pin_triangle_side_length: f32,
188 pub pin_line_thickness: f32,
189 pub pin_hover_radius: f32,
190 pub pin_offset: f32,
191
192 pub flags: usize,
193 pub colors: [egui::Color32; ColorStyle::Count as usize],
194}
195
196impl Default for Style {
197 fn default() -> Self {
198 Self {
199 grid_spacing: 32.0,
200 node_corner_rounding: 4.0,
201 node_padding_horizontal: 8.0,
202 node_padding_vertical: 8.0,
203 node_border_thickness: 1.0,
204 link_thickness: 3.0,
205 link_line_segments_per_length: 0.1,
206 link_hover_distance: 10.0,
207 pin_circle_radius: 4.0,
208 pin_quad_side_length: 7.0,
209 pin_triangle_side_length: 9.5,
210 pin_line_thickness: 1.0,
211 pin_hover_radius: 10.0,
212 pin_offset: 0.0,
213 flags: StyleFlags::NodeOutline as usize | StyleFlags::GridLines as usize,
214 colors: ColorStyle::colors_dark(),
215 }
216 }
217}
218
219impl Style {
220 pub(crate) fn get_screen_space_pin_coordinates(
221 &self,
222 node_rect: &egui::Rect,
223 attribute_rect: &egui::Rect,
224 kind: AttributeType,
225 ) -> egui::Pos2 {
226 let x = match kind {
227 AttributeType::Input => node_rect.min.x - self.pin_offset,
228 _ => node_rect.max.x + self.pin_offset,
229 };
230 egui::pos2(x, 0.5 * (attribute_rect.min.y + attribute_rect.max.y))
231 }
232
233 pub(crate) fn draw_pin_shape(
234 &self,
235 pin_pos: egui::Pos2,
236 pin_shape: PinShape,
237 pin_color: egui::Color32,
238 shape: egui::layers::ShapeIdx,
239 ui: &mut egui::Ui,
240 ) {
241 let painter = ui.painter();
242 match pin_shape {
243 PinShape::Circle => painter.set(
244 shape,
245 egui::Shape::circle_stroke(
246 pin_pos,
247 self.pin_circle_radius,
248 (self.pin_line_thickness, pin_color),
249 ),
250 ),
251 PinShape::CircleFilled => painter.set(
252 shape,
253 egui::Shape::circle_filled(pin_pos, self.pin_circle_radius, pin_color),
254 ),
255 PinShape::Quad => painter.set(
256 shape,
257 egui::Shape::rect_stroke(
258 egui::Rect::from_center_size(
259 pin_pos,
260 [self.pin_quad_side_length / 2.0; 2].into(),
261 ),
262 0.0,
263 (self.pin_line_thickness, pin_color),
264 egui::StrokeKind::Inside,
265 ),
266 ),
267 PinShape::QuadFilled => painter.set(
268 shape,
269 egui::Shape::rect_filled(
270 egui::Rect::from_center_size(
271 pin_pos,
272 [self.pin_quad_side_length / 2.0; 2].into(),
273 ),
274 0.0,
275 pin_color,
276 ),
277 ),
278 PinShape::Triangle => {
279 let sqrt_3 = 3f32.sqrt();
280 let left_offset = -0.166_666_7 * sqrt_3 * self.pin_triangle_side_length;
281 let right_offset = 0.333_333_3 * sqrt_3 * self.pin_triangle_side_length;
282 let verticacl_offset = 0.5 * self.pin_triangle_side_length;
283 painter.set(
284 shape,
285 egui::Shape::closed_line(
286 vec![
287 pin_pos + (left_offset, verticacl_offset).into(),
288 pin_pos + (right_offset, 0.0).into(),
289 pin_pos + (left_offset, -verticacl_offset).into(),
290 ],
291 (self.pin_line_thickness, pin_color),
292 ),
293 )
294 }
295 PinShape::TriangleFilled => {
296 let sqrt_3 = 3f32.sqrt();
297 let left_offset = -0.166_666_7 * sqrt_3 * self.pin_triangle_side_length;
298 let right_offset = 0.333_333_3 * sqrt_3 * self.pin_triangle_side_length;
299 let verticacl_offset = 0.5 * self.pin_triangle_side_length;
300 painter.set(
301 shape,
302 egui::Shape::convex_polygon(
303 vec![
304 pin_pos + (left_offset, verticacl_offset).into(),
305 pin_pos + (right_offset, 0.0).into(),
306 pin_pos + (left_offset, -verticacl_offset).into(),
307 ],
308 pin_color,
309 egui::Stroke::NONE,
310 ),
311 )
312 }
313 }
314 }
315
316 pub(crate) fn format_node(&self, node: &mut NodeData, args: NodeArgs) {
317 node.color_style.background =
318 args.background.unwrap_or(self.colors[ColorStyle::NodeBackground as usize]);
319 node.color_style.background_hovered = args
320 .background_hovered
321 .unwrap_or(self.colors[ColorStyle::NodeBackgroundHovered as usize]);
322 node.color_style.background_selected = args
323 .background_selected
324 .unwrap_or(self.colors[ColorStyle::NodeBackgroundSelected as usize]);
325 node.color_style.outline =
326 args.outline.unwrap_or(self.colors[ColorStyle::NodeOutline as usize]);
327 node.color_style.titlebar =
328 args.titlebar.unwrap_or(self.colors[ColorStyle::TitleBar as usize]);
329 node.color_style.titlebar_hovered =
330 args.titlebar_hovered.unwrap_or(self.colors[ColorStyle::TitleBarHovered as usize]);
331 node.color_style.titlebar_selected =
332 args.titlebar_selected.unwrap_or(self.colors[ColorStyle::TitleBarSelected as usize]);
333 node.layout_style.corner_rounding =
334 args.corner_rounding.unwrap_or(self.node_corner_rounding);
335 node.layout_style.padding = args.padding.unwrap_or_else(|| {
336 egui::vec2(self.node_padding_horizontal, self.node_padding_vertical)
337 });
338 node.layout_style.border_thickness =
339 args.border_thickness.unwrap_or(self.node_border_thickness);
340 }
341
342 pub(crate) fn format_pin(&self, pin: &mut PinData, args: PinArgs, flags: usize) {
343 pin.shape = args.shape;
344 pin.flags = args.flags.unwrap_or(flags);
345 pin.color_style.background =
346 args.background.unwrap_or(self.colors[ColorStyle::Pin as usize]);
347 pin.color_style.hovered =
348 args.hovered.unwrap_or(self.colors[ColorStyle::PinHovered as usize]);
349 }
350
351 pub(crate) fn format_link(&self, link: &mut LinkData, args: LinkArgs) {
352 link.color_style.base = args.base.unwrap_or(self.colors[ColorStyle::Link as usize]);
353 link.color_style.hovered =
354 args.hovered.unwrap_or(self.colors[ColorStyle::LinkHovered as usize]);
355 link.color_style.selected =
356 args.selected.unwrap_or(self.colors[ColorStyle::LinkSelected as usize]);
357 }
358}