From 81e5e77ae8afe4916e6981b9880064fbdbc81568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Czapli=C5=84ski?= Date: Wed, 19 Oct 2022 18:07:40 +0200 Subject: [PATCH] A caption when hovering the marketplace button on the left bar of Component Browser (#3783) When hovering the mouse pointer over the Marketplace button on the left bar of the Component Browser, show a caption informing that the Marketplace will be available soon. https://www.pivotaltracker.com/story/show/182613789 #### Visuals The video below demonstrates the caption shown when hovering the Marketplace button on the left bar of the Component Browser. It shows the caption disappearing after a hardcoded time, or when the mouse pointer is moved away from the button. https://user-images.githubusercontent.com/273837/196195809-45a712e1-ad86-47d8-99ff-1475a0b74c6e.mov # Important Notes - The "Label" visual component was fixed. Previously, the width calculation of the background was not synchronized correctly with the text width. As a result, a zero-width background was displayed when a Label was shown for the first time. --- Cargo.lock | 1 + .../component-list-panel/Cargo.toml | 1 + .../component-list-panel/src/navigator.rs | 48 +++++++++++++++++-- lib/rust/ensogl/component/label/src/lib.rs | 8 ++-- 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f65e36304468..5d498db5ce55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3934,6 +3934,7 @@ dependencies = [ "ensogl-selector", "ensogl-shadow", "ensogl-text", + "ensogl-tooltip", "ide-view-component-list-panel-breadcrumbs", "ide-view-component-list-panel-grid", "ordered-float", diff --git a/app/gui/view/component-browser/component-list-panel/Cargo.toml b/app/gui/view/component-browser/component-list-panel/Cargo.toml index 2d96e467ae60..a1a00531d2bd 100644 --- a/app/gui/view/component-browser/component-list-panel/Cargo.toml +++ b/app/gui/view/component-browser/component-list-panel/Cargo.toml @@ -19,6 +19,7 @@ ensogl-scroll-area = { path = "../../../../../lib/rust/ensogl/component/scroll-a ensogl-selector = { path = "../../../../../lib/rust/ensogl/component/selector" } ensogl-shadow = { path = "../../../../../lib/rust/ensogl/component/shadow" } ensogl-text = { path = "../../../../../lib/rust/ensogl/component/text" } +ensogl-tooltip = { path = "../../../../../lib/rust/ensogl/component/tooltip/" } ide-view-component-list-panel-breadcrumbs = { path = "breadcrumbs" } ide-view-component-list-panel-grid = { path = "grid" } ordered-float = "3.0.0" diff --git a/app/gui/view/component-browser/component-list-panel/src/navigator.rs b/app/gui/view/component-browser/component-list-panel/src/navigator.rs index fdf6df2a9dd5..39111a86f493 100644 --- a/app/gui/view/component-browser/component-list-panel/src/navigator.rs +++ b/app/gui/view/component-browser/component-list-panel/src/navigator.rs @@ -9,6 +9,8 @@ use ensogl_core::prelude::*; use crate::AllStyles; use enso_frp as frp; +use ensogl_core::animation::animation::delayed::DelayedAnimation; +use ensogl_core::application::tooltip; use ensogl_core::application::Application; use ensogl_core::data::color; use ensogl_core::display; @@ -17,12 +19,26 @@ use ensogl_hardcoded_theme::application::component_browser::component_list_panel use ensogl_list_view as list_view; use ensogl_list_view::entry::AnyModelProvider; use ensogl_shadow as shadow; +use ensogl_tooltip::Tooltip; use ide_view_component_list_panel_grid::entry::icon; use ide_view_component_list_panel_grid::SectionId; use list_panel_theme::navigator as theme; +// ================= +// === Constants === +// ================= + +const MARKETPLACE_TOOLTIP_TEXT: &str = "Marketplace will be available soon."; +const MARKETPLACE_TOOLTIP_HIDE_DELAY_MS: f32 = 3000.0; +const MARKETPLACE_TOOLTIP_PLACEMENT: tooltip::Placement = tooltip::Placement::Bottom; +const TOP_BUTTONS: [icon::Id; 2] = [icon::Id::Libraries, icon::Id::Marketplace]; +const MARKETPLACE_BUTTON_INDEX: usize = 1; +const BOTTOM_BUTTONS: [icon::Id; 3] = [icon::Id::SubModules, icon::Id::Star, icon::Id::LocalScope]; + + + // ============== // === Shadow === // ============== @@ -115,27 +131,25 @@ pub struct Navigator { network: frp::Network, bottom_buttons: list_view::ListView, top_buttons: list_view::ListView, + tooltip: Tooltip, pub select_section: frp::Any>, pub chosen_section: frp::Stream>, } -const TOP_BUTTONS: [icon::Id; 2] = [icon::Id::Libraries, icon::Id::Marketplace]; -const BOTTOM_BUTTONS: [icon::Id; 3] = [icon::Id::SubModules, icon::Id::Star, icon::Id::LocalScope]; - impl Navigator { pub fn new(app: &Application) -> Self { let display_object = display::object::Instance::new(); let top_buttons = app.new_view::>(); let bottom_buttons = app.new_view::>(); + let tooltip = Tooltip::new(app); top_buttons.set_style_prefix(list_panel_theme::navigator::list_view::HERE.str); bottom_buttons.set_style_prefix(list_panel_theme::navigator::list_view::HERE.str); top_buttons.show_background_shadow(false); bottom_buttons.show_background_shadow(false); - top_buttons.disable_selecting_entries_with_mouse(); bottom_buttons.disable_selecting_entries_with_mouse(); display_object.add_child(&top_buttons); display_object.add_child(&bottom_buttons); - // Top buttons are disabled until https://www.pivotaltracker.com/story/show/182613789. + app.display.default_scene.add_child(&tooltip); top_buttons.hide_selection(); top_buttons.set_entries(AnyModelProvider::new(TOP_BUTTONS.to_vec())); @@ -143,18 +157,42 @@ impl Navigator { bottom_buttons.select_entry(Some(section_id_to_list_index(SectionId::Popular))); let network = frp::Network::new("ComponentBrowser.Navigator"); + let tooltip_hide_timer = DelayedAnimation::new(&network); + tooltip_hide_timer.set_delay(MARKETPLACE_TOOLTIP_HIDE_DELAY_MS); + tooltip_hide_timer.set_duration(0.0); frp::extend! { network select_section <- any(...); bottom_buttons.select_entry <+ select_section.map(|&s:&Option| s.map(section_id_to_list_index)); chosen_section <- bottom_buttons.chosen_entry.map(|&id| id.as_ref().map(index_to_section_id)); + + + // === Show tooltip when hovering the Marketplace button + + let idx_of_marketplace_btn = |idx: &Option<_>| *idx == Some(MARKETPLACE_BUTTON_INDEX); + marketplace_button_selected <- top_buttons.selected_entry.map(idx_of_marketplace_btn); + marketplace_button_hovered <- marketplace_button_selected && top_buttons.is_mouse_over; + marketplace_button_hovered <- marketplace_button_hovered.on_change(); + tooltip_hide_timer.start <+ marketplace_button_hovered.on_true(); + tooltip_hide_timer.reset <+ marketplace_button_hovered.on_false(); + tooltip_not_hidden <- bool(&tooltip_hide_timer.on_end, &tooltip_hide_timer.on_reset); + showing_tooltip <- marketplace_button_hovered && tooltip_not_hidden; + tooltip.frp.set_style <+ showing_tooltip.map(|showing| if *showing { + let style = tooltip::Style::set_label(MARKETPLACE_TOOLTIP_TEXT.into()); + style.with_placement(MARKETPLACE_TOOLTIP_PLACEMENT) + } else { + tooltip::Style::unset_label() + } + ); } + tooltip_hide_timer.reset(); Self { display_object, top_buttons, bottom_buttons, + tooltip, network, select_section, chosen_section, diff --git a/lib/rust/ensogl/component/label/src/lib.rs b/lib/rust/ensogl/component/label/src/lib.rs index 5dca134da370..c7b0040917e0 100644 --- a/lib/rust/ensogl/component/label/src/lib.rs +++ b/lib/rust/ensogl/component/label/src/lib.rs @@ -140,9 +140,8 @@ impl Model { padded_size } - fn set_content(&self, t: &str) -> Vector2 { + fn set_content(&self, t: &str) { self.label.set_content(t); - self.set_width(self.label.width.value()) } fn set_opacity(&self, value: f32) { @@ -191,8 +190,9 @@ impl Label { let model = &self.model; frp::extend! { network - frp.source.size <+ frp.set_content.map(f!((t) - model.set_content(t) + eval frp.set_content((t) model.set_content(t)); + frp.source.size <+ model.label.width.map(f!((w) + model.set_width(*w) )); eval frp.set_opacity((value) model.set_opacity(*value));