Extend graph editor api to allow data to be set on visualizations and stream the visibility status of visualisations. (https://github.com/enso-org/ide/pull/507)

Original commit: 75a421cf88
This commit is contained in:
Michael Mauderer 2020-06-01 21:00:35 +02:00 committed by GitHub
parent b3906ae338
commit 403f8c19a5
5 changed files with 43 additions and 19 deletions

View File

@ -283,7 +283,7 @@ impl NodeModel {
let scene = scene.clone_ref(); let scene = scene.clone_ref();
let input = InputEvents::new(&network); let input = InputEvents::new(&network);
let visualization_container = visualization::Container::new(); let visualization_container = visualization::Container::new(&scene);
visualization_container.mod_position(|t| { visualization_container.mod_position(|t| {
t.x = 60.0; t.x = 60.0;
t.y = -120.0; t.y = -120.0;

View File

@ -5,11 +5,11 @@ use crate::prelude::*;
use crate::frp; use crate::frp;
use crate::visualization::*; use crate::visualization::*;
use ensogl::display::Scene;
use ensogl::display::traits::*; use ensogl::display::traits::*;
use ensogl::display; use ensogl::display;
// =========== // ===========
// === FRP === // === FRP ===
// =========== // ===========
@ -84,7 +84,7 @@ impl ContainerData {
} }
/// Indicates whether the visualization is visible. /// 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() { if let Some(vis) = self.visualization.borrow().as_ref() {
vis.has_parent() vis.has_parent()
} else { } else {
@ -125,13 +125,15 @@ impl display::Object for ContainerData {
impl Container { impl Container {
/// Constructor. /// Constructor.
pub fn new() -> Self { pub fn new(scene:&Scene) -> Self {
let logger = Logger::new("visualization"); let logger = Logger::new("visualization");
let visualization = default(); let visualization = default();
let size = Cell::new(Vector2::new(200.0, 200.0)); let size = Cell::new(Vector2::new(200.0, 200.0));
let display_object = display::object::Instance::new(&logger); let display_object = display::object::Instance::new(&logger);
let data = ContainerData {logger,visualization,size,display_object}; let data = ContainerData {logger,visualization,size,display_object};
let data = Rc::new(data); let data = Rc::new(data);
data.set_visualization(Registry::default_visualisation(&scene));
data.set_visibility(false);
let frp = default(); let frp = default();
Self {data,frp} . init_frp() 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 { impl display::Object for Container {
fn display_object(&self) -> &display::object::Instance { fn display_object(&self) -> &display::object::Instance {
&self.data.display_object &self.data.display_object

View File

@ -106,4 +106,16 @@ impl Registry {
let entries = self.entries.borrow(); let entries = self.entries.borrow();
entries.get(dtype).cloned().unwrap_or_else(default) 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")
}
} }

View File

@ -67,7 +67,6 @@ impl DataRenderer for BubbleChart {
fn receive_data(&self, data:Data) -> Result<(),DataError> { fn receive_data(&self, data:Data) -> Result<(),DataError> {
let data_inner: Rc<Vec<Vector3<f32>>> = data.as_binary()?; let data_inner: Rc<Vec<Vector3<f32>>> = data.as_binary()?;
// Avoid re-creating views, if we have already created some before. // Avoid re-creating views, if we have already created some before.
let mut views = self.views.borrow_mut(); let mut views = self.views.borrow_mut();
views.resize_with(data_inner.len(),|| component::ShapeView::new(&self.logger,&self.scene)); views.resize_with(data_inner.len(),|| component::ShapeView::new(&self.logger,&self.scene));

View File

@ -356,12 +356,11 @@ pub struct FrpInputs {
pub remove_node : frp::Source<NodeId>, pub remove_node : frp::Source<NodeId>,
pub set_node_expression : frp::Source<(NodeId,node::Expression)>, pub set_node_expression : frp::Source<(NodeId,node::Expression)>,
pub set_node_position : frp::Source<(NodeId,Position)>, pub set_node_position : frp::Source<(NodeId,Position)>,
pub set_visualization_data : frp::Source<NodeId>,
pub translate_selected_nodes : frp::Source<Position>, pub translate_selected_nodes : frp::Source<Position>,
pub cycle_visualization : frp::Source<NodeId>, pub cycle_visualization : frp::Source<NodeId>,
pub set_visualization : frp::Source<(NodeId,Option<Visualization>)>, pub set_visualization : frp::Source<(NodeId,Option<Visualization>)>,
pub register_visualization_class : frp::Source<Option<Rc<visualization::Handle>>>, pub register_visualization_class : frp::Source<Option<Rc<visualization::Handle>>>,
pub set_visualization_data : frp::Source<(NodeId,Option<visualization::Data>)>,
hover_node_input : frp::Source<Option<EdgeTarget>>, hover_node_input : frp::Source<Option<EdgeTarget>>,
some_edge_targets_detached : frp::Source, some_edge_targets_detached : frp::Source,
@ -396,6 +395,7 @@ impl FrpInputs {
def hover_node_input = source(); def hover_node_input = source();
def some_edge_targets_detached = source(); def some_edge_targets_detached = source();
def all_edge_targets_attached = source(); def all_edge_targets_attached = source();
} }
let commands = Commands::new(&network); let commands = Commands::new(&network);
Self {commands,remove_edge,press_node_input,remove_all_node_edges Self {commands,remove_edge,press_node_input,remove_all_node_edges
@ -497,6 +497,9 @@ generate_frp_outputs! {
connection_added : EdgeId, connection_added : EdgeId,
connection_removed : 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. // TODO remove this once real data is available.
let sample_data_generator = MockDataGenerator3D::default(); 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| { nodes.selected.for_each(|node_id| {
let data = Rc::new(sample_data_generator.generate_data()); let data = Rc::new(sample_data_generator.generate_data());
let content = Rc::new(serde_json::to_value(data).unwrap()); let content = Rc::new(serde_json::to_value(data).unwrap());
let data = visualization::Data::JSON{ content }; let data = visualization::Data::JSON{ content };
if let Some(node) = nodes.get_cloned(node_id) { inputs.set_visualization_data.emit((*node_id,Some(data)));
node.view.visualization_container.frp.set_data.emit(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)); let cycle_count = Rc::new(Cell::new(0));
def _cycle_visualization = inputs.cycle_visualization.map(f!([scene,nodes,visualization_registry,logger](node_id) { 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()); 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); 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| { nodes.selected.for_each(|node_id| {
if let Some(node) = nodes.get_cloned_ref(node_id) { if let Some(node) = nodes.get_cloned_ref(node_id) {
node.view.visualization_container.frp.toggle_visibility.emit(()); 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 === // === Register Visualization ===
def _register_visualization = inputs.register_visualization_class.map(f!([visualization_registry](handle) { def _register_visualization = inputs.register_visualization_class.map(f!([visualization_registry](handle) {