1use alloc::vec::Vec;
2use core::fmt;
3
4use azul_core::{
5 callbacks::{CoreCallback, CoreCallbackData, Update},
6 dom::{Dom, EventFilter, HoverEventFilter, IdOrClass, IdOrClass::Class, IdOrClassVec},
7 geom::{LogicalPosition, LogicalRect, LogicalSize, PhysicalSizeU32},
8 gl::Texture,
9 menu::{Menu, MenuItem, StringMenuItem},
10 refany::{OptionRefAny, RefAny},
11 resources::{ImageRef, RawImageFormat},
12 svg::{SvgPath, SvgPathElement, SvgStrokeStyle, TessellatedGPUSvgNode},
13 window::CursorPosition::InWindow,
14};
15use azul_css::{
16 dynamic_selector::{CssPropertyWithConditions, CssPropertyWithConditionsVec},
17 props::{
18 basic::*,
19 layout::*,
20 property::{CssProperty, *},
21 style::*,
22 },
23 *,
24};
25
26use crate::{
27 callbacks::{Callback, CallbackInfo},
28 extra::coloru_from_str,
29 widgets::{
30 check_box::{CheckBox, CheckBoxOnToggleCallbackType, CheckBoxState},
31 color_input::{ColorInput, ColorInputOnValueChangeCallbackType, ColorInputState},
32 file_input::{FileInput, FileInputOnPathChangeCallbackType, FileInputState},
33 number_input::{NumberInput, NumberInputOnFocusLostCallbackType, NumberInputState},
34 text_input::{TextInput, TextInputOnFocusLostCallbackType, TextInputState},
35 },
36};
37
38#[derive(Debug, Clone)]
40#[repr(C)]
41pub struct NodeGraph {
42 pub node_types: NodeTypeIdInfoMapVec,
43 pub input_output_types: InputOutputTypeIdInfoMapVec,
44 pub nodes: NodeIdNodeMapVec,
45 pub allow_multiple_root_nodes: bool,
46 pub offset: LogicalPosition,
47 pub style: NodeGraphStyle,
48 pub callbacks: NodeGraphCallbacks,
49 pub add_node_str: AzString,
50 pub scale_factor: f32,
51}
52
53impl Default for NodeGraph {
54 fn default() -> Self {
55 Self {
56 node_types: NodeTypeIdInfoMapVec::from_const_slice(&[]),
57 input_output_types: InputOutputTypeIdInfoMapVec::from_const_slice(&[]),
58 nodes: NodeIdNodeMapVec::from_const_slice(&[]),
59 allow_multiple_root_nodes: false,
60 offset: LogicalPosition::zero(),
61 style: NodeGraphStyle::Default,
62 callbacks: NodeGraphCallbacks::default(),
63 add_node_str: AzString::from_const_str(""),
64 scale_factor: 1.0,
65 }
66 }
67}
68
69impl NodeGraph {
70 pub fn generate_unique_node_id(&self) -> NodeGraphNodeId {
72 NodeGraphNodeId {
73 inner: self
74 .nodes
75 .iter()
76 .map(|i| i.node_id.inner)
77 .max()
78 .unwrap_or(0)
79 .saturating_add(1),
80 }
81 }
82}
83
84#[derive(Debug, Clone)]
85#[repr(C)]
86pub struct NodeTypeIdInfoMap {
87 pub node_type_id: NodeTypeId,
88 pub node_type_info: NodeTypeInfo,
89}
90
91impl_vec!(
92 NodeTypeIdInfoMap,
93 NodeTypeIdInfoMapVec,
94 NodeTypeIdInfoMapVecDestructor,
95 NodeTypeIdInfoMapVecDestructorType
96);
97impl_vec_clone!(
98 NodeTypeIdInfoMap,
99 NodeTypeIdInfoMapVec,
100 NodeTypeIdInfoMapVecDestructor
101);
102impl_vec_mut!(NodeTypeIdInfoMap, NodeTypeIdInfoMapVec);
103impl_vec_debug!(NodeTypeIdInfoMap, NodeTypeIdInfoMapVec);
104
105#[derive(Debug, Clone)]
106#[repr(C)]
107pub struct InputOutputTypeIdInfoMap {
108 pub io_type_id: InputOutputTypeId,
109 pub io_info: InputOutputInfo,
110}
111
112impl_vec!(
113 InputOutputTypeIdInfoMap,
114 InputOutputTypeIdInfoMapVec,
115 InputOutputTypeIdInfoMapVecDestructor,
116 InputOutputTypeIdInfoMapVecDestructorType
117);
118impl_vec_clone!(
119 InputOutputTypeIdInfoMap,
120 InputOutputTypeIdInfoMapVec,
121 InputOutputTypeIdInfoMapVecDestructor
122);
123impl_vec_mut!(InputOutputTypeIdInfoMap, InputOutputTypeIdInfoMapVec);
124impl_vec_debug!(InputOutputTypeIdInfoMap, InputOutputTypeIdInfoMapVec);
125
126#[derive(Debug, Clone)]
127#[repr(C)]
128pub struct NodeIdNodeMap {
129 pub node_id: NodeGraphNodeId,
130 pub node: Node,
131}
132
133impl_vec!(
134 NodeIdNodeMap,
135 NodeIdNodeMapVec,
136 NodeIdNodeMapVecDestructor,
137 NodeIdNodeMapVecDestructorType
138);
139impl_vec_clone!(NodeIdNodeMap, NodeIdNodeMapVec, NodeIdNodeMapVecDestructor);
140impl_vec_mut!(NodeIdNodeMap, NodeIdNodeMapVec);
141impl_vec_debug!(NodeIdNodeMap, NodeIdNodeMapVec);
142
143#[derive(Debug, Copy, Clone)]
144#[repr(C)]
145pub enum NodeGraphStyle {
146 Default,
147 }
149
150#[derive(Default, Debug, Clone)]
151#[repr(C)]
152pub struct NodeGraphCallbacks {
153 pub on_node_added: OptionOnNodeAdded,
154 pub on_node_removed: OptionOnNodeRemoved,
155 pub on_node_dragged: OptionOnNodeDragged,
156 pub on_node_graph_dragged: OptionOnNodeGraphDragged,
157 pub on_node_connected: OptionOnNodeConnected,
158 pub on_node_input_disconnected: OptionOnNodeInputDisconnected,
159 pub on_node_output_disconnected: OptionOnNodeOutputDisconnected,
160 pub on_node_field_edited: OptionOnNodeFieldEdited,
161}
162
163pub type OnNodeAddedCallbackType = extern "C" fn(
164 refany: RefAny,
165 info: CallbackInfo,
166 new_node_type: NodeTypeId,
167 new_node_id: NodeGraphNodeId,
168 new_node_position: NodePosition,
169) -> Update;
170impl_widget_callback!(
171 OnNodeAdded,
172 OptionOnNodeAdded,
173 OnNodeAddedCallback,
174 OnNodeAddedCallbackType
175);
176
177pub type OnNodeRemovedCallbackType =
178 extern "C" fn(refany: RefAny, info: CallbackInfo, node_id_to_remove: NodeGraphNodeId) -> Update;
179impl_widget_callback!(
180 OnNodeRemoved,
181 OptionOnNodeRemoved,
182 OnNodeRemovedCallback,
183 OnNodeRemovedCallbackType
184);
185
186pub type OnNodeGraphDraggedCallbackType =
187 extern "C" fn(refany: RefAny, info: CallbackInfo, drag_amount: GraphDragAmount) -> Update;
188impl_widget_callback!(
189 OnNodeGraphDragged,
190 OptionOnNodeGraphDragged,
191 OnNodeGraphDraggedCallback,
192 OnNodeGraphDraggedCallbackType
193);
194
195pub type OnNodeDraggedCallbackType = extern "C" fn(
196 refany: RefAny,
197 info: CallbackInfo,
198 node_dragged: NodeGraphNodeId,
199 drag_amount: NodeDragAmount,
200) -> Update;
201impl_widget_callback!(
202 OnNodeDragged,
203 OptionOnNodeDragged,
204 OnNodeDraggedCallback,
205 OnNodeDraggedCallbackType
206);
207
208pub type OnNodeConnectedCallbackType = extern "C" fn(
209 refany: RefAny,
210 info: CallbackInfo,
211 input: NodeGraphNodeId,
212 input_index: usize,
213 output: NodeGraphNodeId,
214 output_index: usize,
215) -> Update;
216impl_widget_callback!(
217 OnNodeConnected,
218 OptionOnNodeConnected,
219 OnNodeConnectedCallback,
220 OnNodeConnectedCallbackType
221);
222
223pub type OnNodeInputDisconnectedCallbackType = extern "C" fn(
224 refany: RefAny,
225 info: CallbackInfo,
226 input: NodeGraphNodeId,
227 input_index: usize,
228) -> Update;
229impl_widget_callback!(
230 OnNodeInputDisconnected,
231 OptionOnNodeInputDisconnected,
232 OnNodeInputDisconnectedCallback,
233 OnNodeInputDisconnectedCallbackType
234);
235
236pub type OnNodeOutputDisconnectedCallbackType = extern "C" fn(
237 refany: RefAny,
238 info: CallbackInfo,
239 output: NodeGraphNodeId,
240 output_index: usize,
241) -> Update;
242impl_widget_callback!(
243 OnNodeOutputDisconnected,
244 OptionOnNodeOutputDisconnected,
245 OnNodeOutputDisconnectedCallback,
246 OnNodeOutputDisconnectedCallbackType
247);
248
249pub type OnNodeFieldEditedCallbackType = extern "C" fn(
250 refany: RefAny,
251 info: CallbackInfo,
252 node_id: NodeGraphNodeId,
253 field_id: usize,
254 node_type: NodeTypeId,
255 new_value: NodeTypeFieldValue,
256) -> Update;
257impl_widget_callback!(
258 OnNodeFieldEdited,
259 OptionOnNodeFieldEdited,
260 OnNodeFieldEditedCallback,
261 OnNodeFieldEditedCallbackType
262);
263
264#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
265#[repr(C)]
266pub struct InputOutputTypeId {
267 pub inner: u64,
268}
269
270impl_vec!(
271 InputOutputTypeId,
272 InputOutputTypeIdVec,
273 InputOutputTypeIdVecDestructor,
274 InputOutputTypeIdVecDestructorType
275);
276impl_vec_clone!(
277 InputOutputTypeId,
278 InputOutputTypeIdVec,
279 InputOutputTypeIdVecDestructor
280);
281impl_vec_mut!(InputOutputTypeId, InputOutputTypeIdVec);
282impl_vec_debug!(InputOutputTypeId, InputOutputTypeIdVec);
283
284#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
285#[repr(C)]
286pub struct NodeTypeId {
287 pub inner: u64,
288}
289
290#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
291#[repr(C)]
292pub struct NodeGraphNodeId {
293 pub inner: u64,
294}
295
296#[derive(Debug, Clone)]
297#[repr(C)]
298pub struct Node {
299 pub node_type: NodeTypeId,
300 pub position: NodePosition,
301 pub fields: NodeTypeFieldVec,
302 pub connect_in: InputConnectionVec,
303 pub connect_out: OutputConnectionVec,
304}
305
306#[derive(Debug, Clone)]
307#[repr(C)]
308pub struct NodeTypeField {
309 pub key: AzString,
310 pub value: NodeTypeFieldValue,
311}
312
313impl_vec!(
314 NodeTypeField,
315 NodeTypeFieldVec,
316 NodeTypeFieldVecDestructor,
317 NodeTypeFieldVecDestructorType
318);
319impl_vec_clone!(NodeTypeField, NodeTypeFieldVec, NodeTypeFieldVecDestructor);
320impl_vec_debug!(NodeTypeField, NodeTypeFieldVec);
321impl_vec_mut!(NodeTypeField, NodeTypeFieldVec);
322
323#[derive(Debug, Clone)]
324#[repr(C, u8)]
325pub enum NodeTypeFieldValue {
326 TextInput(AzString),
327 NumberInput(f32),
328 CheckBox(bool),
329 ColorInput(ColorU),
330 FileInput(OptionString),
331}
332
333#[derive(Debug, Clone)]
334#[repr(C)]
335pub struct InputConnection {
336 pub input_index: usize,
337 pub connects_to: OutputNodeAndIndexVec,
338}
339
340impl_vec!(
341 InputConnection,
342 InputConnectionVec,
343 InputConnectionVecDestructor,
344 InputConnectionVecDestructorType
345);
346impl_vec_clone!(
347 InputConnection,
348 InputConnectionVec,
349 InputConnectionVecDestructor
350);
351impl_vec_debug!(InputConnection, InputConnectionVec);
352impl_vec_mut!(InputConnection, InputConnectionVec);
353
354#[derive(Debug, Clone)]
355#[repr(C)]
356pub struct OutputNodeAndIndex {
357 pub node_id: NodeGraphNodeId,
358 pub output_index: usize,
359}
360
361impl_vec!(
362 OutputNodeAndIndex,
363 OutputNodeAndIndexVec,
364 OutputNodeAndIndexVecDestructor,
365 OutputNodeAndIndexVecDestructorType
366);
367impl_vec_clone!(
368 OutputNodeAndIndex,
369 OutputNodeAndIndexVec,
370 OutputNodeAndIndexVecDestructor
371);
372impl_vec_debug!(OutputNodeAndIndex, OutputNodeAndIndexVec);
373impl_vec_mut!(OutputNodeAndIndex, OutputNodeAndIndexVec);
374
375#[derive(Debug, Clone)]
376#[repr(C)]
377pub struct OutputConnection {
378 pub output_index: usize,
379 pub connects_to: InputNodeAndIndexVec,
380}
381
382impl_vec!(
383 OutputConnection,
384 OutputConnectionVec,
385 OutputConnectionVecDestructor,
386 OutputConnectionVecDestructorType
387);
388impl_vec_clone!(
389 OutputConnection,
390 OutputConnectionVec,
391 OutputConnectionVecDestructor
392);
393impl_vec_debug!(OutputConnection, OutputConnectionVec);
394impl_vec_mut!(OutputConnection, OutputConnectionVec);
395
396#[derive(Debug, Clone, PartialEq)]
397#[repr(C)]
398pub struct InputNodeAndIndex {
399 pub node_id: NodeGraphNodeId,
400 pub input_index: usize,
401}
402
403impl_vec!(
404 InputNodeAndIndex,
405 InputNodeAndIndexVec,
406 InputNodeAndIndexVecDestructor,
407 InputNodeAndIndexVecDestructorType
408);
409impl_vec_clone!(
410 InputNodeAndIndex,
411 InputNodeAndIndexVec,
412 InputNodeAndIndexVecDestructor
413);
414impl_vec_debug!(InputNodeAndIndex, InputNodeAndIndexVec);
415impl_vec_mut!(InputNodeAndIndex, InputNodeAndIndexVec);
416
417#[derive(Debug, Clone)]
418#[repr(C)]
419pub struct NodeTypeInfo {
420 pub is_root: bool,
422 pub node_type_name: AzString,
424 pub inputs: InputOutputTypeIdVec,
426 pub outputs: InputOutputTypeIdVec,
428}
429
430#[derive(Debug, Clone)]
431#[repr(C)]
432pub struct InputOutputInfo {
433 pub data_type: AzString,
435 pub color: ColorU,
437}
438
439#[derive(Debug, Copy, Clone)]
442#[repr(C)]
443pub struct NodePosition {
444 pub x: f32,
446 pub y: f32,
448}
449
450#[derive(Debug, Copy, Clone, PartialEq, Eq)]
451#[repr(C)]
452pub enum NodeGraphError {
453 NodeMimeTypeMismatch,
456 NodeInvalidIndex,
458 NodeInvalidNode,
460 NoRootNode,
462}
463
464impl fmt::Display for NodeGraphError {
465 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
466 use self::NodeGraphError::*;
467 match self {
468 NodeMimeTypeMismatch => write!(f, "MIME type mismatch"),
469 NodeInvalidIndex => write!(f, "Invalid node index"),
470 NodeInvalidNode => write!(f, "Invalid node"),
471 NoRootNode => write!(f, "No root node found"),
472 }
473 }
474}
475
476#[derive(Debug, Copy, Clone, PartialEq)]
477#[repr(C)]
478pub struct GraphDragAmount {
479 pub x: f32,
480 pub y: f32,
481}
482
483#[derive(Debug, Copy, Clone, PartialEq)]
484#[repr(C)]
485pub struct NodeDragAmount {
486 pub x: f32,
487 pub y: f32,
488}
489
490impl NodeGraph {
491 pub fn swap_with_default(&mut self) -> Self {
492 let mut default = Self::default();
493 ::core::mem::swap(&mut default, self);
494 default
495 }
496
497 fn connect_input_output(
517 &mut self,
518 input_node_id: NodeGraphNodeId,
519 input_index: usize,
520 output_node_id: NodeGraphNodeId,
521 output_index: usize,
522 ) -> Result<(), NodeGraphError> {
523 let _ =
525 self.verify_nodetype_match(output_node_id, output_index, input_node_id, input_index)?;
526
527 if let Some(input_node) = self
529 .nodes
530 .as_mut()
531 .iter_mut()
532 .find(|i| i.node_id == input_node_id)
533 {
534 if let Some(position) = input_node
535 .node
536 .connect_in
537 .as_ref()
538 .iter()
539 .position(|i| i.input_index == input_index)
540 {
541 input_node.node.connect_in.as_mut()[position]
542 .connects_to
543 .push(OutputNodeAndIndex {
544 node_id: output_node_id,
545 output_index,
546 });
547 } else {
548 input_node.node.connect_in.push(InputConnection {
549 input_index,
550 connects_to: vec![OutputNodeAndIndex {
551 node_id: output_node_id,
552 output_index,
553 }]
554 .into(),
555 })
556 }
557 } else {
558 return Err(NodeGraphError::NodeInvalidNode);
559 }
560
561 if let Some(output_node) = self
563 .nodes
564 .as_mut()
565 .iter_mut()
566 .find(|i| i.node_id == output_node_id)
567 {
568 if let Some(position) = output_node
569 .node
570 .connect_out
571 .as_ref()
572 .iter()
573 .position(|i| i.output_index == output_index)
574 {
575 output_node.node.connect_out.as_mut()[position]
576 .connects_to
577 .push(InputNodeAndIndex {
578 node_id: input_node_id,
579 input_index,
580 });
581 } else {
582 output_node.node.connect_out.push(OutputConnection {
583 output_index,
584 connects_to: vec![InputNodeAndIndex {
585 node_id: input_node_id,
586 input_index,
587 }]
588 .into(),
589 })
590 }
591 } else {
592 return Err(NodeGraphError::NodeInvalidNode);
593 }
594
595 Ok(())
596 }
597
598 fn disconnect_input(
615 &mut self,
616 input_node_id: NodeGraphNodeId,
617 input_index: usize,
618 ) -> Result<(), NodeGraphError> {
619 let output_connections = {
620 let input_node = self
621 .nodes
622 .as_ref()
623 .iter()
624 .find(|i| i.node_id == input_node_id)
625 .ok_or(NodeGraphError::NodeInvalidNode)?;
626
627 match input_node
628 .node
629 .connect_in
630 .iter()
631 .find(|i| i.input_index == input_index)
632 {
633 None => return Ok(()),
634 Some(s) => s.connects_to.clone(),
635 }
636 };
637
638 for OutputNodeAndIndex {
640 node_id,
641 output_index,
642 } in output_connections.as_ref().iter()
643 {
644 let output_node_id = *node_id;
645 let output_index = *output_index;
646
647 let _ = self.verify_nodetype_match(
649 output_node_id,
650 output_index,
651 input_node_id,
652 input_index,
653 )?;
654
655 if let Some(input_node) = self
658 .nodes
659 .as_mut()
660 .iter_mut()
661 .find(|i| i.node_id == input_node_id)
662 {
663 if let Some(position) = input_node
664 .node
665 .connect_in
666 .iter()
667 .position(|i| i.input_index == input_index)
668 {
669 input_node.node.connect_in.remove(position);
670 }
671 } else {
672 return Err(NodeGraphError::NodeInvalidNode);
673 }
674
675 if let Some(output_node) = self
676 .nodes
677 .as_mut()
678 .iter_mut()
679 .find(|i| i.node_id == output_node_id)
680 {
681 if let Some(position) = output_node
682 .node
683 .connect_out
684 .iter()
685 .position(|i| i.output_index == output_index)
686 {
687 output_node.node.connect_out.remove(position);
688 }
689 } else {
690 return Err(NodeGraphError::NodeInvalidNode);
691 }
692 }
693
694 Ok(())
695 }
696
697 fn disconnect_output(
714 &mut self,
715 output_node_id: NodeGraphNodeId,
716 output_index: usize,
717 ) -> Result<(), NodeGraphError> {
718 let input_connections = {
719 let output_node = self
720 .nodes
721 .as_ref()
722 .iter()
723 .find(|i| i.node_id == output_node_id)
724 .ok_or(NodeGraphError::NodeInvalidNode)?;
725
726 match output_node
727 .node
728 .connect_out
729 .iter()
730 .find(|i| i.output_index == output_index)
731 {
732 None => return Ok(()),
733 Some(s) => s.connects_to.clone(),
734 }
735 };
736
737 for InputNodeAndIndex {
738 node_id,
739 input_index,
740 } in input_connections.iter()
741 {
742 let input_node_id = *node_id;
743 let input_index = *input_index;
744
745 let _ = self.verify_nodetype_match(
747 output_node_id,
748 output_index,
749 input_node_id,
750 input_index,
751 )?;
752
753 if let Some(output_node) = self
754 .nodes
755 .as_mut()
756 .iter_mut()
757 .find(|i| i.node_id == output_node_id)
758 {
759 if let Some(position) = output_node
760 .node
761 .connect_out
762 .iter()
763 .position(|i| i.output_index == output_index)
764 {
765 output_node.node.connect_out.remove(position);
766 }
767 } else {
768 return Err(NodeGraphError::NodeInvalidNode);
769 }
770
771 if let Some(input_node) = self
772 .nodes
773 .as_mut()
774 .iter_mut()
775 .find(|i| i.node_id == input_node_id)
776 {
777 if let Some(position) = input_node
778 .node
779 .connect_in
780 .iter()
781 .position(|i| i.input_index == input_index)
782 {
783 input_node.node.connect_in.remove(position);
784 }
785 } else {
786 return Err(NodeGraphError::NodeInvalidNode);
787 }
788 }
789
790 Ok(())
791 }
792
793 fn verify_nodetype_match(
795 &self,
796 output_node_id: NodeGraphNodeId,
797 output_index: usize,
798 input_node_id: NodeGraphNodeId,
799 input_index: usize,
800 ) -> Result<(), NodeGraphError> {
801 let output_node = self
802 .nodes
803 .iter()
804 .find(|i| i.node_id == output_node_id)
805 .ok_or(NodeGraphError::NodeInvalidNode)?;
806
807 let output_node_type = self
808 .node_types
809 .iter()
810 .find(|i| i.node_type_id == output_node.node.node_type)
811 .ok_or(NodeGraphError::NodeInvalidNode)?;
812
813 let output_type = output_node_type
814 .node_type_info
815 .outputs
816 .as_ref()
817 .get(output_index)
818 .copied()
819 .ok_or(NodeGraphError::NodeInvalidIndex)?;
820
821 let input_node = self
822 .nodes
823 .iter()
824 .find(|i| i.node_id == input_node_id)
825 .ok_or(NodeGraphError::NodeInvalidNode)?;
826
827 let input_node_type = self
828 .node_types
829 .iter()
830 .find(|i| i.node_type_id == input_node.node.node_type)
831 .ok_or(NodeGraphError::NodeInvalidNode)?;
832
833 let input_type = input_node_type
834 .node_type_info
835 .inputs
836 .as_ref()
837 .get(input_index)
838 .copied()
839 .ok_or(NodeGraphError::NodeInvalidIndex)?;
840
841 if input_type != output_type {
843 return Err(NodeGraphError::NodeMimeTypeMismatch);
844 }
845
846 Ok(())
847 }
848
849 pub fn dom(self) -> Dom {
850 static NODEGRAPH_CLASS: &[IdOrClass] = &[Class(AzString::from_const_str("nodegraph"))];
851
852 static NODEGRAPH_BACKGROUND: &[StyleBackgroundContent] = &[StyleBackgroundContent::Image(
853 AzString::from_const_str("nodegraph-background"),
854 )];
855
856 static NODEGRAPH_NODES_CONTAINER_CLASS: &[IdOrClass] =
857 &[Class(AzString::from_const_str("nodegraph-nodes-container"))];
858
859 static NODEGRAPH_NODES_CONTAINER_PROPS: &[CssPropertyWithConditions] = &[
860 CssPropertyWithConditions::simple(CssProperty::flex_grow(LayoutFlexGrow::const_new(1))),
861 CssPropertyWithConditions::simple(CssProperty::position(LayoutPosition::Absolute)),
862 ];
863
864 let nodegraph_wrapper_props = vec![
865 CssPropertyWithConditions::simple(CssProperty::overflow_x(LayoutOverflow::Hidden)),
866 CssPropertyWithConditions::simple(CssProperty::overflow_y(LayoutOverflow::Hidden)),
867 CssPropertyWithConditions::simple(CssProperty::flex_grow(LayoutFlexGrow::const_new(1))),
868 CssPropertyWithConditions::simple(CssProperty::background_content(
869 StyleBackgroundContentVec::from_const_slice(NODEGRAPH_BACKGROUND),
870 )),
871 CssPropertyWithConditions::simple(CssProperty::background_repeat(
872 vec![StyleBackgroundRepeat::PatternRepeat].into(),
873 )),
874 CssPropertyWithConditions::simple(CssProperty::background_position(
875 vec![StyleBackgroundPosition {
876 horizontal: BackgroundPositionHorizontal::Exact(PixelValue::const_px(0)),
877 vertical: BackgroundPositionVertical::Exact(PixelValue::const_px(0)),
878 }]
879 .into(),
880 )),
881 ];
882
883 let nodegraph_props = vec![
884 CssPropertyWithConditions::simple(CssProperty::overflow_x(LayoutOverflow::Hidden)),
885 CssPropertyWithConditions::simple(CssProperty::overflow_y(LayoutOverflow::Hidden)),
886 CssPropertyWithConditions::simple(CssProperty::flex_grow(LayoutFlexGrow::const_new(1))),
887 CssPropertyWithConditions::simple(CssProperty::position(LayoutPosition::Relative)),
888 ];
889
890 let node_connection_marker = RefAny::new(NodeConnectionMarkerDataset {});
891
892 let node_graph_local_dataset = RefAny::new(NodeGraphLocalDataset {
893 node_graph: self.clone(), last_input_or_output_clicked: None,
895 active_node_being_dragged: None,
896 node_connection_marker: node_connection_marker.clone(),
897 callbacks: self.callbacks.clone(),
898 });
899
900 let context_menu = Menu::create(
901 vec![MenuItem::String(
902 StringMenuItem::create(self.add_node_str.clone()).with_children(
903 self.node_types
904 .iter()
905 .map(
906 |NodeTypeIdInfoMap {
907 node_type_id,
908 node_type_info,
909 }| {
910 let context_menu_local_dataset =
911 RefAny::new(ContextMenuEntryLocalDataset {
912 node_type: *node_type_id,
913 backref: node_graph_local_dataset.clone(),
915 });
916
917 MenuItem::String(
918 StringMenuItem::create(
919 node_type_info.node_type_name.clone().into(),
920 )
921 .with_callback(
922 context_menu_local_dataset,
923 nodegraph_context_menu_click as usize,
924 ),
925 )
926 },
927 )
928 .collect::<Vec<_>>()
929 .into(),
930 ),
931 )]
932 .into(),
933 );
934
935 Dom::create_div()
936 .with_css_props(nodegraph_wrapper_props.into())
937 .with_context_menu(context_menu)
938 .with_children(
939 vec![Dom::create_div()
940 .with_ids_and_classes(IdOrClassVec::from_const_slice(NODEGRAPH_CLASS))
941 .with_css_props(nodegraph_props.into())
942 .with_callbacks(
943 vec![
944 CoreCallbackData {
945 event: EventFilter::Hover(HoverEventFilter::MouseOver),
946 refany: node_graph_local_dataset.clone(),
947 callback: CoreCallback {
948 cb: nodegraph_drag_graph_or_nodes as usize as usize,
949 ctx: OptionRefAny::None,
950 },
951 },
952 CoreCallbackData {
953 event: EventFilter::Hover(HoverEventFilter::LeftMouseUp),
954 refany: node_graph_local_dataset.clone(),
955 callback: CoreCallback {
956 cb: nodegraph_unset_active_node as usize as usize,
957 ctx: OptionRefAny::None,
958 },
959 },
960 ]
961 .into(),
962 )
963 .with_children({
964 vec![
965 render_connections(&self, node_connection_marker),
967 self.nodes
969 .iter()
970 .filter_map(|NodeIdNodeMap { node_id, node }| {
971 let node_type_info = self
972 .node_types
973 .iter()
974 .find(|i| i.node_type_id == node.node_type)?;
975 let node_local_dataset = NodeLocalDataset {
976 node_id: *node_id,
977 backref: node_graph_local_dataset.clone(),
978 };
979
980 Some(render_node(
981 node,
982 (self.offset.x, self.offset.y),
983 &node_type_info.node_type_info,
984 node_local_dataset,
985 self.scale_factor,
986 ))
987 })
988 .collect::<Dom>()
989 .with_ids_and_classes(IdOrClassVec::from_const_slice(
990 NODEGRAPH_NODES_CONTAINER_CLASS,
991 ))
992 .with_css_props(CssPropertyWithConditionsVec::from_const_slice(
993 NODEGRAPH_NODES_CONTAINER_PROPS,
994 )),
995 ]
996 .into()
997 })]
998 .into(),
999 )
1000 .with_dataset(Some(node_graph_local_dataset).into())
1001 }
1002}
1003
1004struct NodeGraphLocalDataset {
1007 node_graph: NodeGraph,
1008 last_input_or_output_clicked: Option<(NodeGraphNodeId, InputOrOutput)>,
1009 active_node_being_dragged: Option<(NodeGraphNodeId, RefAny)>,
1011 node_connection_marker: RefAny, callbacks: NodeGraphCallbacks,
1013}
1014
1015struct ContextMenuEntryLocalDataset {
1016 node_type: NodeTypeId,
1017 backref: RefAny, }
1019
1020struct NodeConnectionMarkerDataset {}
1021
1022struct NodeLocalDataset {
1023 node_id: NodeGraphNodeId,
1024 backref: RefAny, }
1026
1027#[derive(Debug, Copy, Clone)]
1028enum InputOrOutput {
1029 Input(usize),
1030 Output(usize),
1031}
1032
1033struct NodeInputOutputLocalDataset {
1034 io_id: InputOrOutput,
1035 backref: RefAny, }
1037
1038struct NodeFieldLocalDataset {
1039 field_idx: usize,
1040 backref: RefAny, }
1042
1043#[derive(Copy, Clone)]
1044struct ConnectionLocalDataset {
1045 out_node_id: NodeGraphNodeId,
1046 out_idx: usize,
1047 in_node_id: NodeGraphNodeId,
1048 in_idx: usize,
1049 swap_vert: bool,
1050 swap_horz: bool,
1051 color: ColorU,
1052}
1053
1054fn render_node(
1055 node: &Node,
1056 graph_offset: (f32, f32),
1057 node_info: &NodeTypeInfo,
1058 mut node_local_dataset: NodeLocalDataset,
1059 scale_factor: f32,
1060) -> Dom {
1061 use azul_core::dom::{
1062 CssPropertyWithConditions, CssPropertyWithConditionsVec, Dom, DomVec, IdOrClass,
1063 IdOrClass::Class, IdOrClassVec,
1064 };
1065 use azul_css::*;
1066
1067 const STRING_9416190750059025162: AzString = AzString::from_const_str("Material Icons");
1068 const STRING_16146701490593874959: AzString = AzString::from_const_str("sans-serif");
1069 const STYLE_BACKGROUND_CONTENT_524016094839686509_ITEMS: &[StyleBackgroundContent] =
1070 &[StyleBackgroundContent::Color(ColorU {
1071 r: 34,
1072 g: 34,
1073 b: 34,
1074 a: 255,
1075 })];
1076 const STYLE_BACKGROUND_CONTENT_10430246856047584562_ITEMS: &[StyleBackgroundContent] =
1077 &[StyleBackgroundContent::LinearGradient(LinearGradient {
1078 direction: Direction::FromTo(DirectionCorners {
1079 dir_from: DirectionCorner::Left,
1080 dir_to: DirectionCorner::Right,
1081 }),
1082 extend_mode: ExtendMode::Clamp,
1083 stops: NormalizedLinearColorStopVec::from_const_slice(
1084 LINEAR_COLOR_STOP_4373556077110009258_ITEMS,
1085 ),
1086 })];
1087 const STYLE_BACKGROUND_CONTENT_11535310356736632656_ITEMS: &[StyleBackgroundContent] =
1088 &[StyleBackgroundContent::RadialGradient(RadialGradient {
1089 shape: Shape::Ellipse,
1090 extend_mode: ExtendMode::Clamp,
1091 position: StyleBackgroundPosition {
1092 horizontal: BackgroundPositionHorizontal::Left,
1093 vertical: BackgroundPositionVertical::Top,
1094 },
1095 size: RadialGradientSize::FarthestCorner,
1096 stops: NormalizedLinearColorStopVec::from_const_slice(
1097 LINEAR_COLOR_STOP_15596411095679453272_ITEMS,
1098 ),
1099 })];
1100 const STYLE_BACKGROUND_CONTENT_11936041127084538304_ITEMS: &[StyleBackgroundContent] =
1101 &[StyleBackgroundContent::LinearGradient(LinearGradient {
1102 direction: Direction::FromTo(DirectionCorners {
1103 dir_from: DirectionCorner::Right,
1104 dir_to: DirectionCorner::Left,
1105 }),
1106 extend_mode: ExtendMode::Clamp,
1107 stops: NormalizedLinearColorStopVec::from_const_slice(
1108 LINEAR_COLOR_STOP_4373556077110009258_ITEMS,
1109 ),
1110 })];
1111 const STYLE_BACKGROUND_CONTENT_15813232491335471489_ITEMS: &[StyleBackgroundContent] =
1112 &[StyleBackgroundContent::Color(ColorU {
1113 r: 0,
1114 g: 0,
1115 b: 0,
1116 a: 85,
1117 })];
1118 const STYLE_BACKGROUND_CONTENT_17648039690071193942_ITEMS: &[StyleBackgroundContent] =
1119 &[StyleBackgroundContent::LinearGradient(LinearGradient {
1120 direction: Direction::FromTo(DirectionCorners {
1121 dir_from: DirectionCorner::Top,
1122 dir_to: DirectionCorner::Bottom,
1123 }),
1124 extend_mode: ExtendMode::Clamp,
1125 stops: NormalizedLinearColorStopVec::from_const_slice(
1126 LINEAR_COLOR_STOP_7397113864565941600_ITEMS,
1127 ),
1128 })];
1129 const STYLE_TRANSFORM_347117342922946953_ITEMS: &[StyleTransform] =
1130 &[StyleTransform::Translate(StyleTransformTranslate2D {
1131 x: PixelValue::const_px(200),
1132 y: PixelValue::const_px(100),
1133 })];
1134 const STYLE_TRANSFORM_14683950870521466298_ITEMS: &[StyleTransform] =
1135 &[StyleTransform::Translate(StyleTransformTranslate2D {
1136 x: PixelValue::const_px(240),
1137 y: PixelValue::const_px(-10),
1138 })];
1139 const STYLE_FONT_FAMILY_8122988506401935406_ITEMS: &[StyleFontFamily] =
1140 &[StyleFontFamily::System(STRING_16146701490593874959)];
1141 const STYLE_FONT_FAMILY_11383897783350685780_ITEMS: &[StyleFontFamily] =
1142 &[StyleFontFamily::System(STRING_9416190750059025162)];
1143 const LINEAR_COLOR_STOP_4373556077110009258_ITEMS: &[NormalizedLinearColorStop] = &[
1144 NormalizedLinearColorStop {
1145 offset: PercentageValue::const_new(20),
1146 color: ColorU {
1147 r: 0,
1148 g: 0,
1149 b: 0,
1150 a: 204,
1151 },
1152 },
1153 NormalizedLinearColorStop {
1154 offset: PercentageValue::const_new(100),
1155 color: ColorU {
1156 r: 0,
1157 g: 0,
1158 b: 0,
1159 a: 0,
1160 },
1161 },
1162 ];
1163 const LINEAR_COLOR_STOP_7397113864565941600_ITEMS: &[NormalizedLinearColorStop] = &[
1164 NormalizedLinearColorStop {
1165 offset: PercentageValue::const_new(0),
1166 color: ColorU {
1167 r: 229,
1168 g: 57,
1169 b: 53,
1170 a: 255,
1171 },
1172 },
1173 NormalizedLinearColorStop {
1174 offset: PercentageValue::const_new(100),
1175 color: ColorU {
1176 r: 227,
1177 g: 93,
1178 b: 91,
1179 a: 255,
1180 },
1181 },
1182 ];
1183 const LINEAR_COLOR_STOP_15596411095679453272_ITEMS: &[NormalizedLinearColorStop] = &[
1184 NormalizedLinearColorStop {
1185 offset: PercentageValue::const_new(0),
1186 color: ColorU {
1187 r: 47,
1188 g: 49,
1189 b: 54,
1190 a: 255,
1191 },
1192 },
1193 NormalizedLinearColorStop {
1194 offset: PercentageValue::const_new(50),
1195 color: ColorU {
1196 r: 47,
1197 g: 49,
1198 b: 54,
1199 a: 255,
1200 },
1201 },
1202 NormalizedLinearColorStop {
1203 offset: PercentageValue::const_new(100),
1204 color: ColorU {
1205 r: 32,
1206 g: 34,
1207 b: 37,
1208 a: 255,
1209 },
1210 },
1211 ];
1212
1213 const CSS_MATCH_10339190304804100510_PROPERTIES: &[CssPropertyWithConditions] = &[
1214 CssPropertyWithConditions::simple(CssProperty::Display(LayoutDisplayValue::Exact(
1216 LayoutDisplay::Flex,
1217 ))),
1218 CssPropertyWithConditions::simple(CssProperty::FlexDirection(
1219 LayoutFlexDirectionValue::Exact(LayoutFlexDirection::Column),
1220 )),
1221 CssPropertyWithConditions::simple(CssProperty::Left(LayoutLeftValue::Exact(LayoutLeft {
1222 inner: PixelValue::const_px(0),
1223 }))),
1224 CssPropertyWithConditions::simple(CssProperty::OverflowX(LayoutOverflowValue::Exact(
1225 LayoutOverflow::Visible,
1226 ))),
1227 CssPropertyWithConditions::simple(CssProperty::OverflowY(LayoutOverflowValue::Exact(
1228 LayoutOverflow::Visible,
1229 ))),
1230 CssPropertyWithConditions::simple(CssProperty::Position(LayoutPositionValue::Exact(
1231 LayoutPosition::Absolute,
1232 ))),
1233 ];
1234 const CSS_MATCH_10339190304804100510: CssPropertyWithConditionsVec =
1235 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_10339190304804100510_PROPERTIES);
1236
1237 const CSS_MATCH_11452431279102104133_PROPERTIES: &[CssPropertyWithConditions] = &[
1238 CssPropertyWithConditions::simple(CssProperty::FontFamily(StyleFontFamilyVecValue::Exact(
1240 StyleFontFamilyVec::from_const_slice(STYLE_FONT_FAMILY_8122988506401935406_ITEMS),
1241 ))),
1242 CssPropertyWithConditions::simple(CssProperty::FontSize(StyleFontSizeValue::Exact(
1243 StyleFontSize {
1244 inner: PixelValue::const_px(12),
1245 },
1246 ))),
1247 CssPropertyWithConditions::simple(CssProperty::Height(LayoutHeightValue::Exact(
1248 LayoutHeight::Px(PixelValue::const_px(15)),
1249 ))),
1250 CssPropertyWithConditions::simple(CssProperty::TextAlign(StyleTextAlignValue::Exact(
1251 StyleTextAlign::Right,
1252 ))),
1253 CssPropertyWithConditions::simple(CssProperty::Width(LayoutWidthValue::Exact(
1254 LayoutWidth::Px(PixelValue::const_px(100)),
1255 ))),
1256 ];
1257 const CSS_MATCH_11452431279102104133: CssPropertyWithConditionsVec =
1258 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_11452431279102104133_PROPERTIES);
1259
1260 const CSS_MATCH_1173826950760010563_PROPERTIES: &[CssPropertyWithConditions] = &[
1261 CssPropertyWithConditions::simple(CssProperty::BorderTopColor(
1263 StyleBorderTopColorValue::Exact(StyleBorderTopColor {
1264 inner: ColorU {
1265 r: 0,
1266 g: 131,
1267 b: 176,
1268 a: 119,
1269 },
1270 }),
1271 )),
1272 CssPropertyWithConditions::simple(CssProperty::BorderRightColor(
1273 StyleBorderRightColorValue::Exact(StyleBorderRightColor {
1274 inner: ColorU {
1275 r: 0,
1276 g: 131,
1277 b: 176,
1278 a: 119,
1279 },
1280 }),
1281 )),
1282 CssPropertyWithConditions::simple(CssProperty::BorderLeftColor(
1283 StyleBorderLeftColorValue::Exact(StyleBorderLeftColor {
1284 inner: ColorU {
1285 r: 0,
1286 g: 131,
1287 b: 176,
1288 a: 119,
1289 },
1290 }),
1291 )),
1292 CssPropertyWithConditions::simple(CssProperty::BorderBottomColor(
1293 StyleBorderBottomColorValue::Exact(StyleBorderBottomColor {
1294 inner: ColorU {
1295 r: 0,
1296 g: 131,
1297 b: 176,
1298 a: 119,
1299 },
1300 }),
1301 )),
1302 CssPropertyWithConditions::simple(CssProperty::BorderTopStyle(
1303 StyleBorderTopStyleValue::Exact(StyleBorderTopStyle {
1304 inner: BorderStyle::Solid,
1305 }),
1306 )),
1307 CssPropertyWithConditions::simple(CssProperty::BorderRightStyle(
1308 StyleBorderRightStyleValue::Exact(StyleBorderRightStyle {
1309 inner: BorderStyle::Solid,
1310 }),
1311 )),
1312 CssPropertyWithConditions::simple(CssProperty::BorderLeftStyle(
1313 StyleBorderLeftStyleValue::Exact(StyleBorderLeftStyle {
1314 inner: BorderStyle::Solid,
1315 }),
1316 )),
1317 CssPropertyWithConditions::simple(CssProperty::BorderBottomStyle(
1318 StyleBorderBottomStyleValue::Exact(StyleBorderBottomStyle {
1319 inner: BorderStyle::Solid,
1320 }),
1321 )),
1322 CssPropertyWithConditions::simple(CssProperty::BorderTopWidth(
1323 LayoutBorderTopWidthValue::Exact(LayoutBorderTopWidth {
1324 inner: PixelValue::const_px(1),
1325 }),
1326 )),
1327 CssPropertyWithConditions::simple(CssProperty::BorderRightWidth(
1328 LayoutBorderRightWidthValue::Exact(LayoutBorderRightWidth {
1329 inner: PixelValue::const_px(1),
1330 }),
1331 )),
1332 CssPropertyWithConditions::simple(CssProperty::BorderLeftWidth(
1333 LayoutBorderLeftWidthValue::Exact(LayoutBorderLeftWidth {
1334 inner: PixelValue::const_px(1),
1335 }),
1336 )),
1337 CssPropertyWithConditions::simple(CssProperty::BorderBottomWidth(
1338 LayoutBorderBottomWidthValue::Exact(LayoutBorderBottomWidth {
1339 inner: PixelValue::const_px(1),
1340 }),
1341 )),
1342 CssPropertyWithConditions::simple(CssProperty::AlignItems(LayoutAlignItemsValue::Exact(
1344 LayoutAlignItems::Center,
1345 ))),
1346 CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
1347 StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
1348 STYLE_BACKGROUND_CONTENT_524016094839686509_ITEMS,
1349 )),
1350 )),
1351 CssPropertyWithConditions::simple(CssProperty::BorderTopColor(
1352 StyleBorderTopColorValue::Exact(StyleBorderTopColor {
1353 inner: ColorU {
1354 r: 54,
1355 g: 57,
1356 b: 63,
1357 a: 255,
1358 },
1359 }),
1360 )),
1361 CssPropertyWithConditions::simple(CssProperty::BorderRightColor(
1362 StyleBorderRightColorValue::Exact(StyleBorderRightColor {
1363 inner: ColorU {
1364 r: 54,
1365 g: 57,
1366 b: 63,
1367 a: 255,
1368 },
1369 }),
1370 )),
1371 CssPropertyWithConditions::simple(CssProperty::BorderLeftColor(
1372 StyleBorderLeftColorValue::Exact(StyleBorderLeftColor {
1373 inner: ColorU {
1374 r: 54,
1375 g: 57,
1376 b: 63,
1377 a: 255,
1378 },
1379 }),
1380 )),
1381 CssPropertyWithConditions::simple(CssProperty::BorderBottomColor(
1382 StyleBorderBottomColorValue::Exact(StyleBorderBottomColor {
1383 inner: ColorU {
1384 r: 54,
1385 g: 57,
1386 b: 63,
1387 a: 255,
1388 },
1389 }),
1390 )),
1391 CssPropertyWithConditions::simple(CssProperty::BorderTopStyle(
1392 StyleBorderTopStyleValue::Exact(StyleBorderTopStyle {
1393 inner: BorderStyle::Solid,
1394 }),
1395 )),
1396 CssPropertyWithConditions::simple(CssProperty::BorderRightStyle(
1397 StyleBorderRightStyleValue::Exact(StyleBorderRightStyle {
1398 inner: BorderStyle::Solid,
1399 }),
1400 )),
1401 CssPropertyWithConditions::simple(CssProperty::BorderLeftStyle(
1402 StyleBorderLeftStyleValue::Exact(StyleBorderLeftStyle {
1403 inner: BorderStyle::Solid,
1404 }),
1405 )),
1406 CssPropertyWithConditions::simple(CssProperty::BorderBottomStyle(
1407 StyleBorderBottomStyleValue::Exact(StyleBorderBottomStyle {
1408 inner: BorderStyle::Solid,
1409 }),
1410 )),
1411 CssPropertyWithConditions::simple(CssProperty::BorderTopWidth(
1412 LayoutBorderTopWidthValue::Exact(LayoutBorderTopWidth {
1413 inner: PixelValue::const_px(1),
1414 }),
1415 )),
1416 CssPropertyWithConditions::simple(CssProperty::BorderRightWidth(
1417 LayoutBorderRightWidthValue::Exact(LayoutBorderRightWidth {
1418 inner: PixelValue::const_px(1),
1419 }),
1420 )),
1421 CssPropertyWithConditions::simple(CssProperty::BorderLeftWidth(
1422 LayoutBorderLeftWidthValue::Exact(LayoutBorderLeftWidth {
1423 inner: PixelValue::const_px(1),
1424 }),
1425 )),
1426 CssPropertyWithConditions::simple(CssProperty::BorderBottomWidth(
1427 LayoutBorderBottomWidthValue::Exact(LayoutBorderBottomWidth {
1428 inner: PixelValue::const_px(1),
1429 }),
1430 )),
1431 CssPropertyWithConditions::simple(CssProperty::FlexGrow(LayoutFlexGrowValue::Exact(
1432 LayoutFlexGrow {
1433 inner: FloatValue::const_new(1),
1434 },
1435 ))),
1436 CssPropertyWithConditions::simple(CssProperty::TextAlign(StyleTextAlignValue::Exact(
1437 StyleTextAlign::Left,
1438 ))),
1439 ];
1440 const CSS_MATCH_1173826950760010563: CssPropertyWithConditionsVec =
1441 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_1173826950760010563_PROPERTIES);
1442
1443 const CSS_MATCH_1198521124955124418_PROPERTIES: &[CssPropertyWithConditions] = &[
1444 CssPropertyWithConditions::simple(CssProperty::AlignItems(LayoutAlignItemsValue::Exact(
1446 LayoutAlignItems::Center,
1447 ))),
1448 CssPropertyWithConditions::simple(CssProperty::FlexGrow(LayoutFlexGrowValue::Exact(
1449 LayoutFlexGrow {
1450 inner: FloatValue::const_new(1),
1451 },
1452 ))),
1453 CssPropertyWithConditions::simple(CssProperty::MaxWidth(LayoutMaxWidthValue::Exact(
1454 LayoutMaxWidth {
1455 inner: PixelValue::const_px(120),
1456 },
1457 ))),
1458 CssPropertyWithConditions::simple(CssProperty::PaddingLeft(LayoutPaddingLeftValue::Exact(
1459 LayoutPaddingLeft {
1460 inner: PixelValue::const_px(10),
1461 },
1462 ))),
1463 CssPropertyWithConditions::simple(CssProperty::TextAlign(StyleTextAlignValue::Exact(
1464 StyleTextAlign::Left,
1465 ))),
1466 ];
1467 const CSS_MATCH_1198521124955124418: CssPropertyWithConditionsVec =
1468 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_1198521124955124418_PROPERTIES);
1469
1470 const CSS_MATCH_12038890904436132038_PROPERTIES: &[CssPropertyWithConditions] = &[
1471 CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
1473 StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
1474 STYLE_BACKGROUND_CONTENT_10430246856047584562_ITEMS,
1475 )),
1476 )),
1477 CssPropertyWithConditions::simple(CssProperty::PaddingLeft(LayoutPaddingLeftValue::Exact(
1478 LayoutPaddingLeft {
1479 inner: PixelValue::const_px(5),
1480 },
1481 ))),
1482 ];
1483 const CSS_MATCH_12038890904436132038: CssPropertyWithConditionsVec =
1484 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_12038890904436132038_PROPERTIES);
1485
1486 const CSS_MATCH_12400244273289328300_PROPERTIES: &[CssPropertyWithConditions] = &[
1487 CssPropertyWithConditions::simple(CssProperty::Display(LayoutDisplayValue::Exact(
1489 LayoutDisplay::Flex,
1490 ))),
1491 CssPropertyWithConditions::simple(CssProperty::FlexDirection(
1492 LayoutFlexDirectionValue::Exact(LayoutFlexDirection::Row),
1493 )),
1494 CssPropertyWithConditions::simple(CssProperty::MarginTop(LayoutMarginTopValue::Exact(
1495 LayoutMarginTop {
1496 inner: PixelValue::const_px(10),
1497 },
1498 ))),
1499 ];
1500 const CSS_MATCH_12400244273289328300: CssPropertyWithConditionsVec =
1501 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_12400244273289328300_PROPERTIES);
1502
1503 const CSS_MATCH_14906563417280941890_PROPERTIES: &[CssPropertyWithConditions] = &[
1504 CssPropertyWithConditions::simple(CssProperty::FlexGrow(LayoutFlexGrowValue::Exact(
1506 LayoutFlexGrow {
1507 inner: FloatValue::const_new(0),
1508 },
1509 ))),
1510 CssPropertyWithConditions::simple(CssProperty::OverflowX(LayoutOverflowValue::Exact(
1511 LayoutOverflow::Visible,
1512 ))),
1513 CssPropertyWithConditions::simple(CssProperty::OverflowY(LayoutOverflowValue::Exact(
1514 LayoutOverflow::Visible,
1515 ))),
1516 CssPropertyWithConditions::simple(CssProperty::Position(LayoutPositionValue::Exact(
1517 LayoutPosition::Relative,
1518 ))),
1519 CssPropertyWithConditions::simple(CssProperty::Width(LayoutWidthValue::Exact(
1520 LayoutWidth::Px(PixelValue::const_px(0)),
1521 ))),
1522 ];
1523 const CSS_MATCH_14906563417280941890: CssPropertyWithConditionsVec =
1524 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_14906563417280941890_PROPERTIES);
1525
1526 const CSS_MATCH_16946967739775705757_PROPERTIES: &[CssPropertyWithConditions] = &[
1527 CssPropertyWithConditions::simple(CssProperty::FlexGrow(LayoutFlexGrowValue::Exact(
1529 LayoutFlexGrow {
1530 inner: FloatValue::const_new(0),
1531 },
1532 ))),
1533 CssPropertyWithConditions::simple(CssProperty::OverflowX(LayoutOverflowValue::Exact(
1534 LayoutOverflow::Visible,
1535 ))),
1536 CssPropertyWithConditions::simple(CssProperty::OverflowY(LayoutOverflowValue::Exact(
1537 LayoutOverflow::Visible,
1538 ))),
1539 CssPropertyWithConditions::simple(CssProperty::Position(LayoutPositionValue::Exact(
1540 LayoutPosition::Relative,
1541 ))),
1542 CssPropertyWithConditions::simple(CssProperty::Width(LayoutWidthValue::Exact(
1543 LayoutWidth::Px(PixelValue::const_px(0)),
1544 ))),
1545 ];
1546 const CSS_MATCH_16946967739775705757: CssPropertyWithConditionsVec =
1547 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_16946967739775705757_PROPERTIES);
1548
1549 const CSS_MATCH_1739273067404038547_PROPERTIES: &[CssPropertyWithConditions] = &[
1550 CssPropertyWithConditions::simple(CssProperty::FontSize(StyleFontSizeValue::Exact(
1552 StyleFontSize {
1553 inner: PixelValue::const_px(18),
1554 },
1555 ))),
1556 CssPropertyWithConditions::simple(CssProperty::Height(LayoutHeightValue::Exact(
1557 LayoutHeight::Px(PixelValue::const_px(50)),
1558 ))),
1559 CssPropertyWithConditions::simple(CssProperty::PaddingLeft(LayoutPaddingLeftValue::Exact(
1560 LayoutPaddingLeft {
1561 inner: PixelValue::const_px(5),
1562 },
1563 ))),
1564 CssPropertyWithConditions::simple(CssProperty::PaddingTop(LayoutPaddingTopValue::Exact(
1565 LayoutPaddingTop {
1566 inner: PixelValue::const_px(10),
1567 },
1568 ))),
1569 ];
1570 const CSS_MATCH_1739273067404038547: CssPropertyWithConditionsVec =
1571 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_1739273067404038547_PROPERTIES);
1572
1573 const CSS_MATCH_2008162367868363199_PROPERTIES: &[CssPropertyWithConditions] = &[
1574 CssPropertyWithConditions::simple(CssProperty::FontFamily(StyleFontFamilyVecValue::Exact(
1576 StyleFontFamilyVec::from_const_slice(STYLE_FONT_FAMILY_8122988506401935406_ITEMS),
1577 ))),
1578 CssPropertyWithConditions::simple(CssProperty::FontSize(StyleFontSizeValue::Exact(
1579 StyleFontSize {
1580 inner: PixelValue::const_px(12),
1581 },
1582 ))),
1583 CssPropertyWithConditions::simple(CssProperty::Height(LayoutHeightValue::Exact(
1584 LayoutHeight::Px(PixelValue::const_px(15)),
1585 ))),
1586 CssPropertyWithConditions::simple(CssProperty::TextAlign(StyleTextAlignValue::Exact(
1587 StyleTextAlign::Left,
1588 ))),
1589 CssPropertyWithConditions::simple(CssProperty::Width(LayoutWidthValue::Exact(
1590 LayoutWidth::Px(PixelValue::const_px(100)),
1591 ))),
1592 ];
1593 const CSS_MATCH_2008162367868363199: CssPropertyWithConditionsVec =
1594 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_2008162367868363199_PROPERTIES);
1595
1596 const CSS_MATCH_2639191696846875011_PROPERTIES: &[CssPropertyWithConditions] = &[
1597 CssPropertyWithConditions::simple(CssProperty::FlexDirection(
1599 LayoutFlexDirectionValue::Exact(LayoutFlexDirection::Column),
1600 )),
1601 CssPropertyWithConditions::simple(CssProperty::PaddingTop(LayoutPaddingTopValue::Exact(
1602 LayoutPaddingTop {
1603 inner: PixelValue::const_px(3),
1604 },
1605 ))),
1606 CssPropertyWithConditions::simple(CssProperty::PaddingBottom(
1607 LayoutPaddingBottomValue::Exact(LayoutPaddingBottom {
1608 inner: PixelValue::const_px(3),
1609 }),
1610 )),
1611 CssPropertyWithConditions::simple(CssProperty::PaddingLeft(LayoutPaddingLeftValue::Exact(
1612 LayoutPaddingLeft {
1613 inner: PixelValue::const_px(5),
1614 },
1615 ))),
1616 CssPropertyWithConditions::simple(CssProperty::PaddingRight(
1617 LayoutPaddingRightValue::Exact(LayoutPaddingRight {
1618 inner: PixelValue::const_px(5),
1619 }),
1620 )),
1621 ];
1622 const CSS_MATCH_2639191696846875011: CssPropertyWithConditionsVec =
1623 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_2639191696846875011_PROPERTIES);
1624
1625 const CSS_MATCH_3354247437065914166_PROPERTIES: &[CssPropertyWithConditions] = &[
1626 CssPropertyWithConditions::simple(CssProperty::FlexDirection(
1628 LayoutFlexDirectionValue::Exact(LayoutFlexDirection::Row),
1629 )),
1630 CssPropertyWithConditions::simple(CssProperty::Position(LayoutPositionValue::Exact(
1631 LayoutPosition::Relative,
1632 ))),
1633 ];
1634 const CSS_MATCH_3354247437065914166: CssPropertyWithConditionsVec =
1635 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_3354247437065914166_PROPERTIES);
1636
1637 const CSS_MATCH_4700400755767504372_PROPERTIES: &[CssPropertyWithConditions] = &[
1638 CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
1640 StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
1641 STYLE_BACKGROUND_CONTENT_11936041127084538304_ITEMS,
1642 )),
1643 )),
1644 CssPropertyWithConditions::simple(CssProperty::PaddingRight(
1645 LayoutPaddingRightValue::Exact(LayoutPaddingRight {
1646 inner: PixelValue::const_px(5),
1647 }),
1648 )),
1649 ];
1650 const CSS_MATCH_4700400755767504372: CssPropertyWithConditionsVec =
1651 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_4700400755767504372_PROPERTIES);
1652
1653 const CSS_MATCH_705881630351954657_PROPERTIES: &[CssPropertyWithConditions] = &[
1654 CssPropertyWithConditions::simple(CssProperty::Display(LayoutDisplayValue::Exact(
1656 LayoutDisplay::Flex,
1657 ))),
1658 CssPropertyWithConditions::simple(CssProperty::FlexDirection(
1659 LayoutFlexDirectionValue::Exact(LayoutFlexDirection::Column),
1660 )),
1661 CssPropertyWithConditions::simple(CssProperty::OverflowX(LayoutOverflowValue::Exact(
1662 LayoutOverflow::Visible,
1663 ))),
1664 CssPropertyWithConditions::simple(CssProperty::OverflowY(LayoutOverflowValue::Exact(
1665 LayoutOverflow::Visible,
1666 ))),
1667 CssPropertyWithConditions::simple(CssProperty::Position(LayoutPositionValue::Exact(
1668 LayoutPosition::Absolute,
1669 ))),
1670 CssPropertyWithConditions::simple(CssProperty::Right(LayoutRightValue::Exact(
1671 LayoutRight {
1672 inner: PixelValue::const_px(0),
1673 },
1674 ))),
1675 ];
1676 const CSS_MATCH_705881630351954657: CssPropertyWithConditionsVec =
1677 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_705881630351954657_PROPERTIES);
1678
1679 const CSS_MATCH_7395766480280098891_PROPERTIES: &[CssPropertyWithConditions] = &[
1680 CssPropertyWithConditions::simple(CssProperty::AlignItems(LayoutAlignItemsValue::Exact(
1682 LayoutAlignItems::Center,
1683 ))),
1684 CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
1685 StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
1686 STYLE_BACKGROUND_CONTENT_17648039690071193942_ITEMS,
1687 )),
1688 )),
1689 CssPropertyWithConditions::simple(CssProperty::BorderTopColor(
1690 StyleBorderTopColorValue::Exact(StyleBorderTopColor {
1691 inner: ColorU {
1692 r: 255,
1693 g: 255,
1694 b: 255,
1695 a: 153,
1696 },
1697 }),
1698 )),
1699 CssPropertyWithConditions::simple(CssProperty::BorderRightColor(
1700 StyleBorderRightColorValue::Exact(StyleBorderRightColor {
1701 inner: ColorU {
1702 r: 255,
1703 g: 255,
1704 b: 255,
1705 a: 153,
1706 },
1707 }),
1708 )),
1709 CssPropertyWithConditions::simple(CssProperty::BorderLeftColor(
1710 StyleBorderLeftColorValue::Exact(StyleBorderLeftColor {
1711 inner: ColorU {
1712 r: 255,
1713 g: 255,
1714 b: 255,
1715 a: 153,
1716 },
1717 }),
1718 )),
1719 CssPropertyWithConditions::simple(CssProperty::BorderBottomColor(
1720 StyleBorderBottomColorValue::Exact(StyleBorderBottomColor {
1721 inner: ColorU {
1722 r: 255,
1723 g: 255,
1724 b: 255,
1725 a: 153,
1726 },
1727 }),
1728 )),
1729 CssPropertyWithConditions::simple(CssProperty::BorderTopStyle(
1730 StyleBorderTopStyleValue::Exact(StyleBorderTopStyle {
1731 inner: BorderStyle::Solid,
1732 }),
1733 )),
1734 CssPropertyWithConditions::simple(CssProperty::BorderRightStyle(
1735 StyleBorderRightStyleValue::Exact(StyleBorderRightStyle {
1736 inner: BorderStyle::Solid,
1737 }),
1738 )),
1739 CssPropertyWithConditions::simple(CssProperty::BorderLeftStyle(
1740 StyleBorderLeftStyleValue::Exact(StyleBorderLeftStyle {
1741 inner: BorderStyle::Solid,
1742 }),
1743 )),
1744 CssPropertyWithConditions::simple(CssProperty::BorderBottomStyle(
1745 StyleBorderBottomStyleValue::Exact(StyleBorderBottomStyle {
1746 inner: BorderStyle::Solid,
1747 }),
1748 )),
1749 CssPropertyWithConditions::simple(CssProperty::BorderTopWidth(
1750 LayoutBorderTopWidthValue::Exact(LayoutBorderTopWidth {
1751 inner: PixelValue::const_px(1),
1752 }),
1753 )),
1754 CssPropertyWithConditions::simple(CssProperty::BorderRightWidth(
1755 LayoutBorderRightWidthValue::Exact(LayoutBorderRightWidth {
1756 inner: PixelValue::const_px(1),
1757 }),
1758 )),
1759 CssPropertyWithConditions::simple(CssProperty::BorderLeftWidth(
1760 LayoutBorderLeftWidthValue::Exact(LayoutBorderLeftWidth {
1761 inner: PixelValue::const_px(1),
1762 }),
1763 )),
1764 CssPropertyWithConditions::simple(CssProperty::BorderBottomWidth(
1765 LayoutBorderBottomWidthValue::Exact(LayoutBorderBottomWidth {
1766 inner: PixelValue::const_px(1),
1767 }),
1768 )),
1769 CssPropertyWithConditions::simple(CssProperty::BoxShadowLeft(StyleBoxShadowValue::Exact(
1770 StyleBoxShadow {
1771 offset_x: PixelValueNoPercent {
1772 inner: PixelValue::const_px(0),
1773 },
1774 offset_y: PixelValueNoPercent {
1775 inner: PixelValue::const_px(0),
1776 },
1777 color: ColorU {
1778 r: 229,
1779 g: 57,
1780 b: 53,
1781 a: 255,
1782 },
1783 blur_radius: PixelValueNoPercent {
1784 inner: PixelValue::const_px(2),
1785 },
1786 spread_radius: PixelValueNoPercent {
1787 inner: PixelValue::const_px(0),
1788 },
1789 clip_mode: BoxShadowClipMode::Outset,
1790 },
1791 ))),
1792 CssPropertyWithConditions::simple(CssProperty::BoxShadowRight(StyleBoxShadowValue::Exact(
1793 StyleBoxShadow {
1794 offset_x: PixelValueNoPercent {
1795 inner: PixelValue::const_px(0),
1796 },
1797 offset_y: PixelValueNoPercent {
1798 inner: PixelValue::const_px(0),
1799 },
1800 color: ColorU {
1801 r: 229,
1802 g: 57,
1803 b: 53,
1804 a: 255,
1805 },
1806 blur_radius: PixelValueNoPercent {
1807 inner: PixelValue::const_px(2),
1808 },
1809 spread_radius: PixelValueNoPercent {
1810 inner: PixelValue::const_px(0),
1811 },
1812 clip_mode: BoxShadowClipMode::Outset,
1813 },
1814 ))),
1815 CssPropertyWithConditions::simple(CssProperty::BoxShadowTop(StyleBoxShadowValue::Exact(
1816 StyleBoxShadow {
1817 offset_x: PixelValueNoPercent {
1818 inner: PixelValue::const_px(0),
1819 },
1820 offset_y: PixelValueNoPercent {
1821 inner: PixelValue::const_px(0),
1822 },
1823 color: ColorU {
1824 r: 229,
1825 g: 57,
1826 b: 53,
1827 a: 255,
1828 },
1829 blur_radius: PixelValueNoPercent {
1830 inner: PixelValue::const_px(2),
1831 },
1832 spread_radius: PixelValueNoPercent {
1833 inner: PixelValue::const_px(0),
1834 },
1835 clip_mode: BoxShadowClipMode::Outset,
1836 },
1837 ))),
1838 CssPropertyWithConditions::simple(CssProperty::BoxShadowBottom(
1839 StyleBoxShadowValue::Exact(StyleBoxShadow {
1840 offset_x: PixelValueNoPercent {
1841 inner: PixelValue::const_px(0),
1842 },
1843 offset_y: PixelValueNoPercent {
1844 inner: PixelValue::const_px(0),
1845 },
1846 color: ColorU {
1847 r: 229,
1848 g: 57,
1849 b: 53,
1850 a: 255,
1851 },
1852 blur_radius: PixelValueNoPercent {
1853 inner: PixelValue::const_px(2),
1854 },
1855 spread_radius: PixelValueNoPercent {
1856 inner: PixelValue::const_px(0),
1857 },
1858 clip_mode: BoxShadowClipMode::Outset,
1859 }),
1860 )),
1861 CssPropertyWithConditions::simple(CssProperty::Cursor(StyleCursorValue::Exact(
1862 StyleCursor::Pointer,
1863 ))),
1864 CssPropertyWithConditions::simple(CssProperty::FontFamily(StyleFontFamilyVecValue::Exact(
1865 StyleFontFamilyVec::from_const_slice(STYLE_FONT_FAMILY_11383897783350685780_ITEMS),
1866 ))),
1867 CssPropertyWithConditions::simple(CssProperty::Height(LayoutHeightValue::Exact(
1868 LayoutHeight::Px(PixelValue::const_px(20)),
1869 ))),
1870 CssPropertyWithConditions::simple(CssProperty::Position(LayoutPositionValue::Exact(
1871 LayoutPosition::Absolute,
1872 ))),
1873 CssPropertyWithConditions::simple(CssProperty::TextAlign(StyleTextAlignValue::Exact(
1874 StyleTextAlign::Center,
1875 ))),
1876 CssPropertyWithConditions::simple(CssProperty::Transform(StyleTransformVecValue::Exact(
1877 StyleTransformVec::from_const_slice(STYLE_TRANSFORM_14683950870521466298_ITEMS),
1878 ))),
1879 CssPropertyWithConditions::simple(CssProperty::Width(LayoutWidthValue::Exact(
1880 LayoutWidth::Px(PixelValue::const_px(20)),
1881 ))),
1882 ];
1883 const CSS_MATCH_7395766480280098891: CssPropertyWithConditionsVec =
1884 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_7395766480280098891_PROPERTIES);
1885
1886 const CSS_MATCH_7432473243011547380_PROPERTIES: &[CssPropertyWithConditions] = &[
1887 CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
1889 StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
1890 STYLE_BACKGROUND_CONTENT_15813232491335471489_ITEMS,
1891 )),
1892 )),
1893 CssPropertyWithConditions::simple(CssProperty::BoxShadowLeft(StyleBoxShadowValue::Exact(
1894 StyleBoxShadow {
1895 offset_x: PixelValueNoPercent {
1896 inner: PixelValue::const_px(0),
1897 },
1898 offset_y: PixelValueNoPercent {
1899 inner: PixelValue::const_px(0),
1900 },
1901 color: ColorU {
1902 r: 0,
1903 g: 0,
1904 b: 0,
1905 a: 255,
1906 },
1907 blur_radius: PixelValueNoPercent {
1908 inner: PixelValue::const_px(4),
1909 },
1910 spread_radius: PixelValueNoPercent {
1911 inner: PixelValue::const_px(0),
1912 },
1913 clip_mode: BoxShadowClipMode::Inset,
1914 },
1915 ))),
1916 CssPropertyWithConditions::simple(CssProperty::BoxShadowRight(StyleBoxShadowValue::Exact(
1917 StyleBoxShadow {
1918 offset_x: PixelValueNoPercent {
1919 inner: PixelValue::const_px(0),
1920 },
1921 offset_y: PixelValueNoPercent {
1922 inner: PixelValue::const_px(0),
1923 },
1924 color: ColorU {
1925 r: 0,
1926 g: 0,
1927 b: 0,
1928 a: 255,
1929 },
1930 blur_radius: PixelValueNoPercent {
1931 inner: PixelValue::const_px(4),
1932 },
1933 spread_radius: PixelValueNoPercent {
1934 inner: PixelValue::const_px(0),
1935 },
1936 clip_mode: BoxShadowClipMode::Inset,
1937 },
1938 ))),
1939 CssPropertyWithConditions::simple(CssProperty::BoxShadowTop(StyleBoxShadowValue::Exact(
1940 StyleBoxShadow {
1941 offset_x: PixelValueNoPercent {
1942 inner: PixelValue::const_px(0),
1943 },
1944 offset_y: PixelValueNoPercent {
1945 inner: PixelValue::const_px(0),
1946 },
1947 color: ColorU {
1948 r: 0,
1949 g: 0,
1950 b: 0,
1951 a: 255,
1952 },
1953 blur_radius: PixelValueNoPercent {
1954 inner: PixelValue::const_px(4),
1955 },
1956 spread_radius: PixelValueNoPercent {
1957 inner: PixelValue::const_px(0),
1958 },
1959 clip_mode: BoxShadowClipMode::Inset,
1960 },
1961 ))),
1962 CssPropertyWithConditions::simple(CssProperty::BoxShadowBottom(
1963 StyleBoxShadowValue::Exact(StyleBoxShadow {
1964 offset_x: PixelValueNoPercent {
1965 inner: PixelValue::const_px(0),
1966 },
1967 offset_y: PixelValueNoPercent {
1968 inner: PixelValue::const_px(0),
1969 },
1970 color: ColorU {
1971 r: 0,
1972 g: 0,
1973 b: 0,
1974 a: 255,
1975 },
1976 blur_radius: PixelValueNoPercent {
1977 inner: PixelValue::const_px(4),
1978 },
1979 spread_radius: PixelValueNoPercent {
1980 inner: PixelValue::const_px(0),
1981 },
1982 clip_mode: BoxShadowClipMode::Inset,
1983 }),
1984 )),
1985 CssPropertyWithConditions::simple(CssProperty::FlexGrow(LayoutFlexGrowValue::Exact(
1986 LayoutFlexGrow {
1987 inner: FloatValue::const_new(1),
1988 },
1989 ))),
1990 ];
1991 const CSS_MATCH_7432473243011547380: CssPropertyWithConditionsVec =
1992 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_7432473243011547380_PROPERTIES);
1993
1994 const CSS_MATCH_9863994880298313101_PROPERTIES: &[CssPropertyWithConditions] = &[
1995 CssPropertyWithConditions::simple(CssProperty::Display(LayoutDisplayValue::Exact(
1997 LayoutDisplay::Flex,
1998 ))),
1999 CssPropertyWithConditions::simple(CssProperty::FlexDirection(
2000 LayoutFlexDirectionValue::Exact(LayoutFlexDirection::Row),
2001 )),
2002 CssPropertyWithConditions::simple(CssProperty::MarginTop(LayoutMarginTopValue::Exact(
2003 LayoutMarginTop {
2004 inner: PixelValue::const_px(10),
2005 },
2006 ))),
2007 ];
2008 const CSS_MATCH_9863994880298313101: CssPropertyWithConditionsVec =
2009 CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_9863994880298313101_PROPERTIES);
2010
2011 let node_transform = StyleTransformTranslate2D {
2014 x: PixelValue::px(graph_offset.0 + node.position.x),
2015 y: PixelValue::px(graph_offset.1 + node.position.y),
2016 };
2017
2018 let inputs = node_info
2020 .inputs
2021 .iter()
2022 .filter_map(|io_id| {
2023 let node_graph_ref = node_local_dataset
2024 .backref
2025 .downcast_ref::<NodeGraphLocalDataset>()?;
2026 let io_info = node_graph_ref
2027 .node_graph
2028 .input_output_types
2029 .iter()
2030 .find(|i| i.io_type_id == *io_id)?;
2031 Some((
2032 io_info.io_info.data_type.clone(),
2033 io_info.io_info.color.clone(),
2034 ))
2035 })
2036 .collect::<Vec<_>>();
2037
2038 let outputs = node_info
2039 .outputs
2040 .iter()
2041 .filter_map(|io_id| {
2042 let node_graph_ref = node_local_dataset
2043 .backref
2044 .downcast_ref::<NodeGraphLocalDataset>()?;
2045 let io_info = node_graph_ref
2046 .node_graph
2047 .input_output_types
2048 .iter()
2049 .find(|i| i.io_type_id == *io_id)?;
2050 Some((
2051 io_info.io_info.data_type.clone(),
2052 io_info.io_info.color.clone(),
2053 ))
2054 })
2055 .collect::<Vec<_>>();
2056
2057 let node_local_dataset = RefAny::new(node_local_dataset);
2058
2059 Dom::create_div()
2060 .with_css_props(vec![
2061 CssPropertyWithConditions::simple(CssProperty::Position(LayoutPositionValue::Exact(
2062 LayoutPosition::Absolute,
2063 ))),
2064 ].into())
2065 .with_children(vec![
2066 Dom::create_div()
2067 .with_callbacks(vec![
2068 CoreCallbackData {
2069 event: EventFilter::Hover(HoverEventFilter::LeftMouseDown),
2070 refany: node_local_dataset.clone(),
2071 callback: CoreCallback { cb: nodegraph_set_active_node as usize, ctx: OptionRefAny::None },
2072 },
2073 ].into())
2074 .with_css_props(vec![
2075 CssPropertyWithConditions::simple(CssProperty::OverflowX(
2077 LayoutOverflowValue::Exact(LayoutOverflow::Visible)
2078 )),
2079 CssPropertyWithConditions::simple(CssProperty::Position(LayoutPositionValue::Exact(
2080 LayoutPosition::Relative,
2081 ))),
2082 CssPropertyWithConditions::simple(CssProperty::OverflowY(
2083 LayoutOverflowValue::Exact(LayoutOverflow::Visible)
2084 )),
2085 CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
2086 StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
2087 STYLE_BACKGROUND_CONTENT_11535310356736632656_ITEMS,
2088 )),
2089 )),
2090 CssPropertyWithConditions::simple(CssProperty::BorderTopColor(
2091 StyleBorderTopColorValue::Exact(StyleBorderTopColor {
2092 inner: ColorU {
2093 r: 0,
2094 g: 180,
2095 b: 219,
2096 a: 255,
2097 },
2098 }),
2099 )),
2100 CssPropertyWithConditions::simple(CssProperty::BorderRightColor(
2101 StyleBorderRightColorValue::Exact(StyleBorderRightColor {
2102 inner: ColorU {
2103 r: 0,
2104 g: 180,
2105 b: 219,
2106 a: 255,
2107 },
2108 }),
2109 )),
2110 CssPropertyWithConditions::simple(CssProperty::BorderLeftColor(
2111 StyleBorderLeftColorValue::Exact(StyleBorderLeftColor {
2112 inner: ColorU {
2113 r: 0,
2114 g: 180,
2115 b: 219,
2116 a: 255,
2117 },
2118 }),
2119 )),
2120 CssPropertyWithConditions::simple(CssProperty::BorderBottomColor(
2121 StyleBorderBottomColorValue::Exact(StyleBorderBottomColor {
2122 inner: ColorU {
2123 r: 0,
2124 g: 180,
2125 b: 219,
2126 a: 255,
2127 },
2128 }),
2129 )),
2130 CssPropertyWithConditions::simple(CssProperty::BorderTopStyle(
2131 StyleBorderTopStyleValue::Exact(StyleBorderTopStyle {
2132 inner: BorderStyle::Solid,
2133 }),
2134 )),
2135 CssPropertyWithConditions::simple(CssProperty::BorderRightStyle(
2136 StyleBorderRightStyleValue::Exact(StyleBorderRightStyle {
2137 inner: BorderStyle::Solid,
2138 }),
2139 )),
2140 CssPropertyWithConditions::simple(CssProperty::BorderLeftStyle(
2141 StyleBorderLeftStyleValue::Exact(StyleBorderLeftStyle {
2142 inner: BorderStyle::Solid,
2143 }),
2144 )),
2145 CssPropertyWithConditions::simple(CssProperty::BorderBottomStyle(
2146 StyleBorderBottomStyleValue::Exact(StyleBorderBottomStyle {
2147 inner: BorderStyle::Solid,
2148 }),
2149 )),
2150 CssPropertyWithConditions::simple(CssProperty::BorderTopWidth(
2151 LayoutBorderTopWidthValue::Exact(LayoutBorderTopWidth {
2152 inner: PixelValue::const_px(1),
2153 }),
2154 )),
2155 CssPropertyWithConditions::simple(CssProperty::BorderRightWidth(
2156 LayoutBorderRightWidthValue::Exact(LayoutBorderRightWidth {
2157 inner: PixelValue::const_px(1),
2158 }),
2159 )),
2160 CssPropertyWithConditions::simple(CssProperty::BorderLeftWidth(
2161 LayoutBorderLeftWidthValue::Exact(LayoutBorderLeftWidth {
2162 inner: PixelValue::const_px(1),
2163 }),
2164 )),
2165 CssPropertyWithConditions::simple(CssProperty::BorderBottomWidth(
2166 LayoutBorderBottomWidthValue::Exact(LayoutBorderBottomWidth {
2167 inner: PixelValue::const_px(1),
2168 }),
2169 )),
2170 CssPropertyWithConditions::simple(CssProperty::BoxShadowLeft(StyleBoxShadowValue::Exact(
2171 StyleBoxShadow {
2172 offset_x: PixelValueNoPercent { inner: PixelValue::const_px(0) }, offset_y: PixelValueNoPercent { inner: PixelValue::const_px(0) },
2173 color: ColorU {
2174 r: 0,
2175 g: 131,
2176 b: 176,
2177 a: 119,
2178 },
2179 blur_radius: PixelValueNoPercent {
2180 inner: PixelValue::const_px(3),
2181 },
2182 spread_radius: PixelValueNoPercent {
2183 inner: PixelValue::const_px(0),
2184 },
2185 clip_mode: BoxShadowClipMode::Outset,
2186 },
2187 ))),
2188 CssPropertyWithConditions::simple(CssProperty::BoxShadowRight(StyleBoxShadowValue::Exact(
2189 StyleBoxShadow {
2190 offset_x: PixelValueNoPercent { inner: PixelValue::const_px(0) }, offset_y: PixelValueNoPercent { inner: PixelValue::const_px(0) },
2191 color: ColorU {
2192 r: 0,
2193 g: 131,
2194 b: 176,
2195 a: 119,
2196 },
2197 blur_radius: PixelValueNoPercent {
2198 inner: PixelValue::const_px(3),
2199 },
2200 spread_radius: PixelValueNoPercent {
2201 inner: PixelValue::const_px(0),
2202 },
2203 clip_mode: BoxShadowClipMode::Outset,
2204 },
2205 ))),
2206 CssPropertyWithConditions::simple(CssProperty::BoxShadowTop(StyleBoxShadowValue::Exact(
2207 StyleBoxShadow {
2208 offset_x: PixelValueNoPercent { inner: PixelValue::const_px(0) }, offset_y: PixelValueNoPercent { inner: PixelValue::const_px(0) },
2209 color: ColorU {
2210 r: 0,
2211 g: 131,
2212 b: 176,
2213 a: 119,
2214 },
2215 blur_radius: PixelValueNoPercent {
2216 inner: PixelValue::const_px(3),
2217 },
2218 spread_radius: PixelValueNoPercent {
2219 inner: PixelValue::const_px(0),
2220 },
2221 clip_mode: BoxShadowClipMode::Outset,
2222 },
2223 ))),
2224 CssPropertyWithConditions::simple(CssProperty::BoxShadowBottom(
2225 StyleBoxShadowValue::Exact(StyleBoxShadow {
2226 offset_x: PixelValueNoPercent { inner: PixelValue::const_px(0) }, offset_y: PixelValueNoPercent { inner: PixelValue::const_px(0) },
2227 color: ColorU {
2228 r: 0,
2229 g: 131,
2230 b: 176,
2231 a: 119,
2232 },
2233 blur_radius: PixelValueNoPercent {
2234 inner: PixelValue::const_px(3),
2235 },
2236 spread_radius: PixelValueNoPercent {
2237 inner: PixelValue::const_px(0),
2238 },
2239 clip_mode: BoxShadowClipMode::Outset,
2240 }),
2241 )),
2242 CssPropertyWithConditions::simple(CssProperty::TextColor(StyleTextColorValue::Exact(
2243 StyleTextColor {
2244 inner: ColorU {
2245 r: 255,
2246 g: 255,
2247 b: 255,
2248 a: 255,
2249 },
2250 },
2251 ))),
2252
2253 CssPropertyWithConditions::simple(CssProperty::Display(LayoutDisplayValue::Exact(
2254 LayoutDisplay::Block
2255 ))),
2256 CssPropertyWithConditions::simple(CssProperty::FontFamily(StyleFontFamilyVecValue::Exact(
2257 StyleFontFamilyVec::from_const_slice(STYLE_FONT_FAMILY_8122988506401935406_ITEMS),
2258 ))),
2259 CssPropertyWithConditions::simple(CssProperty::PaddingTop(LayoutPaddingTopValue::Exact(
2260 LayoutPaddingTop {
2261 inner: PixelValue::const_px(10),
2262 },
2263 ))),
2264 CssPropertyWithConditions::simple(CssProperty::PaddingBottom(
2265 LayoutPaddingBottomValue::Exact(LayoutPaddingBottom {
2266 inner: PixelValue::const_px(10),
2267 }),
2268 )),
2269 CssPropertyWithConditions::simple(CssProperty::PaddingLeft(LayoutPaddingLeftValue::Exact(
2270 LayoutPaddingLeft {
2271 inner: PixelValue::const_px(10),
2272 },
2273 ))),
2274 CssPropertyWithConditions::simple(CssProperty::PaddingRight(
2275 LayoutPaddingRightValue::Exact(LayoutPaddingRight {
2276 inner: PixelValue::const_px(10),
2277 }),
2278 )),
2279 CssPropertyWithConditions::simple(CssProperty::Transform(StyleTransformVecValue::Exact(
2280 if scale_factor != 1.0 {
2281 vec![
2282 StyleTransform::Translate(node_transform),
2283 StyleTransform::ScaleX(PercentageValue::new(scale_factor * 100.0)),
2284 StyleTransform::ScaleY(PercentageValue::new(scale_factor * 100.0)),
2285 ]
2286 } else {
2287 vec![
2288 StyleTransform::Translate(node_transform)
2289 ]
2290 }.into()
2291 ))),
2292 CssPropertyWithConditions::simple(CssProperty::Width(LayoutWidthValue::Exact(
2293 LayoutWidth::Px(PixelValue::const_px(250),),
2294 ))),
2295 ].into())
2296 .with_ids_and_classes({
2297 const IDS_AND_CLASSES_4480169002427296613: &[IdOrClass] =
2298 &[Class(AzString::from_const_str("node_graph_node"))];
2299 IdOrClassVec::from_const_slice(IDS_AND_CLASSES_4480169002427296613)
2300 })
2301 .with_children(DomVec::from_vec(vec![
2302 Dom::create_text(AzString::from_const_str("X"))
2303 .with_css_props(CSS_MATCH_7395766480280098891)
2304 .with_callbacks(vec![
2305 CoreCallbackData {
2306 event: EventFilter::Hover(HoverEventFilter::MouseUp),
2307 refany: node_local_dataset.clone(),
2308 callback: CoreCallback { cb: nodegraph_delete_node as usize, ctx: OptionRefAny::None },
2309 },
2310 ].into())
2311 .with_ids_and_classes({
2312 const IDS_AND_CLASSES_7122017923389407516: &[IdOrClass] =
2313 &[Class(AzString::from_const_str("node_close_button"))];
2314 IdOrClassVec::from_const_slice(IDS_AND_CLASSES_7122017923389407516)
2315 }),
2316 Dom::create_text(node_info.node_type_name.clone())
2317 .with_css_props(CSS_MATCH_1739273067404038547)
2318 .with_ids_and_classes({
2319 const IDS_AND_CLASSES_15777790571346582635: &[IdOrClass] =
2320 &[Class(AzString::from_const_str("node_label"))];
2321 IdOrClassVec::from_const_slice(IDS_AND_CLASSES_15777790571346582635)
2322 }),
2323 Dom::create_div()
2324 .with_css_props(CSS_MATCH_3354247437065914166)
2325 .with_ids_and_classes({
2326 const IDS_AND_CLASSES_5590500152394859708: &[IdOrClass] =
2327 &[Class(AzString::from_const_str("node_body"))];
2328 IdOrClassVec::from_const_slice(IDS_AND_CLASSES_5590500152394859708)
2329 })
2330 .with_children(DomVec::from_vec(vec![
2331 Dom::create_div()
2332 .with_css_props(CSS_MATCH_16946967739775705757)
2333 .with_ids_and_classes({
2334 const IDS_AND_CLASSES_3626404106673061698: &[IdOrClass] =
2335 &[Class(AzString::from_const_str("inputs"))];
2336 IdOrClassVec::from_const_slice(IDS_AND_CLASSES_3626404106673061698)
2337 })
2338 .with_children(DomVec::from_vec(vec![Dom::create_div()
2339 .with_css_props(CSS_MATCH_705881630351954657)
2340 .with_ids_and_classes({
2341 const IDS_AND_CLASSES_12825690349660780627: &[IdOrClass] =
2342 &[Class(AzString::from_const_str("node_input_wrapper"))];
2343 IdOrClassVec::from_const_slice(
2344 IDS_AND_CLASSES_12825690349660780627,
2345 )
2346 })
2347 .with_children(DomVec::from_vec(
2348 inputs
2349 .into_iter()
2350 .enumerate()
2351 .map(|(io_id, (input_label, input_color))| {
2352 use self::InputOrOutput::*;
2353
2354 Dom::create_div()
2355 .with_css_props(CSS_MATCH_9863994880298313101)
2356 .with_ids_and_classes({
2357 const IDS_AND_CLASSES_5020681879750641508:
2358 &[IdOrClass] = &[Class(AzString::from_const_str(
2359 "node_input_container",
2360 ))];
2361 IdOrClassVec::from_const_slice(
2362 IDS_AND_CLASSES_5020681879750641508,
2363 )
2364 })
2365 .with_children(DomVec::from_vec(vec![
2366 Dom::create_div()
2367 .with_css_props(
2368 CSS_MATCH_4700400755767504372,
2369 )
2370 .with_ids_and_classes({
2371 const IDS_AND_CLASSES_9154857442066749879:
2372 &[IdOrClass] =
2373 &[Class(AzString::from_const_str(
2374 "node_input_connection_label_wrapper",
2375 ))];
2376 IdOrClassVec::from_const_slice(
2377 IDS_AND_CLASSES_9154857442066749879,
2378 )
2379 })
2380 .with_children(DomVec::from_vec(vec![Dom::create_text(
2381 input_label.clone(),
2382 )
2383 .with_css_props(
2384 CSS_MATCH_11452431279102104133,
2385 )
2386 .with_ids_and_classes({
2387 const IDS_AND_CLASSES_16291496011772407931:
2388 &[IdOrClass] =
2389 &[Class(AzString::from_const_str(
2390 "node_input_connection_label",
2391 ))];
2392 IdOrClassVec::from_const_slice(
2393 IDS_AND_CLASSES_16291496011772407931,
2394 )
2395 })])),
2396 Dom::create_div()
2397 .with_callbacks(vec![
2398 CoreCallbackData {
2399 event: EventFilter::Hover(HoverEventFilter::LeftMouseUp),
2400 refany: RefAny::new(NodeInputOutputLocalDataset {
2401 io_id: Input(io_id),
2402 backref: node_local_dataset.clone(),
2403 }),
2404 callback: CoreCallback { cb: nodegraph_input_output_connect as usize, ctx: OptionRefAny::None },
2405 },
2406 CoreCallbackData {
2407 event: EventFilter::Hover(HoverEventFilter::MiddleMouseUp),
2408 refany: RefAny::new(NodeInputOutputLocalDataset {
2409 io_id: Input(io_id),
2410 backref: node_local_dataset.clone(),
2411 }),
2412 callback: CoreCallback { cb: nodegraph_input_output_disconnect as usize, ctx: OptionRefAny::None },
2413 },
2414 ].into())
2415 .with_css_props(CssPropertyWithConditionsVec::from_vec(vec![
2416 CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
2418 StyleBackgroundContentVecValue::Exact(vec![StyleBackgroundContent::Color(input_color)].into()),
2419 )),
2420 CssPropertyWithConditions::simple(CssProperty::Cursor(StyleCursorValue::Exact(
2421 StyleCursor::Pointer,
2422 ))),
2423 CssPropertyWithConditions::simple(CssProperty::Height(LayoutHeightValue::Exact(
2424 LayoutHeight::Px(PixelValue::const_px(15),),
2425 ))),
2426 CssPropertyWithConditions::simple(CssProperty::Width(LayoutWidthValue::Exact(
2427 LayoutWidth::Px(PixelValue::const_px(15),),
2428 ))),
2429 ])
2430 )
2431 .with_ids_and_classes({
2432 const IDS_AND_CLASSES_2128818677168244823:
2433 &[IdOrClass] = &[Class(
2434 AzString::from_const_str("node_input"),
2435 )];
2436 IdOrClassVec::from_const_slice(
2437 IDS_AND_CLASSES_2128818677168244823,
2438 )
2439 }),
2440 ]))
2441 }).collect()
2442 ))
2443 ])),
2444 Dom::create_div()
2445 .with_css_props(CSS_MATCH_7432473243011547380)
2446 .with_ids_and_classes({
2447 const IDS_AND_CLASSES_746059979773622802: &[IdOrClass] =
2448 &[Class(AzString::from_const_str("node_content_wrapper"))];
2449 IdOrClassVec::from_const_slice(IDS_AND_CLASSES_746059979773622802)
2450 })
2451 .with_children({
2452
2453 let mut fields = Vec::new();
2454
2455 for (field_idx, field) in node.fields.iter().enumerate() {
2456
2457 let field_local_dataset = RefAny::new(NodeFieldLocalDataset {
2458 field_idx,
2459 backref: node_local_dataset.clone(),
2460 });
2461
2462 let div = Dom::create_div()
2463 .with_css_props(CSS_MATCH_2639191696846875011)
2464 .with_ids_and_classes({
2465 const IDS_AND_CLASSES_4413230059125905311: &[IdOrClass] =
2466 &[Class(AzString::from_const_str(
2467 "node_configuration_field_container",
2468 ))];
2469 IdOrClassVec::from_const_slice(
2470 IDS_AND_CLASSES_4413230059125905311,
2471 )
2472 })
2473 .with_children(DomVec::from_vec(vec![
2474 Dom::create_text(field.key.clone())
2475 .with_css_props(CSS_MATCH_1198521124955124418)
2476 .with_ids_and_classes({
2477 const IDS_AND_CLASSES_12334207996395559585:
2478 &[IdOrClass] =
2479 &[Class(AzString::from_const_str(
2480 "node_configuration_field_label",
2481 ))];
2482 IdOrClassVec::from_const_slice(
2483 IDS_AND_CLASSES_12334207996395559585,
2484 )
2485 }),
2486
2487 match &field.value {
2488 NodeTypeFieldValue::TextInput(initial_text) => {
2489 TextInput::create()
2490 .with_text(initial_text.clone())
2491 .with_on_focus_lost(field_local_dataset, nodegraph_on_textinput_focus_lost as TextInputOnFocusLostCallbackType)
2492 .dom()
2493 },
2494 NodeTypeFieldValue::NumberInput(initial_value) => {
2495 NumberInput::create(*initial_value)
2496 .with_on_focus_lost(field_local_dataset, nodegraph_on_numberinput_focus_lost as NumberInputOnFocusLostCallbackType)
2497 .dom()
2498 },
2499 NodeTypeFieldValue::CheckBox(initial_checked) => {
2500 CheckBox::create(*initial_checked)
2501 .with_on_toggle(field_local_dataset, nodegraph_on_checkbox_value_changed as CheckBoxOnToggleCallbackType)
2502 .dom()
2503 },
2504 NodeTypeFieldValue::ColorInput(initial_color) => {
2505 ColorInput::create(*initial_color)
2506 .with_on_value_change(field_local_dataset, nodegraph_on_colorinput_value_changed as ColorInputOnValueChangeCallbackType)
2507 .dom()
2508 },
2509 NodeTypeFieldValue::FileInput(file_path) => {
2510 let cb: FileInputOnPathChangeCallbackType = nodegraph_on_fileinput_button_clicked;
2511 FileInput::create(file_path.clone())
2512 .with_on_path_change(field_local_dataset, cb)
2513 .dom()
2514 },
2515 }
2516 ]));
2517
2518 fields.push(div);
2519 }
2520
2521 DomVec::from_vec(fields)
2522 }),
2523 Dom::create_div()
2524 .with_css_props(CSS_MATCH_14906563417280941890)
2525 .with_ids_and_classes({
2526 const IDS_AND_CLASSES_4737474624251936466: &[IdOrClass] =
2527 &[Class(AzString::from_const_str("outputs"))];
2528 IdOrClassVec::from_const_slice(IDS_AND_CLASSES_4737474624251936466)
2529 })
2530 .with_children(DomVec::from_vec(vec![Dom::create_div()
2531 .with_css_props(CSS_MATCH_10339190304804100510)
2532 .with_ids_and_classes({
2533 const IDS_AND_CLASSES_12883576328110161157: &[IdOrClass] =
2534 &[Class(AzString::from_const_str("node_output_wrapper"))];
2535 IdOrClassVec::from_const_slice(
2536 IDS_AND_CLASSES_12883576328110161157,
2537 )
2538 })
2539 .with_children(DomVec::from_vec(
2540 outputs
2541 .into_iter()
2542 .enumerate()
2543 .map(|(io_id, (output_label, output_color))| {
2544 use self::InputOrOutput::*;
2545 Dom::create_div()
2546 .with_css_props(CSS_MATCH_12400244273289328300)
2547 .with_ids_and_classes({
2548 const IDS_AND_CLASSES_10917819668096233812:
2549 &[IdOrClass] = &[Class(AzString::from_const_str(
2550 "node_output_container",
2551 ))];
2552 IdOrClassVec::from_const_slice(
2553 IDS_AND_CLASSES_10917819668096233812,
2554 )
2555 })
2556 .with_children(DomVec::from_vec(vec![
2557 Dom::create_div()
2558 .with_callbacks(vec![
2559 CoreCallbackData {
2560 event: EventFilter::Hover(HoverEventFilter::LeftMouseUp),
2561 refany: RefAny::new(NodeInputOutputLocalDataset {
2562 io_id: Output(io_id),
2563 backref: node_local_dataset.clone(),
2564 }),
2565 callback: CoreCallback { cb: nodegraph_input_output_connect as usize, ctx: OptionRefAny::None },
2566 },
2567 CoreCallbackData {
2568 event: EventFilter::Hover(HoverEventFilter::MiddleMouseUp),
2569 refany: RefAny::new(NodeInputOutputLocalDataset {
2570 io_id: Output(io_id),
2571 backref: node_local_dataset.clone(),
2572 }),
2573 callback: CoreCallback { cb: nodegraph_input_output_disconnect as usize, ctx: OptionRefAny::None },
2574 },
2575 ].into())
2576 .with_css_props(
2577 CssPropertyWithConditionsVec::from_vec(vec![
2578 CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
2580 StyleBackgroundContentVecValue::Exact(vec![
2581 StyleBackgroundContent::Color(output_color)
2582 ].into()),
2583 )),
2584 CssPropertyWithConditions::simple(CssProperty::Cursor(StyleCursorValue::Exact(
2585 StyleCursor::Pointer,
2586 ))),
2587 CssPropertyWithConditions::simple(CssProperty::Height(LayoutHeightValue::Exact(
2588 LayoutHeight::Px(PixelValue::const_px(15),),
2589 ))),
2590 CssPropertyWithConditions::simple(CssProperty::Width(LayoutWidthValue::Exact(
2591 LayoutWidth::Px(PixelValue::const_px(15),),
2592 ))),
2593 ])
2594 )
2595 .with_ids_and_classes({
2596 const IDS_AND_CLASSES_17632471664405317563:
2597 &[IdOrClass] = &[Class(
2598 AzString::from_const_str("node_output"),
2599 )];
2600 IdOrClassVec::from_const_slice(
2601 IDS_AND_CLASSES_17632471664405317563,
2602 )
2603 }),
2604 Dom::create_div()
2605 .with_css_props(
2606 CSS_MATCH_12038890904436132038,
2607 )
2608 .with_ids_and_classes({
2609 const IDS_AND_CLASSES_1667960214206134147:
2610 &[IdOrClass] =
2611 &[Class(AzString::from_const_str(
2612 "node_output_connection_label_wrapper",
2613 ))];
2614 IdOrClassVec::from_const_slice(
2615 IDS_AND_CLASSES_1667960214206134147,
2616 )
2617 })
2618 .with_children(DomVec::from_vec(vec![Dom::create_text(
2619 output_label.clone(),
2620 )
2621 .with_css_props(
2622 CSS_MATCH_2008162367868363199,
2623 )
2624 .with_ids_and_classes({
2625 const IDS_AND_CLASSES_2974914452796301884:
2626 &[IdOrClass] =
2627 &[Class(AzString::from_const_str(
2628 "node_output_connection_label",
2629 ))];
2630 IdOrClassVec::from_const_slice(
2631 IDS_AND_CLASSES_2974914452796301884,
2632 )
2633 })])),
2634 ]))
2635 }).collect()
2636 ))])),
2637 ])),
2638 ]))
2639 .with_dataset(Some(node_local_dataset).into())
2640 ].into())
2641}
2642
2643fn render_connections(node_graph: &NodeGraph, root_marker_nodedata: RefAny) -> Dom {
2644 const THEME_RED: ColorU = ColorU {
2645 r: 255,
2646 g: 0,
2647 b: 0,
2648 a: 255,
2649 }; const BACKGROUND_THEME_RED: &[StyleBackgroundContent] =
2651 &[StyleBackgroundContent::Color(THEME_RED)];
2652 const BACKGROUND_COLOR_RED: StyleBackgroundContentVec =
2653 StyleBackgroundContentVec::from_const_slice(BACKGROUND_THEME_RED);
2654
2655 static NODEGRAPH_CONNECTIONS_CONTAINER_CLASS: &[IdOrClass] = &[Class(
2656 AzString::from_const_str("nodegraph-connections-container"),
2657 )];
2658
2659 static NODEGRAPH_CONNECTIONS_CONTAINER_PROPS: &[CssPropertyWithConditions] = &[
2660 CssPropertyWithConditions::simple(CssProperty::position(LayoutPosition::Absolute)),
2661 CssPropertyWithConditions::simple(CssProperty::flex_grow(LayoutFlexGrow::const_new(1))),
2662 ];
2663
2664 Dom::create_div()
2665 .with_ids_and_classes(IdOrClassVec::from_const_slice(
2666 NODEGRAPH_CONNECTIONS_CONTAINER_CLASS,
2667 ))
2668 .with_css_props(CssPropertyWithConditionsVec::from_const_slice(
2669 NODEGRAPH_CONNECTIONS_CONTAINER_PROPS,
2670 ))
2671 .with_dataset(Some(root_marker_nodedata).into())
2672 .with_children({
2673 let mut children = Vec::new();
2674
2675 for NodeIdNodeMap { node_id, node } in node_graph.nodes.as_ref().iter() {
2676 let out_node_id = node_id;
2677 let node_type_info = match node_graph
2678 .node_types
2679 .iter()
2680 .find(|i| i.node_type_id == node.node_type)
2681 {
2682 Some(s) => &s.node_type_info,
2683 None => continue,
2684 };
2685
2686 for OutputConnection {
2687 output_index,
2688 connects_to,
2689 } in node.connect_out.as_ref().iter()
2690 {
2691 let output_type_id = match node_type_info.outputs.get(*output_index) {
2692 Some(s) => s,
2693 None => continue,
2694 };
2695
2696 let output_color = match node_graph
2697 .input_output_types
2698 .iter()
2699 .find(|o| o.io_type_id == *output_type_id)
2700 {
2701 Some(s) => s.io_info.color.clone(),
2702 None => continue,
2703 };
2704
2705 for InputNodeAndIndex {
2706 node_id,
2707 input_index,
2708 } in connects_to.as_ref().iter()
2709 {
2710 let in_node_id = node_id;
2711
2712 let mut cld = ConnectionLocalDataset {
2713 out_node_id: *out_node_id,
2714 out_idx: *output_index,
2715 in_node_id: *in_node_id,
2716 in_idx: *input_index,
2717 swap_vert: false,
2718 swap_horz: false,
2719 color: output_color,
2720 };
2721
2722 let (rect, swap_vert, swap_horz) = match get_rect(&node_graph, cld) {
2723 Some(s) => s,
2724 None => continue,
2725 };
2726
2727 cld.swap_vert = swap_vert;
2728 cld.swap_horz = swap_horz;
2729
2730 let cld_refany = RefAny::new(cld);
2731 let connection_div = Dom::create_image(ImageRef::callback(
2732 draw_connection as usize,
2733 cld_refany.clone(),
2734 ))
2735 .with_dataset(Some(cld_refany).into())
2736 .with_css_props(
2737 vec![
2738 CssPropertyWithConditions::simple(CssProperty::Transform(
2739 StyleTransformVecValue::Exact(
2740 vec![
2741 StyleTransform::Translate(StyleTransformTranslate2D {
2742 x: PixelValue::px(
2743 node_graph.offset.x + rect.origin.x,
2744 ),
2745 y: PixelValue::px(
2746 node_graph.offset.y + rect.origin.y,
2747 ),
2748 }),
2749 StyleTransform::ScaleX(PercentageValue::new(
2750 node_graph.scale_factor * 100.0,
2751 )),
2752 StyleTransform::ScaleY(PercentageValue::new(
2753 node_graph.scale_factor * 100.0,
2754 )),
2755 ]
2756 .into(),
2757 ),
2758 )),
2759 CssPropertyWithConditions::simple(CssProperty::Width(
2760 LayoutWidthValue::Exact(LayoutWidth::Px(PixelValue::px(
2761 rect.size.width,
2762 ))),
2763 )),
2764 CssPropertyWithConditions::simple(CssProperty::Height(
2765 LayoutHeightValue::Exact(LayoutHeight::Px(PixelValue::px(
2766 rect.size.height,
2767 ))),
2768 )),
2769 ]
2770 .into(),
2771 );
2772
2773 children.push(
2774 Dom::create_div()
2775 .with_inline_style(
2776 "flex-grow: 1; position: absolute; overflow: hidden;",
2777 )
2778 .with_children(vec![connection_div].into()),
2779 );
2780 }
2781 }
2782 }
2783
2784 children.into()
2785 })
2786}
2787
2788extern "C" fn draw_connection(mut refany: RefAny, _info: ()) -> ImageRef {
2789 let size = azul_core::geom::LogicalSize {
2792 width: 100.0,
2793 height: 100.0,
2794 };
2795 let invalid = ImageRef::null_image(
2796 size.width as usize,
2797 size.height as usize,
2798 RawImageFormat::R8,
2799 Vec::new(),
2800 );
2801
2802 invalid
2804}
2805
2806fn draw_connection_inner(
2807 mut refany: RefAny,
2808 _info: &mut (),
2809 _texture_size: PhysicalSizeU32,
2810) -> Option<ImageRef> {
2811 use crate::xml::svg::tessellate_path_stroke;
2812
2813 let refany = refany.downcast_ref::<ConnectionLocalDataset>()?;
2814 let refany = &*refany;
2815
2816 return None;
2818
2819 }
2942
2943const NODE_WIDTH: f32 = 250.0;
2944const V_OFFSET: f32 = 71.0;
2945const DIST_BETWEEN_NODES: f32 = 10.0;
2946const CONNECTION_DOT_HEIGHT: f32 = 15.0;
2947
2948fn get_rect(
2950 node_graph: &NodeGraph,
2951 connection: ConnectionLocalDataset,
2952) -> Option<(LogicalRect, bool, bool)> {
2953 let ConnectionLocalDataset {
2954 out_node_id,
2955 out_idx,
2956 in_node_id,
2957 in_idx,
2958 ..
2959 } = connection;
2960 let out_node = node_graph.nodes.iter().find(|i| i.node_id == out_node_id)?;
2961 let in_node = node_graph.nodes.iter().find(|i| i.node_id == in_node_id)?;
2962
2963 let x_out = out_node.node.position.x + NODE_WIDTH;
2964 let y_out = out_node.node.position.y
2965 + V_OFFSET
2966 + (out_idx as f32 * (DIST_BETWEEN_NODES + CONNECTION_DOT_HEIGHT));
2967
2968 let x_in = in_node.node.position.x;
2969 let y_in = in_node.node.position.y
2970 + V_OFFSET
2971 + (in_idx as f32 * (DIST_BETWEEN_NODES + CONNECTION_DOT_HEIGHT));
2972
2973 let should_swap_vertical = y_in > y_out;
2974 let should_swap_horizontal = x_in < x_out;
2975
2976 let width = (x_in - x_out).abs();
2977 let height = (y_in - y_out).abs() + CONNECTION_DOT_HEIGHT;
2978
2979 let x = x_in.min(x_out);
2980 let y = y_in.min(y_out);
2981
2982 Some((
2983 LogicalRect {
2984 size: LogicalSize { width, height },
2985 origin: LogicalPosition { x, y },
2986 },
2987 should_swap_vertical,
2988 should_swap_horizontal,
2989 ))
2990}
2991
2992extern "C" fn nodegraph_set_active_node(mut refany: RefAny, _info: CallbackInfo) -> Update {
2993 let data_clone = refany.clone();
2994 if let Some(mut refany) = refany.downcast_mut::<NodeLocalDataset>() {
2995 let node_id = refany.node_id.clone();
2996 if let Some(mut backref) = refany.backref.downcast_mut::<NodeGraphLocalDataset>() {
2997 backref.active_node_being_dragged = Some((node_id, data_clone));
2998 }
2999 }
3000 Update::DoNothing
3001}
3002
3003extern "C" fn nodegraph_unset_active_node(mut refany: RefAny, _info: CallbackInfo) -> Update {
3004 if let Some(mut refany) = refany.downcast_mut::<NodeGraphLocalDataset>() {
3005 refany.active_node_being_dragged = None;
3006 }
3007 Update::DoNothing
3008}
3009
3010extern "C" fn nodegraph_drag_graph_or_nodes(mut refany: RefAny, mut info: CallbackInfo) -> Update {
3012 let mut refany = match refany.downcast_mut::<NodeGraphLocalDataset>() {
3013 Some(s) => s,
3014 None => return Update::DoNothing,
3015 };
3016 let refany = &mut *refany;
3017
3018 let prev = match info.get_previous_mouse_state() {
3019 Some(s) => s,
3020 None => return Update::DoNothing,
3021 };
3022 let cur = info.get_current_mouse_state();
3023 if !(cur.left_down && prev.left_down) {
3024 return Update::DoNothing;
3026 }
3027
3028 let (current_mouse_pos, previous_mouse_pos) = match (cur.cursor_position, prev.cursor_position)
3029 {
3030 (InWindow(c), InWindow(p)) => (c, p),
3031 _ => return Update::DoNothing,
3032 };
3033
3034 let dx = (current_mouse_pos.x - previous_mouse_pos.x) * (1.0 / refany.node_graph.scale_factor);
3035 let dy = (current_mouse_pos.y - previous_mouse_pos.y) * (1.0 / refany.node_graph.scale_factor);
3036 let nodegraph_node = info.get_hit_node();
3037
3038 let should_update = match refany.active_node_being_dragged.clone() {
3039 Some((node_graph_node_id, data_marker)) => {
3041 let node_connection_marker = &mut refany.node_connection_marker;
3042
3043 let _nodegraph_node = info.get_hit_node();
3044 let result = match refany.callbacks.on_node_dragged.as_ref() {
3045 Some(OnNodeDragged { callback, refany }) => (callback.cb)(
3046 refany.clone(),
3047 info.clone(),
3048 node_graph_node_id,
3049 NodeDragAmount { x: dx, y: dy },
3050 ),
3051 None => Update::DoNothing,
3052 };
3053
3054 let node_position = match refany
3056 .node_graph
3057 .nodes
3058 .iter_mut()
3059 .find(|i| i.node_id == node_graph_node_id)
3060 {
3061 Some(s) => {
3062 s.node.position.x += dx;
3063 s.node.position.y += dy;
3064 s.node.position
3065 }
3066 None => return Update::DoNothing,
3067 };
3068
3069 let visual_node_id = match info.get_node_id_of_root_dataset(data_marker) {
3070 Some(s) => s,
3071 None => return Update::DoNothing,
3072 };
3073
3074 let node_transform = StyleTransformTranslate2D {
3075 x: PixelValue::px(node_position.x + refany.node_graph.offset.x),
3076 y: PixelValue::px(node_position.y + refany.node_graph.offset.y),
3077 };
3078
3079 info.set_css_property(
3080 visual_node_id,
3081 CssProperty::transform(
3082 if refany.node_graph.scale_factor != 1.0 {
3083 vec![
3084 StyleTransform::Translate(node_transform),
3085 StyleTransform::ScaleX(PercentageValue::new(
3086 refany.node_graph.scale_factor * 100.0,
3087 )),
3088 StyleTransform::ScaleY(PercentageValue::new(
3089 refany.node_graph.scale_factor * 100.0,
3090 )),
3091 ]
3092 } else {
3093 vec![StyleTransform::Translate(node_transform)]
3094 }
3095 .into(),
3096 ),
3097 );
3098
3099 let connection_container_nodeid =
3101 match info.get_node_id_of_root_dataset(node_connection_marker.clone()) {
3102 Some(s) => s,
3103 None => return result,
3104 };
3105
3106 let mut first_connection_child = info.get_first_child(connection_container_nodeid);
3108
3109 while let Some(connection_nodeid) = first_connection_child {
3110 first_connection_child = info.get_next_sibling(connection_nodeid);
3111
3112 let first_child = match info.get_first_child(connection_nodeid) {
3113 Some(s) => s,
3114 None => continue,
3115 };
3116
3117 let mut dataset = match info.get_dataset(first_child) {
3118 Some(s) => s,
3119 None => continue,
3120 };
3121
3122 let mut cld = match dataset.downcast_mut::<ConnectionLocalDataset>() {
3123 Some(s) => s,
3124 None => continue,
3125 };
3126
3127 if !(cld.out_node_id == node_graph_node_id || cld.in_node_id == node_graph_node_id)
3128 {
3129 continue; }
3131
3132 let (new_rect, swap_vert, swap_horz) = match get_rect(&refany.node_graph, *cld) {
3133 Some(s) => s,
3134 None => continue,
3135 };
3136
3137 cld.swap_vert = swap_vert;
3138 cld.swap_horz = swap_horz;
3139
3140 let node_transform = StyleTransformTranslate2D {
3141 x: PixelValue::px(refany.node_graph.offset.x + new_rect.origin.x),
3142 y: PixelValue::px(refany.node_graph.offset.y + new_rect.origin.y),
3143 };
3144
3145 info.set_css_property(
3146 first_child,
3147 CssProperty::transform(
3148 if refany.node_graph.scale_factor != 1.0 {
3149 vec![
3150 StyleTransform::Translate(node_transform),
3151 StyleTransform::ScaleX(PercentageValue::new(
3152 refany.node_graph.scale_factor * 100.0,
3153 )),
3154 StyleTransform::ScaleY(PercentageValue::new(
3155 refany.node_graph.scale_factor * 100.0,
3156 )),
3157 ]
3158 } else {
3159 vec![StyleTransform::Translate(node_transform)]
3160 }
3161 .into(),
3162 ),
3163 );
3164
3165 info.set_css_property(
3166 first_child,
3167 CssProperty::Width(LayoutWidthValue::Exact(LayoutWidth::Px(PixelValue::px(
3168 new_rect.size.width,
3169 )))),
3170 );
3171 info.set_css_property(
3172 first_child,
3173 CssProperty::Height(LayoutHeightValue::Exact(LayoutHeight::Px(
3174 PixelValue::px(new_rect.size.height),
3175 ))),
3176 );
3177 }
3178
3179 result
3180 }
3181 None => {
3183 let result = match refany.callbacks.on_node_graph_dragged.as_ref() {
3184 Some(OnNodeGraphDragged { callback, refany }) => (callback.cb)(
3185 refany.clone(),
3186 info.clone(),
3187 GraphDragAmount { x: dx, y: dy },
3188 ),
3189 None => Update::DoNothing,
3190 };
3191
3192 refany.node_graph.offset.x += dx;
3193 refany.node_graph.offset.y += dy;
3194
3195 let node_container = match info.get_first_child(nodegraph_node) {
3197 Some(s) => s,
3198 None => return Update::DoNothing,
3199 };
3200
3201 let node_container = match info.get_next_sibling(node_container) {
3202 Some(s) => s,
3203 None => return Update::DoNothing,
3204 };
3205
3206 let mut node = match info.get_first_child(node_container) {
3207 Some(s) => s,
3208 None => return Update::DoNothing,
3209 };
3210
3211 loop {
3212 let node_first_child = match info.get_first_child(node) {
3213 Some(s) => s,
3214 None => return Update::DoNothing,
3215 };
3216
3217 let mut node_local_dataset = match info.get_dataset(node_first_child) {
3218 None => return Update::DoNothing,
3219 Some(s) => s,
3220 };
3221
3222 let node_graph_node_id = match node_local_dataset.downcast_ref::<NodeLocalDataset>()
3223 {
3224 Some(s) => s,
3225 None => continue,
3226 };
3227
3228 let node_graph_node_id = node_graph_node_id.node_id;
3229
3230 let node_position = match refany
3231 .node_graph
3232 .nodes
3233 .iter()
3234 .find(|i| i.node_id == node_graph_node_id)
3235 {
3236 Some(s) => s.node.position,
3237 None => continue,
3238 };
3239
3240 let node_transform = StyleTransformTranslate2D {
3241 x: PixelValue::px(node_position.x + refany.node_graph.offset.x),
3242 y: PixelValue::px(node_position.y + refany.node_graph.offset.y),
3243 };
3244
3245 info.set_css_property(
3246 node_first_child,
3247 CssProperty::transform(
3248 if refany.node_graph.scale_factor != 1.0 {
3249 vec![
3250 StyleTransform::Translate(node_transform),
3251 StyleTransform::ScaleX(PercentageValue::new(
3252 refany.node_graph.scale_factor * 100.0,
3253 )),
3254 StyleTransform::ScaleY(PercentageValue::new(
3255 refany.node_graph.scale_factor * 100.0,
3256 )),
3257 ]
3258 } else {
3259 vec![StyleTransform::Translate(node_transform)]
3260 }
3261 .into(),
3262 ),
3263 );
3264
3265 node = match info.get_next_sibling(node) {
3266 Some(s) => s,
3267 None => break,
3268 };
3269 }
3270
3271 let node_connection_marker = &mut refany.node_connection_marker;
3272
3273 let connection_container_nodeid =
3275 match info.get_node_id_of_root_dataset(node_connection_marker.clone()) {
3276 Some(s) => s,
3277 None => return result,
3278 };
3279
3280 let mut first_connection_child = info.get_first_child(connection_container_nodeid);
3281
3282 while let Some(connection_nodeid) = first_connection_child {
3283 first_connection_child = info.get_next_sibling(connection_nodeid);
3284
3285 let first_child = match info.get_first_child(connection_nodeid) {
3286 Some(s) => s,
3287 None => continue,
3288 };
3289
3290 let mut dataset = match info.get_dataset(first_child) {
3291 Some(s) => s,
3292 None => continue,
3293 };
3294
3295 let cld = match dataset.downcast_ref::<ConnectionLocalDataset>() {
3296 Some(s) => s,
3297 None => continue,
3298 };
3299
3300 let (new_rect, _, _) = match get_rect(&refany.node_graph, *cld) {
3301 Some(s) => s,
3302 None => continue,
3303 };
3304
3305 info.set_css_property(
3306 first_child,
3307 CssProperty::transform(
3308 vec![
3309 StyleTransform::Translate(StyleTransformTranslate2D {
3310 x: PixelValue::px(refany.node_graph.offset.x + new_rect.origin.x),
3311 y: PixelValue::px(refany.node_graph.offset.y + new_rect.origin.y),
3312 }),
3313 StyleTransform::ScaleX(PercentageValue::new(
3314 refany.node_graph.scale_factor * 100.0,
3315 )),
3316 StyleTransform::ScaleY(PercentageValue::new(
3317 refany.node_graph.scale_factor * 100.0,
3318 )),
3319 ]
3320 .into(),
3321 ),
3322 );
3323 }
3324
3325 result
3326 }
3327 };
3328
3329 info.stop_propagation();
3330
3331 should_update
3332}
3333
3334extern "C" fn nodegraph_duplicate_node(mut refany: RefAny, _info: CallbackInfo) -> Update {
3335 let _data = match refany.downcast_mut::<NodeLocalDataset>() {
3336 Some(s) => s,
3337 None => return Update::DoNothing,
3338 };
3339
3340 Update::DoNothing }
3342
3343extern "C" fn nodegraph_delete_node(mut refany: RefAny, mut info: CallbackInfo) -> Update {
3344 let mut refany = match refany.downcast_mut::<NodeLocalDataset>() {
3345 Some(s) => s,
3346 None => return Update::DoNothing,
3347 };
3348
3349 let node_id = refany.node_id.clone();
3350
3351 let mut backref = match refany.backref.downcast_mut::<NodeGraphLocalDataset>() {
3352 Some(s) => s,
3353 None => return Update::DoNothing,
3354 };
3355
3356 let result = match backref.callbacks.on_node_removed.as_ref() {
3357 Some(OnNodeRemoved { callback, refany }) => (callback.cb)(refany.clone(), info, node_id),
3358 None => Update::DoNothing,
3359 };
3360
3361 result
3362}
3363
3364extern "C" fn nodegraph_context_menu_click(mut refany: RefAny, mut info: CallbackInfo) -> Update {
3365 use azul_core::window::CursorPosition;
3366
3367 let mut refany = match refany.downcast_mut::<ContextMenuEntryLocalDataset>() {
3368 Some(s) => s,
3369 None => return Update::DoNothing,
3370 };
3371
3372 let new_node_type = refany.node_type.clone();
3373
3374 let node_graph_wrapper_id = match info.get_node_id_of_root_dataset(refany.backref.clone()) {
3375 Some(s) => s,
3376 None => return Update::DoNothing,
3377 };
3378
3379 let mut backref = match refany.backref.downcast_mut::<NodeGraphLocalDataset>() {
3380 Some(s) => s,
3381 None => return Update::DoNothing,
3382 };
3383
3384 let node_wrapper_offset = info
3385 .get_node_position(node_graph_wrapper_id)
3386 .map(|p| p)
3387 .map(|p| (p.x, p.y))
3388 .unwrap_or((0.0, 0.0));
3389
3390 let cursor_in_viewport = match info.get_current_mouse_state().cursor_position {
3391 CursorPosition::InWindow(i) => i,
3392 CursorPosition::OutOfWindow(i) => i,
3393 _ => LogicalPosition::zero(),
3394 };
3395
3396 let new_node_pos = NodePosition {
3397 x: (cursor_in_viewport.x - node_wrapper_offset.0) * (1.0 / backref.node_graph.scale_factor)
3398 - backref.node_graph.offset.x,
3399 y: (cursor_in_viewport.y - node_wrapper_offset.1) * (1.0 / backref.node_graph.scale_factor)
3400 - backref.node_graph.offset.y,
3401 };
3402
3403 let new_node_id = backref.node_graph.generate_unique_node_id();
3404
3405 let result = match backref.callbacks.on_node_added.as_ref() {
3406 Some(OnNodeAdded { callback, refany }) => (callback.cb)(
3407 refany.clone(),
3408 info,
3409 new_node_type,
3410 new_node_id,
3411 new_node_pos,
3412 ),
3413 None => Update::DoNothing,
3414 };
3415
3416 result
3417}
3418
3419extern "C" fn nodegraph_input_output_connect(mut refany: RefAny, mut info: CallbackInfo) -> Update {
3420 use self::InputOrOutput::*;
3421
3422 let mut refany = match refany.downcast_mut::<NodeInputOutputLocalDataset>() {
3423 Some(s) => s,
3424 None => return Update::DoNothing,
3425 };
3426
3427 let io_id = refany.io_id.clone();
3428
3429 let mut backref = match refany.backref.downcast_mut::<NodeLocalDataset>() {
3430 Some(s) => s,
3431 None => return Update::DoNothing,
3432 };
3433
3434 let node_id = backref.node_id.clone();
3435
3436 let mut backref = match backref.backref.downcast_mut::<NodeGraphLocalDataset>() {
3437 Some(s) => s,
3438 None => return Update::DoNothing,
3439 };
3440
3441 let (input_node, input_index, output_node, output_index) =
3442 match backref.last_input_or_output_clicked.clone() {
3443 None => {
3444 backref.last_input_or_output_clicked = Some((node_id, io_id));
3445 return Update::DoNothing;
3446 }
3447 Some((prev_node_id, prev_io_id)) => {
3448 match (prev_io_id, io_id) {
3449 (Input(i), Output(o)) => (prev_node_id, i, node_id, o),
3450 (Output(o), Input(i)) => (node_id, i, prev_node_id, o),
3451 _ => {
3452 backref.last_input_or_output_clicked = None;
3454 return Update::DoNothing;
3455 }
3456 }
3457 }
3458 };
3459
3460 match backref.node_graph.connect_input_output(
3462 input_node,
3463 input_index,
3464 output_node,
3465 output_index,
3466 ) {
3467 Ok(_) => {}
3468 Err(e) => {
3469 eprintln!("{:?}", e);
3470 backref.last_input_or_output_clicked = None;
3471 return Update::DoNothing;
3472 }
3473 }
3474
3475 let result = match backref.callbacks.on_node_connected.as_ref() {
3476 Some(OnNodeConnected { callback, refany }) => {
3477 let r = (callback.cb)(
3478 refany.clone(),
3479 info,
3480 input_node,
3481 input_index,
3482 output_node,
3483 output_index,
3484 );
3485 backref.last_input_or_output_clicked = None;
3486 r
3487 }
3488 None => Update::DoNothing,
3489 };
3490
3491 result
3492}
3493
3494extern "C" fn nodegraph_input_output_disconnect(mut refany: RefAny, info: CallbackInfo) -> Update {
3495 use self::InputOrOutput::*;
3496
3497 let mut refany = match refany.downcast_mut::<NodeInputOutputLocalDataset>() {
3498 Some(s) => s,
3499 None => return Update::DoNothing,
3500 };
3501
3502 let io_id = refany.io_id.clone();
3503
3504 let mut backref = match refany.backref.downcast_mut::<NodeLocalDataset>() {
3505 Some(s) => s,
3506 None => return Update::DoNothing,
3507 };
3508
3509 let node_id = backref.node_id.clone();
3510
3511 let mut backref = match backref.backref.downcast_mut::<NodeGraphLocalDataset>() {
3512 Some(s) => s,
3513 None => return Update::DoNothing,
3514 };
3515
3516 let mut result = Update::DoNothing;
3517 match io_id {
3518 Input(i) => {
3519 result.max_self(
3520 match backref.callbacks.on_node_input_disconnected.as_ref() {
3521 Some(OnNodeInputDisconnected { callback, refany }) => {
3522 (callback.cb)(refany.clone(), info, node_id, i)
3523 }
3524 None => Update::DoNothing,
3525 },
3526 );
3527 }
3528 Output(o) => {
3529 result.max_self(
3530 match backref.callbacks.on_node_output_disconnected.as_ref() {
3531 Some(OnNodeOutputDisconnected { callback, refany }) => {
3532 (callback.cb)(refany.clone(), info, node_id, o)
3533 }
3534 None => Update::DoNothing,
3535 },
3536 );
3537 }
3538 };
3539
3540 result
3541}
3542
3543extern "C" fn nodegraph_on_textinput_focus_lost(
3544 mut refany: RefAny,
3545 info: CallbackInfo,
3546 textinputstate: TextInputState,
3547) -> Update {
3548 let mut refany = match refany.downcast_mut::<NodeFieldLocalDataset>() {
3549 Some(s) => s,
3550 None => return Update::DoNothing,
3551 };
3552
3553 let field_idx = refany.field_idx;
3554
3555 let mut node_local_dataset = match refany.backref.downcast_mut::<NodeLocalDataset>() {
3556 Some(s) => s,
3557 None => return Update::DoNothing,
3558 };
3559
3560 let node_id = node_local_dataset.node_id;
3561
3562 let mut node_graph = match node_local_dataset
3563 .backref
3564 .downcast_mut::<NodeGraphLocalDataset>()
3565 {
3566 Some(s) => s,
3567 None => return Update::DoNothing,
3568 };
3569
3570 let node_type = match node_graph
3571 .node_graph
3572 .nodes
3573 .iter()
3574 .find(|i| i.node_id == node_id)
3575 {
3576 Some(s) => s.node.node_type,
3577 None => return Update::DoNothing,
3578 };
3579
3580 let result = match node_graph.callbacks.on_node_field_edited.as_ref() {
3581 Some(OnNodeFieldEdited { refany, callback }) => (callback.cb)(
3582 refany.clone(),
3583 info,
3584 node_id,
3585 field_idx,
3586 node_type,
3587 NodeTypeFieldValue::TextInput(textinputstate.get_text().into()),
3588 ),
3589 None => Update::DoNothing,
3590 };
3591
3592 result
3593}
3594
3595extern "C" fn nodegraph_on_numberinput_focus_lost(
3596 mut refany: RefAny,
3597 info: CallbackInfo,
3598 numberinputstate: NumberInputState,
3599) -> Update {
3600 let mut refany = match refany.downcast_mut::<NodeFieldLocalDataset>() {
3601 Some(s) => s,
3602 None => return Update::DoNothing,
3603 };
3604
3605 let field_idx = refany.field_idx;
3606
3607 let mut node_local_dataset = match refany.backref.downcast_mut::<NodeLocalDataset>() {
3608 Some(s) => s,
3609 None => return Update::DoNothing,
3610 };
3611
3612 let node_id = node_local_dataset.node_id;
3613
3614 let mut node_graph = match node_local_dataset
3615 .backref
3616 .downcast_mut::<NodeGraphLocalDataset>()
3617 {
3618 Some(s) => s,
3619 None => return Update::DoNothing,
3620 };
3621
3622 let node_type = match node_graph
3623 .node_graph
3624 .nodes
3625 .iter()
3626 .find(|i| i.node_id == node_id)
3627 {
3628 Some(s) => s.node.node_type,
3629 None => return Update::DoNothing,
3630 };
3631
3632 let result = match node_graph.callbacks.on_node_field_edited.as_ref() {
3633 Some(OnNodeFieldEdited { refany, callback }) => (callback.cb)(
3634 refany.clone(),
3635 info,
3636 node_id,
3637 field_idx,
3638 node_type,
3639 NodeTypeFieldValue::NumberInput(numberinputstate.number),
3640 ),
3641 None => Update::DoNothing,
3642 };
3643
3644 result
3645}
3646
3647extern "C" fn nodegraph_on_checkbox_value_changed(
3648 mut refany: RefAny,
3649 info: CallbackInfo,
3650 checkboxinputstate: CheckBoxState,
3651) -> Update {
3652 let mut refany = match refany.downcast_mut::<NodeFieldLocalDataset>() {
3653 Some(s) => s,
3654 None => return Update::DoNothing,
3655 };
3656
3657 let field_idx = refany.field_idx;
3658
3659 let mut node_local_dataset = match refany.backref.downcast_mut::<NodeLocalDataset>() {
3660 Some(s) => s,
3661 None => return Update::DoNothing,
3662 };
3663
3664 let node_id = node_local_dataset.node_id;
3665
3666 let mut node_graph = match node_local_dataset
3667 .backref
3668 .downcast_mut::<NodeGraphLocalDataset>()
3669 {
3670 Some(s) => s,
3671 None => return Update::DoNothing,
3672 };
3673
3674 let node_type = match node_graph
3675 .node_graph
3676 .nodes
3677 .iter()
3678 .find(|i| i.node_id == node_id)
3679 {
3680 Some(s) => s.node.node_type,
3681 None => return Update::DoNothing,
3682 };
3683
3684 let result = match node_graph.callbacks.on_node_field_edited.as_ref() {
3685 Some(OnNodeFieldEdited { refany, callback }) => (callback.cb)(
3686 refany.clone(),
3687 info,
3688 node_id,
3689 field_idx,
3690 node_type,
3691 NodeTypeFieldValue::CheckBox(checkboxinputstate.checked),
3692 ),
3693 None => Update::DoNothing,
3694 };
3695
3696 result
3697}
3698
3699extern "C" fn nodegraph_on_colorinput_value_changed(
3700 mut refany: RefAny,
3701 info: CallbackInfo,
3702 colorinputstate: ColorInputState,
3703) -> Update {
3704 let mut refany = match refany.downcast_mut::<NodeFieldLocalDataset>() {
3705 Some(s) => s,
3706 None => return Update::DoNothing,
3707 };
3708
3709 let field_idx = refany.field_idx;
3710
3711 let mut node_local_dataset = match refany.backref.downcast_mut::<NodeLocalDataset>() {
3712 Some(s) => s,
3713 None => return Update::DoNothing,
3714 };
3715
3716 let node_id = node_local_dataset.node_id;
3717 let mut node_graph = match node_local_dataset
3718 .backref
3719 .downcast_mut::<NodeGraphLocalDataset>()
3720 {
3721 Some(s) => s,
3722 None => return Update::DoNothing,
3723 };
3724
3725 let node_type = match node_graph
3726 .node_graph
3727 .nodes
3728 .iter()
3729 .find(|i| i.node_id == node_id)
3730 {
3731 Some(s) => s.node.node_type,
3732 None => return Update::DoNothing,
3733 };
3734
3735 let result = match node_graph.callbacks.on_node_field_edited.as_ref() {
3736 Some(OnNodeFieldEdited { refany, callback }) => (callback.cb)(
3737 refany.clone(),
3738 info,
3739 node_id,
3740 field_idx,
3741 node_type,
3742 NodeTypeFieldValue::ColorInput(colorinputstate.color),
3743 ),
3744 None => Update::DoNothing,
3745 };
3746
3747 result
3748}
3749
3750extern "C" fn nodegraph_on_fileinput_button_clicked(
3751 mut refany: RefAny,
3752 info: CallbackInfo,
3753 file: FileInputState,
3754) -> Update {
3755 let mut refany = match refany.downcast_mut::<NodeFieldLocalDataset>() {
3756 Some(s) => s,
3757 None => return Update::DoNothing,
3758 };
3759
3760 let field_idx = refany.field_idx;
3761
3762 let mut node_local_dataset = match refany.backref.downcast_mut::<NodeLocalDataset>() {
3763 Some(s) => s,
3764 None => return Update::DoNothing,
3765 };
3766
3767 let node_id = node_local_dataset.node_id;
3768 let mut node_graph = match node_local_dataset
3769 .backref
3770 .downcast_mut::<NodeGraphLocalDataset>()
3771 {
3772 Some(s) => s,
3773 None => return Update::DoNothing,
3774 };
3775
3776 let node_type = match node_graph
3777 .node_graph
3778 .nodes
3779 .iter()
3780 .find(|i| i.node_id == node_id)
3781 {
3782 Some(s) => s.node.node_type,
3783 None => return Update::DoNothing,
3784 };
3785
3786 let result = match node_graph.callbacks.on_node_field_edited.as_ref() {
3788 Some(OnNodeFieldEdited { refany, callback }) => (callback.cb)(
3789 refany.clone(),
3790 info,
3791 node_id,
3792 field_idx,
3793 node_type,
3794 NodeTypeFieldValue::FileInput(file.path.clone()),
3795 ),
3796 None => return Update::DoNothing,
3797 };
3798
3799 result
3800}