Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement loading spinner for visualisations. #6512

Merged
merged 6 commits into from
May 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
belongs to the node.][6487].
- [List Editor Widget][6470]. Now you can edit lists by clicking buttons on
nodes or by dragging the elements.
- [Visualisations now show a loading spinner while waiting on data.][6512].
- [Fixed text visualisations which were being cut off at the last line.][6421]
- [Fixed a bug where, when scrolling or dragging on a full-screen visualization,
the view of the graph changed as well.][6530]
Expand Down Expand Up @@ -216,6 +217,7 @@
[6487]: https://github.com/enso-org/enso/pull/6487
[6341]: https://github.com/enso-org/enso/pull/6341
[6470]: https://github.com/enso-org/enso/pull/6470
[6512]: https://github.com/enso-org/enso/pull/6512

#### Enso Standard Library

Expand Down
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/gui/view/documentation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ impl Model {
}

/// Load an HTML file into the documentation view when user is waiting for data to be received.
/// TODO(#184315201): This should be replaced with a EnsoGL spinner.
/// TODO(#5214): This should be replaced with a EnsoGL spinner.
fn load_waiting_screen(&self) {
let spinner = include_str!("../assets/spinner.html");
self.inner_dom.dom().set_inner_html(spinner)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::visualization;
use action_bar::ActionBar;
use enso_frp as frp;
use ensogl::application::Application;
use ensogl::data::color::Rgba;
use ensogl::display;
use ensogl::display::scene;
use ensogl::display::scene::Scene;
Expand Down Expand Up @@ -162,10 +163,11 @@ ensogl::define_endpoints! {
pub struct View {
display_object: display::object::Instance,

background: background::View,
overlay: overlay::View,
background_dom: DomSymbol,
scene: Scene,
background: background::View,
overlay: overlay::View,
background_dom: DomSymbol,
scene: Scene,
loading_spinner: ensogl_component::spinner::View,
}

impl View {
Expand All @@ -176,16 +178,38 @@ impl View {
let overlay = overlay::View::new();
display_object.add_child(&background);
display_object.add_child(&overlay);
let div = web::document.create_div_or_panic();
let background_dom = DomSymbol::new(&div);
display_object.add_child(&background_dom);
let loading_spinner = ensogl_component::spinner::View::new();

ensogl::shapes_order_dependencies! {
scene => {
background -> overlay;
background -> ensogl_component::spinner;
}
};

Self { display_object, background, overlay, background_dom, scene, loading_spinner }.init()
}

fn set_layer(&self, layer: visualization::Layer) {
layer.apply_for_html_component(&self.scene, &self.background_dom);
}

fn show_waiting_screen(&self) {
self.add_child(&self.loading_spinner);
}

fn disable_waiting_screen(&self) {
self.loading_spinner.unset_parent();
}

fn init_background(&self) {
let background = &self.background_dom;
// FIXME : StyleWatch is unsuitable here, as it was designed as an internal tool for shape
// system (#795)
let styles = StyleWatch::new(&scene.style_sheet);
let styles = StyleWatch::new(&self.scene.style_sheet);
let bg_color =
styles.get_color(ensogl_hardcoded_theme::graph_editor::visualization::background);
let bg_hex = format!(
Expand All @@ -196,29 +220,29 @@ impl View {
bg_color.alpha
);

let div = web::document.create_div_or_panic();
let background_dom = DomSymbol::new(&div);
// TODO : We added a HTML background to the `View`, because "shape" background was
// overlapping the JS visualization. This should be further investigated
// while fixing rust visualization displaying. (#796)
background_dom.dom().set_style_or_warn("width", "0");
background_dom.dom().set_style_or_warn("height", "0");
background_dom.dom().set_style_or_warn("z-index", "1");
background_dom.dom().set_style_or_warn("overflow-y", "auto");
background_dom.dom().set_style_or_warn("overflow-x", "auto");
background_dom.dom().set_style_or_warn("background", bg_hex);
background_dom.dom().set_style_or_warn("border-radius", "14px");
shadow::add_to_dom_element(&background_dom, &styles);
display_object.add_child(&background_dom);

Self { display_object, background, overlay, background_dom, scene }.init()
background.dom().set_style_or_warn("width", "0");
background.dom().set_style_or_warn("height", "0");
background.dom().set_style_or_warn("z-index", "1");
background.dom().set_style_or_warn("overflow-y", "auto");
background.dom().set_style_or_warn("overflow-x", "auto");
background.dom().set_style_or_warn("background", bg_hex);
background.dom().set_style_or_warn("border-radius", "14px");
shadow::add_to_dom_element(background, &styles);
}

fn set_layer(&self, layer: visualization::Layer) {
layer.apply_for_html_component(&self.scene, &self.background_dom);
fn init_spinner(&self) {
let spinner = &self.loading_spinner;
spinner.scale.set(5.0);
spinner.rgba.set(Rgba::black().into())
}

fn init(self) -> Self {
self.init_background();
self.init_spinner();
self.show_waiting_screen();
self.set_layer(visualization::Layer::Default);
self.scene.layers.viz.add(&self);
self
Expand Down Expand Up @@ -300,6 +324,8 @@ impl ContainerModel {
// FIXME: These 2 lines fix a bug with display objects visible on stage.
self.set_visibility(true);
self.set_visibility(false);

self.view.show_waiting_screen();
self
}

Expand Down Expand Up @@ -409,6 +435,7 @@ impl ContainerModel {
self.view.background.radius.set(CORNER_RADIUS);
self.view.overlay.set_size(size);
self.view.background.set_size(size + 2.0 * Vector2(PADDING, PADDING));
self.view.loading_spinner.set_size(size + 2.0 * Vector2(PADDING, PADDING));
dom.set_style_or_warn("width", format!("{}px", size[0]));
dom.set_style_or_warn("height", format!("{}px", size[1]));
bg_dom.set_style_or_warn("width", "0");
Expand Down Expand Up @@ -584,9 +611,17 @@ impl Container {
}
vis_definition.clone()
}));


// === Visualisation Loading Spinner ===

eval_ frp.source.visualisation ( model.view.show_waiting_screen() );
eval_ frp.set_data ( model.view.disable_waiting_screen() );

}



// === Selecting Visualization ===

frp::extend! { network
Expand Down
1 change: 1 addition & 0 deletions lib/rust/ensogl/component/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ ensogl-shadow = { path = "shadow" }
ensogl-text = { path = "text" }
ensogl-tooltip = { path = "tooltip" }
ensogl-toggle-button = { path = "toggle-button" }
ensogl-spinner = { path = "spinner" }
15 changes: 15 additions & 0 deletions lib/rust/ensogl/component/spinner/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "ensogl-spinner"
version = "0.1.0"
authors = ["Enso Team <[email protected]>"]
edition = "2021"

[lib]
crate-type = ["rlib", "cdylib"]

[dependencies]
enso-frp = { path = "../../../frp" }
enso-prelude = { path = "../../../prelude" }
enso-shapely = { path = "../../../shapely" }
enso-types = { path = "../../../types" }
ensogl-core = { path = "../../core" }
58 changes: 58 additions & 0 deletions lib/rust/ensogl/component/spinner/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//! An animated spinner component that can be used to indicate that a process
//! is running.

use ensogl_core::display::shape::*;
use ensogl_core::prelude::*;

use ensogl_core::display::IntoGlsl;



// ===============
// === Spinner ===
// ===============

const ANIMATION_SPEED: f32 = 0.001;
const SHAPE_RADIUS: f32 = 1.0;
const SHAPE_OFFSET: f32 = 2.0;
const ANIMATION_OFFSET_MS: f32 = 100.0;

/// Convert a time value to an alpha value for the spinner animation. The
/// animation is a sine wave that oscillates between 0 and 1.
fn time_to_alpha<F1: Into<Var<f32>>, F2: Into<Var<f32>>, F3: Into<Var<f32>>>(
time: F1,
offset: F2,
scale: F3,
) -> Var<f32> {
let time = time.into();
let offset = offset.into();
let scale = scale.into();
Var::from(0.5) + ((time + offset) * scale).sin() / 2.0
}

ensogl_core::shape! {
alignment = center;
(style: Style, scale: f32, rgba: Vector4<f32>) {
let time = &Var::<f32>::from("input_time");
let radius = (&scale * SHAPE_RADIUS).px();
let offset = (&scale * (SHAPE_RADIUS * 2.0 + SHAPE_OFFSET)).px();
let dot1 = Circle(&radius).translate_x(-&offset);
let dot2 = Circle(&radius);
let dot3 = Circle(&radius).translate_x(offset);
let dot3_anim_start = 0.0;
let dot2_anim_start = dot3_anim_start + ANIMATION_OFFSET_MS;
let dot1_anim_start = dot2_anim_start + ANIMATION_OFFSET_MS;
let dot1_alpha = rgba.w() * time_to_alpha(time, dot1_anim_start, ANIMATION_SPEED);
let dot2_alpha = rgba.w() * time_to_alpha(time, dot2_anim_start, ANIMATION_SPEED);
let dot3_alpha = rgba.w() * time_to_alpha(time, dot3_anim_start, ANIMATION_SPEED);
let rgb = rgba.xyz();
let color1 = format!("srgba({}.x,{}.y,{}.z,{})", rgb, rgb, rgb, dot1_alpha.glsl());
let color2 = format!("srgba({}.x,{}.y,{}.z,{})", rgb, rgb, rgb, dot2_alpha.glsl());
let color3 = format!("srgba({}.x,{}.y,{}.z,{})", rgb, rgb, rgb, dot3_alpha.glsl());
let dot1 = dot1.fill(color1);
let dot2 = dot2.fill(color2);
let dot3 = dot3.fill(color3);
let shape = dot1 + dot2 + dot3;
shape.into()
}
}
1 change: 1 addition & 0 deletions lib/rust/ensogl/component/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub use ensogl_scroll_area as scroll_area;
pub use ensogl_scrollbar as scrollbar;
pub use ensogl_selector as selector;
pub use ensogl_shadow as shadow;
pub use ensogl_spinner as spinner;
pub use ensogl_text as text;
pub use ensogl_toggle_button as toggle_button;
pub use ensogl_tooltip as tooltip;