From 610b128bfadde1069100d3219f84c627e06d9719 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Wed, 24 Aug 2022 21:00:31 +0200 Subject: [PATCH 1/2] Component Panel List Layout structure. (#3662) This PR does not add anything visual for the user: it's a first part of making efficient Component Browser using fresh Grid View implementation. The Layout is an intermediate model, which keeps the information how the groups are laid out in the Component browser, and allows querying for group entry by location and location of specific group entry (or header). The layout is meant for the new design, where there are no section separators and Local Scope section is below Favorites. # Important Notes The new structure is not used in action, but tested with unit tests. --- Cargo.lock | 1 + .../searcher-list-panel/Cargo.toml | 1 + .../searcher-list-panel/src/column_grid.rs | 11 +- .../searcher-list-panel/src/layout.rs | 342 ++++++++++++++++++ .../searcher-list-panel/src/layouting.rs | 107 +++--- .../searcher-list-panel/src/lib.rs | 18 +- 6 files changed, 425 insertions(+), 55 deletions(-) create mode 100644 app/gui/view/component-browser/searcher-list-panel/src/layout.rs diff --git a/Cargo.lock b/Cargo.lock index 06eec75f50ac7..64588cf244f6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3885,6 +3885,7 @@ dependencies = [ "enso-frp", "ensogl-core", "ensogl-derive-theme", + "ensogl-grid-view", "ensogl-gui-component", "ensogl-hardcoded-theme", "ensogl-list-view", diff --git a/app/gui/view/component-browser/searcher-list-panel/Cargo.toml b/app/gui/view/component-browser/searcher-list-panel/Cargo.toml index d3d2465638ac3..504d2635edcdf 100644 --- a/app/gui/view/component-browser/searcher-list-panel/Cargo.toml +++ b/app/gui/view/component-browser/searcher-list-panel/Cargo.toml @@ -11,6 +11,7 @@ crate-type = ["cdylib", "rlib"] enso-frp = { path = "../../../../../lib/rust/frp" } ensogl-core = { path = "../../../../../lib/rust/ensogl/core" } ensogl-gui-component = { path = "../../../../../lib/rust/ensogl/component/gui/" } +ensogl-grid-view = { path = "../../../../../lib/rust/ensogl/component/grid-view/" } ensogl-hardcoded-theme = { path = "../../../../../lib/rust/ensogl/app/theme/hardcoded" } ensogl-derive-theme = { path = "../../../../../lib/rust/ensogl/app/theme/derive" } ensogl-list-view = { path = "../../../../../lib/rust/ensogl/component/list-view" } diff --git a/app/gui/view/component-browser/searcher-list-panel/src/column_grid.rs b/app/gui/view/component-browser/searcher-list-panel/src/column_grid.rs index 704fc5fda0821..38f874f78c7c8 100644 --- a/app/gui/view/component-browser/searcher-list-panel/src/column_grid.rs +++ b/app/gui/view/component-browser/searcher-list-panel/src/column_grid.rs @@ -5,6 +5,7 @@ use ensogl_core::display::shape::*; use ensogl_core::prelude::*; +use crate::layout; use crate::layouting; use crate::searcher_theme; use crate::GroupId; @@ -87,9 +88,10 @@ impl Model { let overall_width = style.content_width - 2.0 * style.content_padding; let column_width = (overall_width - 2.0 * style.column_gap) / NUMBER_OF_COLUMNS as f32; - let groups = content.iter().enumerate().map(|(index, provider)| { - let height = provider.original_entry_count; - layouting::Group { index, height } + let groups = content.iter().enumerate().map(|(index, provider)| layout::Group { + id: GroupId { section: *section, index }, + height: provider.content.entry_count(), + original_height: provider.original_entry_count, }); let arrangement = layouting::Layouter::new(groups).arrange(); @@ -127,7 +129,8 @@ impl Model { for entry in content.iter() { const DEFAULT_COLUMN_INDEX: usize = 1; let mut arranged = arrangement.iter().enumerate(); - let column_index = arranged.find_map(|(i, c)| c.contains(&entry.index).then_some(i)); + let column_index = + arranged.find_map(|(i, c)| c.iter().find(|g| g.id.index == entry.index).map(|_| i)); let column_index = column_index.unwrap_or(DEFAULT_COLUMN_INDEX); columns[column_index].push(&entry.content); heights[column_index] += entry.content.size.value().y + style.column_gap; diff --git a/app/gui/view/component-browser/searcher-list-panel/src/layout.rs b/app/gui/view/component-browser/searcher-list-panel/src/layout.rs new file mode 100644 index 0000000000000..1e462877522b6 --- /dev/null +++ b/app/gui/view/component-browser/searcher-list-panel/src/layout.rs @@ -0,0 +1,342 @@ +//! A module with description how the list of Component Groups is laid out in the Component Panel +//! List. + +use crate::prelude::*; + +use ensogl_grid_view::Col; +use ensogl_grid_view::Row; +use ide_view_component_group::set::GroupId; +use ide_view_component_group::set::SectionId; + + + +// ================= +// === Constants === +// ================= + +/// Height of the header of the component group. This value is added to the group's number of +/// entries to get the total height. +pub const HEADER_HEIGHT_IN_ROWS: usize = 1; + + + +// ================= +// === ElementId === +// ================= + +/// An identifier of element inside a concrete group: entry (by entry index) or header. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum GroupElement { + /// A group's header. + Header, + /// A group's normal entry with index. + Entry(usize), +} + +/// An identifier of some group's element in Component Browser. +#[allow(missing_docs)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct ElementId { + pub group: GroupId, + pub element: GroupElement, +} + + + +// ============= +// === Group === +// ============= + +/// A information about group needed to compute the Component Panel List layout. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct Group { + /// The group identifier. + pub id: GroupId, + /// Height of group in rows, not counting the header nor filtered-out entries. + pub height: usize, + /// Height of group in rows if no entry is filtered out, not counting the header. + pub original_height: usize, +} + + +// === LaidGroup === + +/// The information of group in the layout. +#[derive(Copy, Clone, Debug)] +pub struct LaidGroup<'a> { + /// The row where header is placed. + pub header_row: Row, + /// The column where the group is placed. + pub column: Col, + /// The reference to the group information in [`Layout`] structure. + pub group: &'a Group, +} + +impl<'a> LaidGroup<'a> { + /// The range of rows where the group spans, _including_ the header. + pub fn rows(&self) -> Range { + self.header_row..(self.header_row + self.group.height + HEADER_HEIGHT_IN_ROWS) + } + + /// The id of element at given row, or `None` if row is outside the group. + pub fn element_at_row(&self, row: Row) -> Option { + let element = self.rows().contains(&row).as_some_from(|| { + if row < self.header_row + HEADER_HEIGHT_IN_ROWS { + GroupElement::Header + } else { + GroupElement::Entry(row - self.header_row - HEADER_HEIGHT_IN_ROWS) + } + }); + element.map(|element| ElementId { group: self.group.id, element }) + } +} + + + +// ============== +// === Layout === +// ============== + +/// The info about single column in [`Layout`]. +#[derive(Clone, Debug)] +struct Column { + /// A mapping between group position and the [`Group`] info. The keys in map are the rows with + /// given group's header. + groups: BTreeMap, + /// The top occupied row in this group. If there is no group in column, it contains the first + /// row of "Local scope" section. If the "Local scope" section is also empty, it's an index + /// of row after last row in grid. + top_row: Row, +} + +/// The Component List Panel Layout information. +/// +/// This structure allows for organizing the component groups according to received group +/// information about their heights. It provides information about where given group is laid out +/// in Grid View, and what group element is at given location (row and column). +#[derive(Clone, Debug)] +pub struct Layout { + columns: Vec, + positions: HashMap, + local_scope_section_start: Row, + local_scope_entry_count: usize, + row_count: Row, +} + +impl Layout { + /// Create layout without standard (not the "Local Scope") groups. + /// + /// The layout will be completely empty if `local_scope_entry_count` will be 0. + pub fn new(row_count: Row, column_count: Col, local_scope_entry_count: usize) -> Self { + let local_scope_rows = local_scope_entry_count.div_ceil(column_count); + let local_scope_section_start = row_count - local_scope_rows; + let columns = + iter::repeat_with(|| Column { groups: default(), top_row: local_scope_section_start }) + .take(column_count) + .collect_vec(); + let positions = default(); + Self { columns, positions, local_scope_section_start, local_scope_entry_count, row_count } + } + + /// Create the layout with given groups arranged in columns. + pub fn create_from_arranged_groups( + groups: [Vec; COLUMN_COUNT], + local_scope_entry_count: usize, + ) -> Self { + let local_scope_rows = local_scope_entry_count.div_ceil(COLUMN_COUNT); + let col_heights: [usize; COLUMN_COUNT] = groups + .each_ref() + .map(|v| v.iter().map(|g| g.original_height + HEADER_HEIGHT_IN_ROWS).sum()); + let groups_rows = col_heights.into_iter().max().unwrap_or_default(); + let all_rows = local_scope_rows + groups_rows; + let mut this = Self::new(all_rows, COLUMN_COUNT, local_scope_entry_count); + let with_col_index = groups.into_iter().enumerate().map(Self::column_to_col_group_pairs); + for (column, group) in with_col_index.flatten() { + this.push_group(column, group); + } + this + } + + fn column_to_col_group_pairs( + (index, column): (Col, Vec), + ) -> impl Iterator { + column.into_iter().map(move |group| (index, group)) + } + + /// Get the information about group other than "Local Scope" occupying given location. + /// + /// If there is no group there, or it's "Local Scope" section, `None` is returned. + pub fn group_at_location(&self, row: Row, column: Col) -> Option { + let groups_in_col = &self.columns.get(column)?.groups; + let (group_before_row, group_before) = groups_in_col.range(..=row).last()?; + let group_end = group_before_row + group_before.height + HEADER_HEIGHT_IN_ROWS; + (group_end > row).as_some_from(|| LaidGroup { + header_row: *group_before_row, + column, + group: group_before, + }) + } + + /// Get the information what element is at given location. + pub fn element_at_location(&self, row: Row, column: Col) -> Option { + if row >= self.local_scope_section_start { + let index = (row - self.local_scope_section_start) * self.columns.len() + column; + (index < self.local_scope_entry_count).as_some_from(|| ElementId { + group: GroupId::local_scope_group(), + element: GroupElement::Entry(index), + }) + } else { + let group = self.group_at_location(row, column)?; + group.element_at_row(row) + } + } + + /// Return the location of element in Grid View. + pub fn location_of_element(&self, element: ElementId) -> Option<(Row, Col)> { + if element.group.section == SectionId::LocalScope { + match element.element { + GroupElement::Header => None, + GroupElement::Entry(index) => { + let row = self.local_scope_section_start + index / self.columns.len(); + let col = index % self.columns.len(); + Some((row, col)) + } + } + } else { + let &(header_pos, col) = self.positions.get(&element.group)?; + match element.element { + GroupElement::Header => Some((header_pos, col)), + GroupElement::Entry(index) => + Some((header_pos + HEADER_HEIGHT_IN_ROWS + index, col)), + } + } + } + + /// Add group to the top of given column. + pub fn push_group(&mut self, column: Col, group: Group) -> Row { + let group_column = &mut self.columns[column]; + let next_header_row = group_column.top_row - group.height - HEADER_HEIGHT_IN_ROWS; + group_column.groups.insert(next_header_row, group); + group_column.top_row = next_header_row; + self.positions.insert(group.id, (next_header_row, column)); + next_header_row + } + + /// The topmost row containing any group. + pub fn top_row(&self) -> Row { + self.columns.iter().map(|column| column.top_row).min().unwrap_or(self.row_count) + } + + /// The topmost row containing any group in given column. + pub fn column_top_row(&self, column: Col) -> Row { + self.columns.get(column).map_or(self.row_count, |c| c.top_row) + } +} + + + +// ============= +// === Tests === +// ============= + +#[cfg(test)] +mod tests { + use super::*; + use ide_view_component_group::set::SectionId; + + const LEFT: usize = 0; + const CENTER: usize = 1; + const RIGHT: usize = 2; + + #[test] + fn group_layout() { + let group_ids = + (0..6).map(|index| GroupId { section: SectionId::Favorites, index }).collect_vec(); + let group_sizes = vec![2, 1, 3, 3, 2, 1]; + let group_data = group_ids.iter().zip(group_sizes.into_iter()); + let mk_group = |(id, size): (&GroupId, usize)| Group { + id: *id, + height: size, + original_height: size, + }; + let groups = group_data.map(mk_group).collect_vec(); + let groups_in_columns = + [vec![groups[1], groups[4]], vec![groups[0], groups[3]], vec![groups[2], groups[5]]]; + let layout = Layout::create_from_arranged_groups(groups_in_columns, 8); + + let header_of = + |group_idx| ElementId { group: group_ids[group_idx], element: GroupElement::Header }; + let entry_of = |group_idx, entry_idx| ElementId { + group: group_ids[group_idx], + element: GroupElement::Entry(entry_idx), + }; + let local_scope_entry = |entry_idx| ElementId { + group: GroupId::local_scope_group(), + element: GroupElement::Entry(entry_idx), + }; + + assert_eq!(layout.element_at_location(0, LEFT), None); + assert_eq!(layout.element_at_location(0, CENTER), Some(header_of(3))); + assert_eq!(layout.element_at_location(0, RIGHT), None); + assert_eq!(layout.element_at_location(1, LEFT), None); + assert_eq!(layout.element_at_location(1, CENTER), Some(entry_of(3, 0))); + assert_eq!(layout.element_at_location(1, RIGHT), Some(header_of(5))); + assert_eq!(layout.element_at_location(2, LEFT), Some(header_of(4))); + assert_eq!(layout.element_at_location(2, CENTER), Some(entry_of(3, 1))); + assert_eq!(layout.element_at_location(2, RIGHT), Some(entry_of(5, 0))); + assert_eq!(layout.element_at_location(5, LEFT), Some(header_of(1))); + assert_eq!(layout.element_at_location(5, CENTER), Some(entry_of(0, 0))); + assert_eq!(layout.element_at_location(5, RIGHT), Some(entry_of(2, 1))); + assert_eq!(layout.element_at_location(6, LEFT), Some(entry_of(1, 0))); + assert_eq!(layout.element_at_location(6, CENTER), Some(entry_of(0, 1))); + assert_eq!(layout.element_at_location(6, RIGHT), Some(entry_of(2, 2))); + assert_eq!(layout.element_at_location(7, LEFT), Some(local_scope_entry(0))); + assert_eq!(layout.element_at_location(7, CENTER), Some(local_scope_entry(1))); + assert_eq!(layout.element_at_location(7, RIGHT), Some(local_scope_entry(2))); + assert_eq!(layout.element_at_location(9, LEFT), Some(local_scope_entry(6))); + assert_eq!(layout.element_at_location(9, CENTER), Some(local_scope_entry(7))); + assert_eq!(layout.element_at_location(9, RIGHT), None); + + assert_eq!(layout.location_of_element(header_of(3)), Some((0, CENTER))); + assert_eq!(layout.location_of_element(entry_of(3, 0)), Some((1, CENTER))); + assert_eq!(layout.location_of_element(header_of(5)), Some((1, RIGHT))); + assert_eq!(layout.location_of_element(header_of(4)), Some((2, LEFT))); + assert_eq!(layout.location_of_element(entry_of(3, 1)), Some((2, CENTER))); + assert_eq!(layout.location_of_element(entry_of(5, 0)), Some((2, RIGHT))); + assert_eq!(layout.location_of_element(header_of(1)), Some((5, LEFT))); + assert_eq!(layout.location_of_element(entry_of(0, 0)), Some((5, CENTER))); + assert_eq!(layout.location_of_element(entry_of(2, 1)), Some((5, RIGHT))); + assert_eq!(layout.location_of_element(entry_of(1, 0)), Some((6, LEFT))); + assert_eq!(layout.location_of_element(entry_of(0, 1)), Some((6, CENTER))); + assert_eq!(layout.location_of_element(entry_of(2, 2)), Some((6, RIGHT))); + assert_eq!(layout.location_of_element(local_scope_entry(0)), Some((7, LEFT))); + assert_eq!(layout.location_of_element(local_scope_entry(1)), Some((7, CENTER))); + assert_eq!(layout.location_of_element(local_scope_entry(2)), Some((7, RIGHT))); + assert_eq!(layout.location_of_element(local_scope_entry(6)), Some((9, LEFT))); + assert_eq!(layout.location_of_element(local_scope_entry(7)), Some((9, CENTER))); + } + + #[test] + fn group_layouts_with_empty_column_and_local_scope() { + let mut layout = Layout::new(3, 3, 0); + let group = Group { + id: GroupId { section: SectionId::Favorites, index: 0 }, + height: 2, + original_height: 2, + }; + layout.push_group(CENTER, group); + + assert_eq!(layout.element_at_location(2, LEFT), None); + assert_eq!( + layout.element_at_location(2, CENTER), + Some(ElementId { + group: GroupId { section: SectionId::Favorites, index: 0 }, + element: GroupElement::Entry(1), + }) + ); + assert_eq!(layout.element_at_location(2, RIGHT), None); + assert_eq!(layout.element_at_location(3, LEFT), None); + assert_eq!(layout.element_at_location(3, CENTER), None); + assert_eq!(layout.element_at_location(3, RIGHT), None); + } +} diff --git a/app/gui/view/component-browser/searcher-list-panel/src/layouting.rs b/app/gui/view/component-browser/searcher-list-panel/src/layouting.rs index 81369406df726..038ee055d6515 100644 --- a/app/gui/view/component-browser/searcher-list-panel/src/layouting.rs +++ b/app/gui/view/component-browser/searcher-list-panel/src/layouting.rs @@ -5,6 +5,12 @@ use ensogl_core::prelude::*; +use crate::layout::Group; +use crate::layout::Layout; +use crate::layout::HEADER_HEIGHT_IN_ROWS; + +use ensogl_grid_view::Col; + // ================= @@ -17,26 +23,15 @@ const COLUMNS: usize = 3; const LEFT: usize = 0; const CENTER: usize = 1; const RIGHT: usize = 2; -/// Height of the header of the component group. This value is added to the group's number of -/// entries to get the total height. -const HEADER_HEIGHT: GroupHeight = 1; -type Column = usize; -// ============= -// === Group === -// ============= +// =============== +// === Aliases === +// =============== -type GroupIndex = usize; type GroupHeight = usize; -#[derive(Clone, Copy, Debug)] -pub struct Group { - pub index: GroupIndex, - pub height: GroupHeight, -} - // ================ @@ -58,8 +53,8 @@ pub struct Group { /// /// [design doc]: https://github.com/enso-org/design/blob/main/epics/component-browser/design.md#layouting-algorithm pub struct Layouter> { - columns: [Vec; COLUMNS], - groups_heights: [GroupHeight; COLUMNS], + columns: [Vec; COLUMNS], + column_heights: [GroupHeight; COLUMNS], iter: iter::Peekable, } @@ -68,13 +63,13 @@ impl> Layouter { pub fn new(iter: I) -> Self { Self { columns: default(), - groups_heights: default(), + column_heights: default(), iter: iter.peekable(), } } - /// Calculate the layouting of the groups. See struct documentation for more information. - pub fn arrange(mut self) -> [Vec; COLUMNS] { + /// Calculate the layout of the groups. See struct documentation for more information. + pub fn arrange(mut self) -> [Vec; COLUMNS] { let mut max_height = self.push_next_group_to(CENTER, None); while self.iter.peek().is_some() { self.push_next_group_to(LEFT, Some(max_height)); @@ -89,17 +84,21 @@ impl> Layouter { self.columns } + /// Calculate the layout of the groups, and return it as a [`Layout`] structure. + /// + /// See struct documentation for more information. + pub fn create_layout(self, local_scope_entry_count: usize) -> Layout { + let arranged_groups = self.arrange(); + Layout::create_from_arranged_groups(arranged_groups, local_scope_entry_count) + } + /// Push the next group to the given column. Returns the size of the added group, 0 if no group /// was added. If [`max_height`] is supplied, the group is pushed only if the column's height /// is less than [`max_height`] before adding new group. - fn push_next_group_to( - &mut self, - column: Column, - max_height: Option, - ) -> GroupHeight { + fn push_next_group_to(&mut self, column: Col, max_height: Option) -> GroupHeight { if let Some(group) = self.iter.next() { if let Some(max_height) = max_height { - if self.groups_heights[column] >= max_height { + if self.column_heights[column] >= max_height { return 0; } } @@ -110,8 +109,8 @@ impl> Layouter { } /// Fill the given column until it reaches the given height. - fn fill_till_height(&mut self, column: Column, max_height: GroupHeight) { - while self.groups_heights[column] < max_height { + fn fill_till_height(&mut self, column: Col, max_height: GroupHeight) { + while self.column_heights[column] < max_height { if let Some(group) = self.iter.next() { self.push(column, group); } else { @@ -122,10 +121,10 @@ impl> Layouter { /// Push a a group to the given column. Returns a height of the added group. (including the /// [`HEADER_HEIGHT`]) - fn push(&mut self, column: Column, group: Group) -> GroupHeight { - self.columns[column].push(group.index); - let group_height = group.height + HEADER_HEIGHT; - self.groups_heights[column] += group_height; + fn push(&mut self, column: Col, group: Group) -> GroupHeight { + self.columns[column].push(group); + let group_height = group.original_height + HEADER_HEIGHT_IN_ROWS; + self.column_heights[column] += group_height; group_height } } @@ -139,37 +138,61 @@ impl> Layouter { #[cfg(test)] mod tests { use super::*; + use ide_view_component_group::set::GroupId; + use ide_view_component_group::set::SectionId; /// Test that the algorithm doesn't panic even with a small count of component groups. #[test] fn test_small_count_of_groups() { for count in 0..4 { - let groups = (0..count).map(|index| Group { index, height: 1 }); + let group_ids = + (0..count).map(|index| GroupId { section: SectionId::Favorites, index }); + let groups = group_ids.map(|id| Group { id, height: 1, original_height: 1 }); let arranged = Layouter::new(groups).arrange(); let total_count = arranged[LEFT].len() + arranged[CENTER].len() + arranged[RIGHT].len(); assert_eq!(total_count, count); } } + fn make_groups(index_height_pairs: Vec<(usize, usize)>) -> impl Iterator { + index_height_pairs.into_iter().map(|(index, height)| Group { + id: GroupId { section: SectionId::Favorites, index }, + height, + original_height: height, + }) + } + + fn check_groups_indices(result: [Vec; COLUMNS], expected: [Vec; COLUMNS]) { + let result_ids = result.map(|groups| groups.into_iter().map(|g| g.id.index).collect_vec()); + assert_eq!(result_ids, expected); + } + /// See [design doc](https://github.com/enso-org/design/blob/main/epics/component-browser/design.md#layouting-algorithm). #[test] fn test_case_from_design_doc() { - let groups: Vec<(usize, usize)> = - vec![(1, 4), (2, 4), (3, 3), (4, 3), (5, 2), (6, 3), (7, 2)]; - let groups = groups.into_iter().map(|(index, size)| Group { index, height: size }); + let groups = make_groups(vec![(1, 4), (2, 4), (3, 3), (4, 3), (5, 2), (6, 3), (7, 2)]); let arranged = Layouter::new(groups).arrange(); - let expected: &[Vec] = &[vec![2, 6], vec![1, 4], vec![3, 5, 7]]; - assert_eq!(&arranged, expected); + let expected = [vec![2, 6], vec![1, 4], vec![3, 5, 7]]; + check_groups_indices(arranged, expected); } /// See [task #181431035](https://www.pivotaltracker.com/story/show/181431035). #[test] fn test_case_from_acceptance_criteria() { - let groups: Vec<(usize, usize)> = - vec![(1, 3), (2, 1), (3, 3), (4, 4), (5, 1), (6, 1), (7, 4), (8, 1), (9, 2), (10, 1)]; - let groups = groups.into_iter().map(|(index, size)| Group { index, height: size }); + let groups = make_groups(vec![ + (1, 3), + (2, 1), + (3, 3), + (4, 4), + (5, 1), + (6, 1), + (7, 4), + (8, 1), + (9, 2), + (10, 1), + ]); let arranged = Layouter::new(groups).arrange(); - let expected: &[Vec] = &[vec![2, 5, 6, 9, 10], vec![1, 4, 8], vec![3, 7]]; - assert_eq!(&arranged, expected); + let expected = [vec![2, 5, 6, 9, 10], vec![1, 4, 8], vec![3, 7]]; + check_groups_indices(arranged, expected); } } diff --git a/app/gui/view/component-browser/searcher-list-panel/src/lib.rs b/app/gui/view/component-browser/searcher-list-panel/src/lib.rs index 2c6604f92f23a..4b33afac32d0a 100644 --- a/app/gui/view/component-browser/searcher-list-panel/src/lib.rs +++ b/app/gui/view/component-browser/searcher-list-panel/src/lib.rs @@ -26,6 +26,8 @@ #![feature(derive_default_enum)] #![feature(slice_as_chunks)] #![feature(option_result_contains)] +#![feature(int_roundings)] +#![feature(array_methods)] // === Standard Linter Configuration === #![deny(non_ascii_idents)] #![warn(unsafe_code)] @@ -42,20 +44,13 @@ #![warn(unused_import_braces)] #![warn(unused_qualifications)] - - -// ============== -// === Export === -// ============== - -mod navigator; - +use crate::prelude::*; use ensogl_core::display::shape::*; -use ensogl_core::prelude::*; use crate::navigator::navigator_shadow; use crate::navigator::Navigator as SectionNavigator; use crate::navigator::Section; + use component_group::icon; use enso_frp as frp; use ensogl_core::animation::physics::inertia; @@ -92,11 +87,16 @@ use searcher_theme::list_panel as list_panel_theme; // ============== pub mod column_grid; +pub mod layout; + + mod layouting; +mod navigator; pub use column_grid::LabeledAnyModelProvider; pub use component_group::set::GroupId; +pub use ensogl_core::prelude; From 4537a4b57b93c7ef88d6de2f5443693deaaafefe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Wawrzyniec=20Urba=C5=84czyk?= Date: Thu, 25 Aug 2022 00:46:36 +0200 Subject: [PATCH 2/2] Adjusting CI / build configuration. (#3664) * Downgrading the electron-builder to avoid https://github.com/electron-userland/electron-builder/issues/6865 * Removed "git clean" workaround from CI. --- .github/workflows/benchmark.yml | 2 +- .github/workflows/gui.yml | 28 ++++++++++++------------- .github/workflows/nightly.yml | 18 ++++++++-------- .github/workflows/scala-new.yml | 6 +++--- Cargo.lock | 10 ++++----- app/ide-desktop/lib/client/package.json | 2 +- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 59bf15cdbdb24..ad479adbdfe2e 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -45,7 +45,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: diff --git a/.github/workflows/gui.yml b/.github/workflows/gui.yml index 3518af57105a6..6e4a70891eb0a 100644 --- a/.github/workflows/gui.yml +++ b/.github/workflows/gui.yml @@ -25,7 +25,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - id: changed_files run: "git fetch\nlist=`git diff --name-only origin/develop HEAD | tr '\\n' ' '`\necho $list\necho \"::set-output name=list::'$list'\"" - run: "if [[ ${{ contains(steps.changed_files.outputs.list,'CHANGELOG.md') || contains(github.event.head_commit.message,'[ci no changelog needed]') || contains(github.event.pull_request.body,'[ci no changelog needed]') || github.event.pull_request.user.login == 'dependabot' }} == false ]]; then exit 1; fi" @@ -63,7 +63,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -108,7 +108,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -155,7 +155,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -202,7 +202,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -247,7 +247,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -294,7 +294,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -352,7 +352,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -399,7 +399,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -446,7 +446,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -496,7 +496,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -544,7 +544,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -594,7 +594,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -643,7 +643,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index a072f0d4e7de4..4f6e2bf268012 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -38,7 +38,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -83,7 +83,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -132,7 +132,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -182,7 +182,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -234,7 +234,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -289,7 +289,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -346,7 +346,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -398,7 +398,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -452,7 +452,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: diff --git a/.github/workflows/scala-new.yml b/.github/workflows/scala-new.yml index f0c04cd8ec52e..e824ddf5d2309 100644 --- a/.github/workflows/scala-new.yml +++ b/.github/workflows/scala-new.yml @@ -49,7 +49,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -102,7 +102,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: @@ -157,7 +157,7 @@ jobs: - name: Checking out the repository uses: actions/checkout@v2 with: - clean: true + clean: false - name: Build Script Setup run: "./run --help" env: diff --git a/Cargo.lock b/Cargo.lock index 64588cf244f6a..5130f54c39abb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1751,7 +1751,7 @@ dependencies = [ [[package]] name = "enso-build" version = "0.1.0" -source = "git+https://github.com/enso-org/ci-build?branch=develop#2b998bd5021c387ad50e99f087b7605ddecfbcc0" +source = "git+https://github.com/enso-org/ci-build?branch=develop#621679899f67018ca50813975e59218abd75f81c" dependencies = [ "anyhow", "async-compression", @@ -1825,7 +1825,7 @@ dependencies = [ [[package]] name = "enso-build-cli" version = "0.1.0" -source = "git+https://github.com/enso-org/ci-build?branch=develop#2b998bd5021c387ad50e99f087b7605ddecfbcc0" +source = "git+https://github.com/enso-org/ci-build?branch=develop#621679899f67018ca50813975e59218abd75f81c" dependencies = [ "anyhow", "byte-unit", @@ -3724,10 +3724,10 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5617e92fc2f2501c3e2bc6ce547cad841adba2bae5b921c7e52510beca6d084c" dependencies = [ - "base64 0.10.1", + "base64 0.11.0", "bytes 1.1.0", "http", - "httpdate 0.3.2", + "httpdate 1.0.2", "language-tags 0.3.2", "mime 0.3.16", "percent-encoding 2.1.0", @@ -3737,7 +3737,7 @@ dependencies = [ [[package]] name = "ide-ci" version = "0.1.0" -source = "git+https://github.com/enso-org/ci-build?branch=develop#2b998bd5021c387ad50e99f087b7605ddecfbcc0" +source = "git+https://github.com/enso-org/ci-build?branch=develop#621679899f67018ca50813975e59218abd75f81c" dependencies = [ "anyhow", "async-compression", diff --git a/app/ide-desktop/lib/client/package.json b/app/ide-desktop/lib/client/package.json index 4bc6f0ef1a4bf..d61a23e63ccbb 100644 --- a/app/ide-desktop/lib/client/package.json +++ b/app/ide-desktop/lib/client/package.json @@ -26,7 +26,7 @@ }, "devDependencies": { "electron": "17.1.0", - "electron-builder": "^23.3.1", + "electron-builder": "^22.14.13", "esbuild": "^0.14.43", "crypto-js": "4.1.1", "electron-notarize": "1.2.1",