mirror of
https://github.com/enso-org/enso.git
synced 2024-12-22 07:21:34 +03:00
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:
parent
b3906ae338
commit
403f8c19a5
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user