@@ -256,6 +256,7 @@ impl NodeNetworkInterface {
256
256
encapsulating_node. inputs . len ( )
257
257
} else {
258
258
// There is one(?) import to the document network, but the imports are not displayed
259
+ // I think this is zero now that the scope system has been added
259
260
1
260
261
}
261
262
}
@@ -1896,6 +1897,109 @@ impl NodeNetworkInterface {
1896
1897
network_metadata. transient_metadata . import_export_ports . unload ( ) ;
1897
1898
}
1898
1899
1900
+ pub fn modify_import_export ( & mut self , network_path : & [ NodeId ] ) -> Option < & ModifyImportExportClickTarget > {
1901
+ let Some ( network_metadata) = self . network_metadata ( network_path) else {
1902
+ log:: error!( "Could not get nested network_metadata in modify_import_export" ) ;
1903
+ return None ;
1904
+ } ;
1905
+ if !network_metadata. transient_metadata . modify_import_export . is_loaded ( ) {
1906
+ self . load_modify_import_export ( network_path) ;
1907
+ }
1908
+ let Some ( network_metadata) = self . network_metadata ( network_path) else {
1909
+ log:: error!( "Could not get nested network_metadata in modify_import_export" ) ;
1910
+ return None ;
1911
+ } ;
1912
+ let TransientMetadata :: Loaded ( click_targets) = & network_metadata. transient_metadata . modify_import_export else {
1913
+ log:: error!( "could not load modify import export ports" ) ;
1914
+ return None ;
1915
+ } ;
1916
+ Some ( click_targets)
1917
+ }
1918
+
1919
+ pub fn load_modify_import_export ( & mut self , network_path : & [ NodeId ] ) {
1920
+ let Some ( all_nodes_bounding_box) = self . all_nodes_bounding_box ( network_path) . cloned ( ) else {
1921
+ log:: error!( "Could not get all nodes bounding box in load_export_ports" ) ;
1922
+ return ;
1923
+ } ;
1924
+ let Some ( rounded_network_edge_distance) = self . rounded_network_edge_distance ( network_path) . cloned ( ) else {
1925
+ log:: error!( "Could not get rounded_network_edge_distance in load_export_ports" ) ;
1926
+ return ;
1927
+ } ;
1928
+ let Some ( network_metadata) = self . network_metadata ( network_path) else {
1929
+ log:: error!( "Could not get nested network_metadata in load_export_ports" ) ;
1930
+ return ;
1931
+ } ;
1932
+ let Some ( network) = self . network ( network_path) else {
1933
+ log:: error!( "Could not get current network in load_export_ports" ) ;
1934
+ return ;
1935
+ } ;
1936
+
1937
+ let viewport_top_right = network_metadata
1938
+ . persistent_metadata
1939
+ . navigation_metadata
1940
+ . node_graph_to_viewport
1941
+ . inverse ( )
1942
+ . transform_point2 ( rounded_network_edge_distance. exports_to_edge_distance ) ;
1943
+ let offset_from_top_right = if network
1944
+ . exports
1945
+ . first ( )
1946
+ . is_some_and ( |export| export. as_node ( ) . is_some_and ( |export_node| self . is_layer ( & export_node, network_path) ) )
1947
+ {
1948
+ DVec2 :: new ( 2. * GRID_SIZE as f64 , -2. * GRID_SIZE as f64 )
1949
+ } else {
1950
+ DVec2 :: new ( 4. * GRID_SIZE as f64 , 0. )
1951
+ } ;
1952
+
1953
+ let bounding_box_top_right = DVec2 :: new ( ( all_nodes_bounding_box[ 1 ] . x / 24. + 0.5 ) . floor ( ) * 24. , ( all_nodes_bounding_box[ 0 ] . y / 24. + 0.5 ) . floor ( ) * 24. ) + offset_from_top_right;
1954
+ let export_top_right = DVec2 :: new ( viewport_top_right. x . max ( bounding_box_top_right. x ) , viewport_top_right. y . min ( bounding_box_top_right. y ) ) ;
1955
+ let add_export_center = export_top_right + DVec2 :: new ( 0. , network. exports . len ( ) as f64 * 24. ) ;
1956
+ let add_export = ClickTarget :: new ( Subpath :: new_ellipse ( add_export_center - DVec2 :: new ( 8. , 8. ) , add_export_center + DVec2 :: new ( 8. , 8. ) ) , 0. ) ;
1957
+
1958
+ let viewport_top_left = network_metadata
1959
+ . persistent_metadata
1960
+ . navigation_metadata
1961
+ . node_graph_to_viewport
1962
+ . inverse ( )
1963
+ . transform_point2 ( rounded_network_edge_distance. imports_to_edge_distance ) ;
1964
+
1965
+ let offset_from_top_left = if network
1966
+ . exports
1967
+ . first ( )
1968
+ . is_some_and ( |export| export. as_node ( ) . is_some_and ( |export_node| self . is_layer ( & export_node, network_path) ) )
1969
+ {
1970
+ DVec2 :: new ( -4. * GRID_SIZE as f64 , -2. * GRID_SIZE as f64 )
1971
+ } else {
1972
+ DVec2 :: new ( -4. * GRID_SIZE as f64 , 0. )
1973
+ } ;
1974
+
1975
+ let bounding_box_top_left = DVec2 :: new ( ( all_nodes_bounding_box[ 0 ] . x / 24. + 0.5 ) . floor ( ) * 24. , ( all_nodes_bounding_box[ 0 ] . y / 24. + 0.5 ) . floor ( ) * 24. ) + offset_from_top_left;
1976
+ let import_top_left = DVec2 :: new ( viewport_top_left. x . min ( bounding_box_top_left. x ) , viewport_top_left. y . min ( bounding_box_top_left. y ) ) ;
1977
+ let add_import_center = import_top_left + DVec2 :: new ( 0. , self . number_of_displayed_imports ( network_path) as f64 * 24. ) ;
1978
+ let add_import = ClickTarget :: new ( Subpath :: new_ellipse ( add_import_center - DVec2 :: new ( 8. , 8. ) , add_import_center + DVec2 :: new ( 8. , 8. ) ) , 0. ) ;
1979
+
1980
+ let Some ( network_metadata) = self . network_metadata_mut ( network_path) else {
1981
+ log:: error!( "Could not get current network in load_modify_import_export" ) ;
1982
+ return ;
1983
+ } ;
1984
+
1985
+ network_metadata. transient_metadata . modify_import_export = TransientMetadata :: Loaded ( ModifyImportExportClickTarget {
1986
+ add_export,
1987
+ add_import,
1988
+ remove_imports : Vec :: new ( ) ,
1989
+ remove_exports : Vec :: new ( ) ,
1990
+ move_import : Vec :: new ( ) ,
1991
+ move_export : Vec :: new ( ) ,
1992
+ } ) ;
1993
+ }
1994
+
1995
+ fn unload_modify_import_export ( & mut self , network_path : & [ NodeId ] ) {
1996
+ let Some ( network_metadata) = self . network_metadata_mut ( network_path) else {
1997
+ log:: error!( "Could not get nested network_metadata in unload_export_ports" ) ;
1998
+ return ;
1999
+ } ;
2000
+ network_metadata. transient_metadata . modify_import_export . unload ( ) ;
2001
+ }
2002
+
1899
2003
pub fn rounded_network_edge_distance ( & mut self , network_path : & [ NodeId ] ) -> Option < & NetworkEdgeDistance > {
1900
2004
let Some ( network_metadata) = self . network_metadata ( network_path) else {
1901
2005
log:: error!( "Could not get nested network_metadata in rounded_network_edge_distance" ) ;
@@ -2981,6 +3085,7 @@ impl NodeNetworkInterface {
2981
3085
} ;
2982
3086
network_metadata. persistent_metadata . navigation_metadata . node_graph_to_viewport = transform;
2983
3087
self . unload_import_export_ports ( network_path) ;
3088
+ self . unload_modify_import_export ( network_path) ;
2984
3089
}
2985
3090
2986
3091
// This should be run whenever the pan ends, a zoom occurs, or the network is opened
@@ -2992,6 +3097,7 @@ impl NodeNetworkInterface {
2992
3097
network_metadata. persistent_metadata . navigation_metadata . node_graph_top_right = node_graph_top_right;
2993
3098
self . unload_rounded_network_edge_distance ( network_path) ;
2994
3099
self . unload_import_export_ports ( network_path) ;
3100
+ self . unload_modify_import_export ( network_path) ;
2995
3101
}
2996
3102
2997
3103
pub fn vector_modify ( & mut self , node_id : & NodeId , modification_type : VectorModificationType ) {
@@ -3045,6 +3151,7 @@ impl NodeNetworkInterface {
3045
3151
3046
3152
// Update the export ports and outward wires for the current network
3047
3153
self . unload_import_export_ports ( network_path) ;
3154
+ self . unload_modify_import_export ( network_path) ;
3048
3155
self . unload_outward_wires ( network_path) ;
3049
3156
3050
3157
// Update the outward wires and bounding box for all nodes in the encapsulating network
@@ -3066,17 +3173,17 @@ impl NodeNetworkInterface {
3066
3173
3067
3174
/// Inserts a new input at insert index. If the insert index is -1 it is inserted at the end. The output_name is used by the encapsulating node.
3068
3175
pub fn add_import ( & mut self , default_value : TaggedValue , exposed : bool , insert_index : isize , input_name : String , network_path : & [ NodeId ] ) {
3069
- let mut network_path = network_path. to_vec ( ) ;
3070
- let Some ( node_id) = network_path . pop ( ) else {
3176
+ let mut encapsulating_network_path = network_path. to_vec ( ) ;
3177
+ let Some ( node_id) = encapsulating_network_path . pop ( ) else {
3071
3178
log:: error!( "Cannot add import for document network" ) ;
3072
3179
return ;
3073
3180
} ;
3074
3181
// Set the node to be a non layer if it is no longer eligible to be a layer
3075
- if !self . is_eligible_to_be_layer ( & node_id, & network_path ) && self . is_layer ( & node_id, & network_path ) {
3076
- self . set_to_node_or_layer ( & node_id, & network_path , false ) ;
3182
+ if !self . is_eligible_to_be_layer ( & node_id, & encapsulating_network_path ) && self . is_layer ( & node_id, & encapsulating_network_path ) {
3183
+ self . set_to_node_or_layer ( & node_id, & encapsulating_network_path , false ) ;
3077
3184
}
3078
3185
3079
- let Some ( network) = self . network_mut ( & network_path ) else {
3186
+ let Some ( network) = self . network_mut ( & encapsulating_network_path ) else {
3080
3187
log:: error!( "Could not get nested network in insert_input" ) ;
3081
3188
return ;
3082
3189
} ;
@@ -3094,7 +3201,7 @@ impl NodeNetworkInterface {
3094
3201
3095
3202
self . transaction_modified ( ) ;
3096
3203
3097
- let Some ( node_metadata) = self . node_metadata_mut ( & node_id, & network_path ) else {
3204
+ let Some ( node_metadata) = self . node_metadata_mut ( & node_id, & encapsulating_network_path ) else {
3098
3205
log:: error!( "Could not get node_metadata in insert_input" ) ;
3099
3206
return ;
3100
3207
} ;
@@ -3111,14 +3218,18 @@ impl NodeNetworkInterface {
3111
3218
}
3112
3219
3113
3220
// Update the click targets for the node
3114
- self . unload_node_click_targets ( & node_id, & network_path ) ;
3221
+ self . unload_node_click_targets ( & node_id, & encapsulating_network_path ) ;
3115
3222
3116
3223
// Update the transient network metadata bounding box for all nodes and outward wires
3117
- self . unload_all_nodes_bounding_box ( & network_path) ;
3118
- self . unload_outward_wires ( & network_path) ;
3224
+ self . unload_all_nodes_bounding_box ( & encapsulating_network_path) ;
3225
+
3226
+ // Unload the metadata for the nested network
3227
+ self . unload_outward_wires ( network_path) ;
3228
+ self . unload_import_export_ports ( network_path) ;
3229
+ self . unload_modify_import_export ( network_path) ;
3119
3230
3120
3231
// If the input is inserted as the first input, then it may have affected the document metadata structure
3121
- if network_path . is_empty ( ) && ( insert_index == 0 || insert_index == 1 ) {
3232
+ if encapsulating_network_path . is_empty ( ) && ( insert_index == 0 || insert_index == 1 ) {
3122
3233
self . load_structure ( ) ;
3123
3234
}
3124
3235
}
@@ -3915,6 +4026,7 @@ impl NodeNetworkInterface {
3915
4026
self . unload_upstream_node_click_targets ( vec ! [ * node_id] , network_path) ;
3916
4027
self . unload_all_nodes_bounding_box ( network_path) ;
3917
4028
self . unload_import_export_ports ( network_path) ;
4029
+ self . unload_modify_import_export ( network_path) ;
3918
4030
self . load_structure ( ) ;
3919
4031
}
3920
4032
@@ -5341,10 +5453,25 @@ pub struct NodeNetworkTransientMetadata {
5341
5453
// pub wire_paths: Vec<WirePath>
5342
5454
/// All export connector click targets
5343
5455
pub import_export_ports : TransientMetadata < Ports > ,
5456
+ /// Click targets for adding, removing, and moving import/export ports
5457
+ pub modify_import_export : TransientMetadata < ModifyImportExportClickTarget > ,
5344
5458
// Distance to the edges of the network, where the import/export ports are displayed. Rounded to nearest grid space when the panning ends.
5345
5459
pub rounded_network_edge_distance : TransientMetadata < NetworkEdgeDistance > ,
5346
5460
}
5347
5461
5462
+ #[ derive( Debug , Clone ) ]
5463
+ pub struct ModifyImportExportClickTarget {
5464
+ // Plus icon that appears below all imports/exports
5465
+ pub add_import : ClickTarget ,
5466
+ pub add_export : ClickTarget ,
5467
+ // Subtract icon that appears when hovering over an import/export
5468
+ pub remove_imports : Vec < ClickTarget > ,
5469
+ pub remove_exports : Vec < ClickTarget > ,
5470
+ // Grip drag icon that appears when hovering over an import/export
5471
+ pub move_import : Vec < ClickTarget > ,
5472
+ pub move_export : Vec < ClickTarget > ,
5473
+ }
5474
+
5348
5475
#[ derive( Debug , Clone ) ]
5349
5476
pub struct NetworkEdgeDistance {
5350
5477
/// The viewport pixel distance between the left edge of the node graph and the exports.
0 commit comments