Skip to content

Commit

Permalink
Make play button clickable and hide it when irrelevant (#6252)
Browse files Browse the repository at this point in the history
Closes #6177: Clicking the play button should show a spinner icon. The play button should only be visible on execution environments that have one or more execution contexts disabled.

https://user-images.githubusercontent.com/607786/231464097-8d6fafe4-1013-47d9-89e8-2a8e5d6d39a6.mp4

# Important Notes
There's a bug in the existing code that's exacerbated by this PR: the clickable area for the drop down menu is not directly placed on top of the text. Michael is fixing that in a [separate branch](https://github.com/enso-org/enso/tree/wip/MichaelMauderer/Ability_to_change_the_execution_environment_between_design_and_live_on_shortcut) (39ce6a2).
  • Loading branch information
Procrat authored Apr 13, 2023
1 parent 9d38b2b commit 9db317b
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 54 deletions.
2 changes: 1 addition & 1 deletion app/gui/src/presenter/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ impl Project {
/// implementation of #5930.
fn init_execution_modes(self) -> Self {
let graph = &self.model.view.graph();
let entries = Rc::new(vec!["development".to_string(), "production".to_string()]);
let entries = Rc::new(vec!["design".to_string(), "live".to_string()]);
graph.set_available_execution_modes(entries);
self
}
Expand Down
2 changes: 1 addition & 1 deletion app/gui/view/examples/execution-mode-dropdown/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use ide_view_execution_mode_selector as execution_mode_selector;
// ======================

fn make_entries() -> execution_mode_selector::ExecutionModes {
Rc::new(vec!["development".to_string(), "production".to_string()])
Rc::new(vec!["design".to_string(), "live".to_string()])
}

fn init(app: &Application) {
Expand Down
3 changes: 1 addition & 2 deletions app/gui/view/examples/interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,7 @@ fn init(app: &Application) {

// === Execution Modes ===

graph_editor
.set_available_execution_modes(vec!["development".to_string(), "production".to_string()]);
graph_editor.set_available_execution_modes(vec!["design".to_string(), "live".to_string()]);


// === Rendering ===
Expand Down
101 changes: 55 additions & 46 deletions app/gui/view/execution-mode-selector/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
#![warn(unused_import_braces)]
#![warn(unused_qualifications)]



mod play_button;

use enso_prelude::*;
use ensogl::prelude::*;

Expand All @@ -39,51 +43,31 @@ use ensogl_hardcoded_theme::graph_editor::execution_mode_selector as theme;

/// Theme specification for the execution mode selector.
#[derive(Debug, Clone, Copy, Default, FromTheme)]
#[base_path = "ensogl_hardcoded_theme::graph_editor::execution_mode_selector"]
#[base_path = "theme"]
pub struct Style {
play_button_size: f32,
play_button_offset: f32,
play_button_padding: f32,
divider_offset: f32,
divider_padding: f32,
dropdown_width: f32,
height: f32,
background: Rgba,
divider: Rgba,
menu_offset: f32,
divider_offset: f32,
divider_padding: f32,
dropdown_width: f32,
height: f32,
background: Rgba,
divider: Rgba,
menu_offset: f32,
#[theme_path = "theme::play_button::triangle_size"]
play_button_triangle_size: f32,
#[theme_path = "theme::play_button::padding_x"]
play_button_padding_x: f32,
}

impl Style {
fn overall_width(&self) -> f32 {
self.dropdown_width
+ 2.0 * self.divider_padding
+ self.play_button_size
+ self.play_button_padding
+ self.play_button_triangle_size
+ 2.0 * self.play_button_padding_x
}
}


// ==============
// === Shapes ===
// ==============

mod play_icon {
use super::*;

use std::f32::consts::PI;
ensogl::shape! {
above = [display::shape::compound::rectangle::shape];
(style:Style) {
let triangle_size = style.get_number(theme::play_button_size);
let color = style.get_color(theme::triangle);
let triangle = Triangle(triangle_size, triangle_size).rotate((PI/2.0).radians());
let triangle = triangle.fill(color);
let bg_size = Var::canvas_size();
let bg = Rect(bg_size).fill(INVISIBLE_HOVER_COLOR);
(bg + triangle).into()
}
}
}

// ===========
// === FRP ===
Expand All @@ -106,6 +90,7 @@ ensogl::define_endpoints_2! {
}



// =============
// === Model ===
// =============
Expand All @@ -120,7 +105,7 @@ pub struct Model {
inner_root: display::object::Instance,
background: display::shape::compound::rectangle::Rectangle,
divider: display::shape::compound::rectangle::Rectangle,
play_icon: play_icon::View,
play_button: play_button::PlayButton,
dropdown: ensogl_drop_down_menu::DropDownMenu,
}

Expand Down Expand Up @@ -148,12 +133,11 @@ impl Model {
self.divider.set_color(style.divider);
}

fn update_play_icon_style(&self, style: &Style) {
fn update_play_button_style(&self, style: &Style) {
let width = style.overall_width();
let size = Vector2::new(style.play_button_size + style.play_button_padding, style.height);
self.play_icon.set_size(size);
self.play_icon.set_x(width / 2.0 - style.play_button_offset - size.x / 2.0);
self.play_icon.set_y(-size.y / 2.0);
let Style { height, .. } = *style;
self.play_button.set_x(width / 2.0);
self.play_button.set_y(-height / 2.0);
}

fn update_position(&self, style: &Style, camera: &Camera2d) {
Expand All @@ -169,6 +153,16 @@ impl Model {
self.dropdown.set_entries(provider);
self.dropdown.set_selected(0);
}

fn set_play_button_visibility(&self, visible: bool) {
if visible {
self.inner_root.add_child(&self.play_button);
self.inner_root.add_child(&self.divider);
} else {
self.inner_root.remove_child(&self.play_button);
self.inner_root.remove_child(&self.divider);
}
}
}

impl display::Object for Model {
Expand All @@ -178,6 +172,7 @@ impl display::Object for Model {
}



// =============================
// === ExecutionModeDropdown ===
// =============================
Expand All @@ -194,12 +189,12 @@ impl component::Model for Model {
let inner_root = display::object::Instance::new();
let background = default();
let divider = default();
let play_icon = play_icon::View::new();
let play_button = play_button::PlayButton::new(app);
let dropdown = ensogl_drop_down_menu::DropDownMenu::new(app);

display_object.add_child(&inner_root);
inner_root.add_child(&dropdown);
inner_root.add_child(&play_icon);
inner_root.add_child(&play_button);
inner_root.add_child(&background);
inner_root.add_child(&divider);

Expand All @@ -211,7 +206,7 @@ impl component::Model for Model {
dropdown.restore_shape_constraints(app);


Self { display_object, background, play_icon, dropdown, inner_root, divider }
Self { display_object, background, play_button, dropdown, inner_root, divider }
}
}

Expand All @@ -226,7 +221,7 @@ impl component::Frp<Model> for Frp {
let scene = &app.display.default_scene;
let camera = scene.camera();
let dropdown = &model.dropdown;
let play_icon = &model.play_icon;
let play_button = &model.play_button;
let input = &frp.input;
let output = &frp.output;

Expand All @@ -246,7 +241,7 @@ impl component::Frp<Model> for Frp {
eval style_update((style) {
model.update_dropdown_style(style);
model.update_background_style(style);
model.update_play_icon_style(style);
model.update_play_button_style(style);
});

// == Inputs ==
Expand All @@ -258,9 +253,23 @@ impl component::Frp<Model> for Frp {
selected_entry <- selection.map(|(entries, entry_id)| entries[*entry_id].clone());
output.selected_execution_mode <+ selected_entry;

eval selected_entry ([model] (execution_mode) {
// TODO(#5930): Revisit when connecting with externally set execution mode
let play_button_visibility = match execution_mode.as_str() {
"design" => true,
"live" => false,
_ => {
error!("Play button: invalid execution mode");
false
}
};
model.set_play_button_visibility(play_button_visibility);
});
play_button.reset <+ selected_entry.constant(());

// == Outputs ==

output.play_press <+ play_icon.events_deprecated.mouse_down.constant(());
output.play_press <+ play_button.pressed;
output.size <+ style_update.map(|style| {
Vector2::new(style.overall_width(),style.height)
}).on_change();
Expand Down
Loading

0 comments on commit 9db317b

Please sign in to comment.