-
Notifications
You must be signed in to change notification settings - Fork 326
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Component Group View with static header and without icons (#3373)
Add an initial version of the visual component for displaying the Component Group View. The component contains a header (for displaying the Group Name) and a list of labels (for displaying the component names). https://www.pivotaltracker.com/story/show/181724889 #### Visuals A screenshot from a debug scene demonstrating the component: <img width="251" alt="Screenshot 2022-04-13 at 20 07 56" src="https://user-images.githubusercontent.com/273837/163243304-21c3ad78-4813-4368-b3bb-844d979da699.png"> Screenshots from other debug scenes (`list_view` and `text_area`), demonstrating that the other components still display correctly: <img width="202" alt="Screenshot 2022-04-13 at 20 08 56" src="https://user-images.githubusercontent.com/273837/163243428-de9dc1c7-5a9f-45e0-9325-db60cece9768.png"> <img width="403" alt="Screenshot 2022-04-13 at 20 08 48" src="https://user-images.githubusercontent.com/273837/163243432-895061d9-5bd9-4349-8679-eb63b0f6724d.png"> A screenshot of the Node Searcher's list, showing that long entries in a ListView are now truncated, and an ellipsis character is added in place of removed characters: <img width="651" alt="Screenshot 2022-04-13 at 20 10 16" src="https://user-images.githubusercontent.com/273837/163243664-5b671969-7aa0-4bef-8fd2-825602d85848.png"> # Important Notes - Adding support for the text truncation feature in `ListView` required some changes in the`list_view::Entry`-related APIs. - An embedded font was added (DejaVuSans-Bold) for use in the Component Group View debug scene, and 5 unused embedded fonts were removed.
- Loading branch information
Showing
22 changed files
with
664 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "ide-view-component-browser" | ||
version = "0.1.0" | ||
authors = ["Enso Team <[email protected]>"] | ||
edition = "2021" | ||
|
||
[lib] | ||
crate-type = ["cdylib", "rlib"] | ||
|
||
[dependencies] | ||
ide-view-component-group = { path = "component-group" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[package] | ||
name = "ide-view-component-group" | ||
version = "0.1.0" | ||
authors = ["Enso Team <[email protected]>"] | ||
edition = "2021" | ||
|
||
[lib] | ||
crate-type = ["cdylib", "rlib"] | ||
|
||
[dependencies] | ||
enso-frp = { version = "0.1.0", path = "../../../../../lib/rust/frp" } | ||
ensogl-core = { version = "0.1.0", path = "../../../../../lib/rust/ensogl/core" } | ||
ensogl-gui-component = { version = "0.1.0", path = "../../../../../lib/rust/ensogl/component/gui" } | ||
ensogl-hardcoded-theme = { version = "0.1.0", path = "../../../../../lib/rust/ensogl/app/theme/hardcoded" } | ||
ensogl-list-view = { version = "0.1.0", path = "../../../../../lib/rust/ensogl/component/list-view" } | ||
ensogl-text = { version = "0.1.0", path = "../../../../../lib/rust/ensogl/component/text" } | ||
|
250 changes: 250 additions & 0 deletions
250
app/gui/view/component-browser/component-group/src/lib.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
//! This module defines a widget for displaying a list of entries of a component group and the name | ||
//! of the component group. | ||
//! | ||
//! The widget is defined by the [`View`]. | ||
//! | ||
//! To learn more about component groups, see the [Component Browser Design | ||
//! Document](https://github.com/enso-org/design/blob/e6cffec2dd6d16688164f04a4ef0d9dff998c3e7/epics/component-browser/design.md). | ||
// === Standard Linter Configuration === | ||
#![deny(non_ascii_idents)] | ||
#![warn(unsafe_code)] | ||
// === Non-Standard Linter Configuration === | ||
#![warn(missing_copy_implementations)] | ||
#![warn(missing_debug_implementations)] | ||
#![warn(missing_docs)] | ||
#![warn(trivial_casts)] | ||
#![warn(trivial_numeric_casts)] | ||
#![warn(unused_import_braces)] | ||
#![warn(unused_qualifications)] | ||
|
||
use ensogl_core::prelude::*; | ||
|
||
use enso_frp as frp; | ||
use ensogl_core::application::Application; | ||
use ensogl_core::data::color::Rgba; | ||
use ensogl_core::display; | ||
use ensogl_core::display::shape::*; | ||
use ensogl_gui_component::component; | ||
use ensogl_hardcoded_theme::application::component_browser::component_group as theme; | ||
use ensogl_list_view as list_view; | ||
use ensogl_text as text; | ||
|
||
|
||
|
||
// ================= | ||
// === Constants === | ||
// ================= | ||
|
||
const HEADER_FONT: &str = "DejaVuSans-Bold"; | ||
|
||
|
||
|
||
// ========================== | ||
// === Shapes Definitions === | ||
// ========================== | ||
|
||
|
||
// === Background === | ||
|
||
/// The background of the [`View`]. | ||
pub mod background { | ||
use super::*; | ||
|
||
ensogl_core::define_shape_system! { | ||
below = [list_view::background]; | ||
(style:Style, color:Vector4) { | ||
let sprite_width: Var<Pixels> = "input_size.x".into(); | ||
let sprite_height: Var<Pixels> = "input_size.y".into(); | ||
let color = Var::<Rgba>::from(color); | ||
// TODO[MC,WD]: We should use Plane here, but it has a bug - renders wrong color. See: | ||
// https://github.com/enso-org/enso/pull/3373#discussion_r849054476 | ||
let shape = Rect((&sprite_width, &sprite_height)).fill(color); | ||
shape.into() | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
// ======================= | ||
// === Header Geometry === | ||
// ======================= | ||
|
||
#[derive(Debug, Copy, Clone, Default)] | ||
struct HeaderGeometry { | ||
height: f32, | ||
padding_left: f32, | ||
padding_right: f32, | ||
padding_bottom: f32, | ||
} | ||
|
||
impl HeaderGeometry { | ||
fn from_style(style: &StyleWatchFrp, network: &frp::Network) -> frp::Sampler<Self> { | ||
let height = style.get_number(theme::header::height); | ||
let padding_left = style.get_number(theme::header::padding::left); | ||
let padding_right = style.get_number(theme::header::padding::right); | ||
let padding_bottom = style.get_number(theme::header::padding::bottom); | ||
|
||
frp::extend! { network | ||
init <- source_(); | ||
theme <- all_with5(&init,&height,&padding_left,&padding_right,&padding_bottom, | ||
|_,&height,&padding_left,&padding_right,&padding_bottom| | ||
Self{height,padding_left,padding_right,padding_bottom} | ||
); | ||
theme_sampler <- theme.sampler(); | ||
} | ||
init.emit(()); | ||
theme_sampler | ||
} | ||
} | ||
|
||
|
||
|
||
// =========== | ||
// === FRP === | ||
// =========== | ||
|
||
ensogl_core::define_endpoints_2! { | ||
Input { | ||
set_header(String), | ||
set_entries(list_view::entry::AnyModelProvider<list_view::entry::Label>), | ||
set_background_color(Rgba), | ||
set_size(Vector2), | ||
} | ||
Output {} | ||
} | ||
|
||
impl component::Frp<Model> for Frp { | ||
fn init(api: &Self::Private, _app: &Application, model: &Model, style: &StyleWatchFrp) { | ||
let network = &api.network; | ||
let input = &api.input; | ||
let header_text_size = style.get_number(theme::header::text::size); | ||
frp::extend! { network | ||
|
||
// === Geometry === | ||
|
||
let header_geometry = HeaderGeometry::from_style(style, network); | ||
size_and_header_geometry <- all(&input.set_size, &header_geometry); | ||
eval size_and_header_geometry(((size, hdr_geom)) model.resize(*size, *hdr_geom)); | ||
|
||
|
||
// === Header === | ||
|
||
init <- source_(); | ||
header_text_size <- all(&header_text_size, &init)._0(); | ||
model.header.set_default_text_size <+ header_text_size.map(|v| text::Size(*v)); | ||
_set_header <- input.set_header.map2(&size_and_header_geometry, f!( | ||
(text, (size, hdr_geom)) { | ||
model.header_text.replace(text.clone()); | ||
model.update_header_width(*size, *hdr_geom); | ||
}) | ||
); | ||
eval input.set_background_color((c) | ||
model.background.color.set(c.into())); | ||
|
||
|
||
// === Entries === | ||
|
||
model.entries.set_background_color(HOVER_COLOR); | ||
model.entries.show_background_shadow(false); | ||
model.entries.set_background_corners_radius(0.0); | ||
model.entries.set_background_color <+ input.set_background_color; | ||
model.entries.set_entries <+ input.set_entries; | ||
} | ||
init.emit(()); | ||
} | ||
} | ||
|
||
|
||
|
||
// ============= | ||
// === Model === | ||
// ============= | ||
|
||
/// The Model of the [`View`] component. | ||
#[derive(Clone, CloneRef, Debug)] | ||
pub struct Model { | ||
display_object: display::object::Instance, | ||
header: text::Area, | ||
header_text: Rc<RefCell<String>>, | ||
background: background::View, | ||
entries: list_view::ListView<list_view::entry::Label>, | ||
} | ||
|
||
impl display::Object for Model { | ||
fn display_object(&self) -> &display::object::Instance { | ||
&self.display_object | ||
} | ||
} | ||
|
||
impl component::Model for Model { | ||
fn label() -> &'static str { | ||
"ComponentGroup" | ||
} | ||
|
||
fn new(app: &Application, logger: &Logger) -> Self { | ||
let header_text = default(); | ||
let display_object = display::object::Instance::new(&logger); | ||
let background = background::View::new(&logger); | ||
let header = text::Area::new(app); | ||
let entries = list_view::ListView::new(app); | ||
display_object.add_child(&background); | ||
display_object.add_child(&header); | ||
display_object.add_child(&entries); | ||
|
||
header.set_font(HEADER_FONT); | ||
let label_layer = &app.display.default_scene.layers.label; | ||
header.add_to_scene_layer(label_layer); | ||
|
||
Model { display_object, header, header_text, background, entries } | ||
} | ||
} | ||
|
||
impl Model { | ||
fn resize(&self, size: Vector2, header_geometry: HeaderGeometry) { | ||
// === Background === | ||
|
||
self.background.size.set(size); | ||
|
||
|
||
// === Header Text === | ||
|
||
let header_padding_left = header_geometry.padding_left; | ||
let header_text_x = -size.x / 2.0 + header_padding_left; | ||
let header_text_height = self.header.height.value(); | ||
let header_padding_bottom = header_geometry.padding_bottom; | ||
let header_height = header_geometry.height; | ||
let header_bottom_y = size.y / 2.0 - header_height; | ||
let header_text_y = header_bottom_y + header_text_height + header_padding_bottom; | ||
self.header.set_position_xy(Vector2(header_text_x, header_text_y)); | ||
self.update_header_width(size, header_geometry); | ||
|
||
|
||
// === Entries === | ||
|
||
self.entries.resize(size - Vector2(0.0, header_height)); | ||
self.entries.set_position_y(-header_height / 2.0); | ||
} | ||
|
||
fn update_header_width(&self, size: Vector2, header_geometry: HeaderGeometry) { | ||
let header_padding_left = header_geometry.padding_left; | ||
let header_padding_right = header_geometry.padding_right; | ||
let max_text_width = size.x - header_padding_left - header_padding_right; | ||
self.header.set_content_truncated(self.header_text.borrow().clone(), max_text_width); | ||
} | ||
} | ||
|
||
|
||
|
||
// ============ | ||
// === View === | ||
// ============ | ||
|
||
/// A widget for displaying the entries and name of a component group. | ||
/// | ||
/// The widget is rendered as a header label, a list of entries below it, and a colored background. | ||
/// | ||
/// To learn more about component groups, see the [Component Browser Design | ||
/// Document](https://github.com/enso-org/design/blob/e6cffec2dd6d16688164f04a4ef0d9dff998c3e7/epics/component-browser/design.md). | ||
pub type View = component::ComponentView<Model, Frp>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// === Standard Linter Configuration === | ||
#![deny(non_ascii_idents)] | ||
#![warn(unsafe_code)] | ||
// === Non-Standard Linter Configuration === | ||
#![warn(missing_copy_implementations)] | ||
#![warn(missing_debug_implementations)] | ||
#![warn(missing_docs)] | ||
#![warn(trivial_casts)] | ||
#![warn(trivial_numeric_casts)] | ||
#![warn(unused_import_braces)] | ||
#![warn(unused_qualifications)] | ||
|
||
|
||
// ============== | ||
// === Export === | ||
// ============== | ||
|
||
pub use ide_view_component_group as component_group; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[package] | ||
name = "debug-scene-component-group" | ||
version = "0.1.0" | ||
authors = ["Enso Team <[email protected]>"] | ||
edition = "2021" | ||
|
||
[lib] | ||
crate-type = ["cdylib", "rlib"] | ||
|
||
[dependencies] | ||
enso-frp = { path = "../../../../../lib/rust/frp" } | ||
ensogl-core = { path = "../../../../../lib/rust/ensogl/core" } | ||
ensogl-hardcoded-theme = { path = "../../../../../lib/rust/ensogl/app/theme/hardcoded" } | ||
ensogl-list-view = { path = "../../../../../lib/rust/ensogl/component/list-view" } | ||
ensogl-text-msdf-sys = { path = "../../../../../lib/rust/ensogl/component/text/msdf-sys" } | ||
ide-view-component-group = { path = "../../component-browser/component-group" } | ||
wasm-bindgen = { version = "0.2.78", features = ["nightly"] } |
Oops, something went wrong.