diff --git a/gui/src/rust/lib/graph-editor/src/component/node.rs b/gui/src/rust/lib/graph-editor/src/component/node.rs index fa61e71cde..f9361bca4f 100644 --- a/gui/src/rust/lib/graph-editor/src/component/node.rs +++ b/gui/src/rust/lib/graph-editor/src/component/node.rs @@ -283,7 +283,7 @@ impl NodeModel { let scene = scene.clone_ref(); let input = InputEvents::new(&network); - let visualization_container = visualization::Container::new(); + let visualization_container = visualization::Container::new(&scene); visualization_container.mod_position(|t| { t.x = 60.0; t.y = -120.0; diff --git a/gui/src/rust/lib/graph-editor/src/component/visualization/container.rs b/gui/src/rust/lib/graph-editor/src/component/visualization/container.rs index dce3759644..575d82919c 100644 --- a/gui/src/rust/lib/graph-editor/src/component/visualization/container.rs +++ b/gui/src/rust/lib/graph-editor/src/component/visualization/container.rs @@ -5,11 +5,11 @@ use crate::prelude::*; use crate::frp; use crate::visualization::*; +use ensogl::display::Scene; use ensogl::display::traits::*; use ensogl::display; - // =========== // === FRP === // =========== @@ -84,7 +84,7 @@ impl ContainerData { } /// Indicates whether the visualization is visible. - fn is_visible(&self) -> bool { + pub fn is_visible(&self) -> bool { if let Some(vis) = self.visualization.borrow().as_ref() { vis.has_parent() } else { @@ -125,13 +125,15 @@ impl display::Object for ContainerData { impl Container { /// Constructor. - pub fn new() -> Self { + pub fn new(scene:&Scene) -> Self { let logger = Logger::new("visualization"); let visualization = default(); let size = Cell::new(Vector2::new(200.0, 200.0)); let display_object = display::object::Instance::new(&logger); let data = ContainerData {logger,visualization,size,display_object}; let data = Rc::new(data); + data.set_visualization(Registry::default_visualisation(&scene)); + data.set_visibility(false); let frp = default(); Self {data,frp} . init_frp() } @@ -167,12 +169,6 @@ impl Container { } } -impl Default for Container { - fn default() -> Self { - Container::new() - } -} - impl display::Object for Container { fn display_object(&self) -> &display::object::Instance { &self.data.display_object diff --git a/gui/src/rust/lib/graph-editor/src/component/visualization/registry.rs b/gui/src/rust/lib/graph-editor/src/component/visualization/registry.rs index 3b5ccaef6b..85023735ec 100644 --- a/gui/src/rust/lib/graph-editor/src/component/visualization/registry.rs +++ b/gui/src/rust/lib/graph-editor/src/component/visualization/registry.rs @@ -106,4 +106,16 @@ impl Registry { let entries = self.entries.borrow(); entries.get(dtype).cloned().unwrap_or_else(default) } + + /// Return a default visualisation class. + pub fn default_visualisation(scene:&Scene) -> Visualization { + let class = NativeConstructorClass::new( + Signature { + name : "Raw Text Visualization (native)".to_string(), + input_types : vec!["[[Float,Float,Float]]".to_string().into()], + }, + |scene:&Scene| Ok(Visualization::new(RawText::new(scene))) + ); + class.instantiate(&scene).expect("Failed to instantiate default visualisation") + } } diff --git a/gui/src/rust/lib/graph-editor/src/component/visualization/renderer/example/native.rs b/gui/src/rust/lib/graph-editor/src/component/visualization/renderer/example/native.rs index f96932953a..c8750ffd4c 100644 --- a/gui/src/rust/lib/graph-editor/src/component/visualization/renderer/example/native.rs +++ b/gui/src/rust/lib/graph-editor/src/component/visualization/renderer/example/native.rs @@ -67,7 +67,6 @@ impl DataRenderer for BubbleChart { fn receive_data(&self, data:Data) -> Result<(),DataError> { let data_inner: Rc>> = data.as_binary()?; - // Avoid re-creating views, if we have already created some before. let mut views = self.views.borrow_mut(); views.resize_with(data_inner.len(),|| component::ShapeView::new(&self.logger,&self.scene)); diff --git a/gui/src/rust/lib/graph-editor/src/lib.rs b/gui/src/rust/lib/graph-editor/src/lib.rs index 8978576cd4..2efdecb300 100644 --- a/gui/src/rust/lib/graph-editor/src/lib.rs +++ b/gui/src/rust/lib/graph-editor/src/lib.rs @@ -356,12 +356,11 @@ pub struct FrpInputs { pub remove_node : frp::Source, pub set_node_expression : frp::Source<(NodeId,node::Expression)>, pub set_node_position : frp::Source<(NodeId,Position)>, - pub set_visualization_data : frp::Source, pub translate_selected_nodes : frp::Source, pub cycle_visualization : frp::Source, pub set_visualization : frp::Source<(NodeId,Option)>, pub register_visualization_class : frp::Source>>, - + pub set_visualization_data : frp::Source<(NodeId,Option)>, hover_node_input : frp::Source>, some_edge_targets_detached : frp::Source, @@ -396,6 +395,7 @@ impl FrpInputs { def hover_node_input = source(); def some_edge_targets_detached = source(); def all_edge_targets_attached = source(); + } let commands = Commands::new(&network); Self {commands,remove_edge,press_node_input,remove_all_node_edges @@ -497,6 +497,9 @@ generate_frp_outputs! { connection_added : EdgeId, connection_removed : EdgeId, + + visualization_enabled : NodeId, + visualization_disabled : NodeId, } @@ -1521,17 +1524,21 @@ fn new_graph_editor(world:&World) -> GraphEditor { // TODO remove this once real data is available. let sample_data_generator = MockDataGenerator3D::default(); - def _set_dumy_data = inputs.debug_set_data_for_selected_node.map(f!([nodes](_) { + def _set_dumy_data = inputs.debug_set_data_for_selected_node.map(f!([nodes,inputs](_) { nodes.selected.for_each(|node_id| { let data = Rc::new(sample_data_generator.generate_data()); let content = Rc::new(serde_json::to_value(data).unwrap()); let data = visualization::Data::JSON{ content }; - if let Some(node) = nodes.get_cloned(node_id) { - node.view.visualization_container.frp.set_data.emit(Some(data)); - } + inputs.set_visualization_data.emit((*node_id,Some(data))); }) })); + def _set_data = inputs.set_visualization_data.map(f!([nodes]((node_id,data)) { + if let Some(node) = nodes.get_cloned(node_id) { + node.view.visualization_container.frp.set_data.emit(data); + } + })); + let cycle_count = Rc::new(Cell::new(0)); def _cycle_visualization = inputs.cycle_visualization.map(f!([scene,nodes,visualization_registry,logger](node_id) { let visualizations = visualization_registry.valid_sources(&"[[Float,Float,Float]]".into()); @@ -1549,15 +1556,25 @@ fn new_graph_editor(world:&World) -> GraphEditor { cycle_count.set(cycle_count.get() + 1); })); - def _toggle_selected = inputs.toggle_visualization_visibility.map(f!([nodes](_) { + def on_visualization_enabled = source(); + def on_visualization_disabled = source(); + + def _toggle_selected = inputs.toggle_visualization_visibility.map(f!([nodes,on_visualization_enabled,on_visualization_disabled](_) { nodes.selected.for_each(|node_id| { if let Some(node) = nodes.get_cloned_ref(node_id) { node.view.visualization_container.frp.toggle_visibility.emit(()); + if node.view.visualization_container.is_visible() { + on_visualization_enabled.emit(node_id); + } else { + on_visualization_disabled.emit(node_id); + } } }); - })); + outputs.visualization_enabled <+ on_visualization_enabled; + outputs.visualization_disabled <+ on_visualization_disabled; + // === Register Visualization === def _register_visualization = inputs.register_visualization_class.map(f!([visualization_registry](handle) {