-
Notifications
You must be signed in to change notification settings - Fork 326
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
Grid-view based dropdown component #3985
Merged
Merged
Changes from 30 commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
c0475c3
dropdown with correct scroll layers behaviour
Frizi f8d0e2a
internal dropdown entry cache and initial multiselect
Frizi d3590a4
remove bad import
Frizi 93d33ba
New dropdown FRP api and static list support
Frizi d69e822
adjust dropdown style to better match design
Frizi eb4ff64
fix deselection of dropdown values and add more cross-connected examp…
Frizi 596c8e8
add tag_values to suggestion entry and propagate it to node widgets
Frizi 796ad19
implement batch node and cleanup FRP network of dropdown
Frizi dc6bf70
isolate standalone dropdown component changeset
Frizi 4e009ca
automatic dropdown width change
Frizi b165a0e
fix format issues
Frizi 67792fa
fix clippy issues
Frizi 855f214
always calculate dropdown width based on bold text labels
Frizi 77d7eae
remove leftover debug code
Frizi a866c6d
add changelog entry
Frizi b55e9b2
handle keyboard input on empty selection
Frizi 29293d2
adjust wasm size limit
Frizi 6112ca8
adjust wasm size limit
Frizi 7738433
add missing docs and restrict unnecessarily public apis
Frizi 0a55998
remove unused type and fix cache size check
Frizi 4cf4b92
remove unused "mask" hardcoded layer
Frizi b1e33fd
fix grid view masked layer visibility
Frizi 7b99768
remove magic numbers and fix spacing
Frizi 8934290
only allow single layer parent and refactor camera inheritance
Frizi 1e76c5e
fix set_size after rebase
Frizi 9f917b7
limit code line width in dropdown frp init
Frizi d961721
fix dropdown min and max size after rebase, add more cases to demo scene
Frizi 389fc98
update according to review comments
Frizi cef13a0
keep using for_each_sublayer, remove `Group` from docs.
Frizi 4a670e8
adjust wasm size limit
Frizi 427a89c
correctly attach mask layer in complex-shape-system demo scene
Frizi ecd1fc6
move LayerFlags definition before Layer
Frizi a2ba44f
add scissor test back to complex-shape-system example
Frizi 5c56247
fix rendering of shape instance children in focus_management scene
Frizi 8178808
Update sprite parents in `ShapeInstance::swap`
Frizi 7ace2dc
Merge branch 'develop' into wip/frizi/dropdown-component-184023380
mergify[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
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
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,13 @@ | ||
[package] | ||
name = "ensogl-drop-down" | ||
version = "0.1.0" | ||
authors = ["Enso Team <[email protected]>"] | ||
edition = "2021" | ||
|
||
[dependencies] | ||
enso-frp = { path = "../../../frp" } | ||
ensogl-core = { path = "../../core" } | ||
ensogl-hardcoded-theme = { path = "../../app/theme/hardcoded" } | ||
ensogl-grid-view = { path = "../grid-view" } | ||
ensogl-text = { path = "../text" } | ||
ensogl-gui-component = { path = "../gui" } |
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,208 @@ | ||
//! A module defining the drop-down specific grid-view [`Entry`]. | ||
|
||
use ensogl_core::display::shape::*; | ||
use ensogl_grid_view::prelude::*; | ||
|
||
use ensogl_core::application::command::FrpNetworkProvider; | ||
use ensogl_core::application::frp::API; | ||
use ensogl_core::application::Application; | ||
use ensogl_core::data::color; | ||
use ensogl_core::display; | ||
use ensogl_core::display::scene::Layer; | ||
use ensogl_grid_view::entry; | ||
use ensogl_grid_view::entry::EntryFrp; | ||
use ensogl_text as text; | ||
|
||
|
||
|
||
// =================== | ||
// === EntryParams === | ||
// =================== | ||
|
||
/// The parameters of [`Dropdown`]` grid entries. | ||
#[allow(missing_docs)] | ||
#[derive(Clone, Debug)] | ||
pub struct EntryParams { | ||
pub focus_color: color::Lcha, | ||
pub font: ImString, | ||
pub text_offset: f32, | ||
pub text_size: text::Size, | ||
pub text_color: color::Lcha, | ||
pub selected_text_color: color::Lcha, | ||
pub corners_radius: f32, | ||
pub min_width: f32, | ||
pub max_width: f32, | ||
} | ||
|
||
impl Default for EntryParams { | ||
fn default() -> Self { | ||
Self { | ||
focus_color: color::Lcha::from(color::Rgba(1.0, 1.0, 1.0, 0.2)), | ||
font: text::font::DEFAULT_FONT.into(), | ||
text_offset: 7.0, | ||
text_size: text::Size(12.0), | ||
text_color: color::Lcha::from(color::Rgba(1.0, 1.0, 1.0, 0.7)), | ||
selected_text_color: color::Lcha::from(color::Rgba(1.0, 1.0, 1.0, 1.0)), | ||
corners_radius: 0.0, | ||
min_width: 40.0, | ||
max_width: 160.0, | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
// ================== | ||
// === EntryModel === | ||
// ================== | ||
|
||
/// The model of [`SimpleGridView`]`s entries. | ||
#[allow(missing_docs)] | ||
#[derive(Clone, CloneRef, Debug, Default)] | ||
pub struct EntryModel { | ||
pub text: ImString, | ||
pub selected: Immutable<bool>, | ||
} | ||
|
||
impl EntryModel { | ||
/// Create a new entry model with given text contents. | ||
pub fn new(text: ImString, selected: bool) -> Self { | ||
Self { text, selected: Immutable(selected) } | ||
} | ||
} | ||
|
||
|
||
|
||
// ============= | ||
// === Entry === | ||
// ============= | ||
|
||
// === EntryData === | ||
|
||
/// An internal structure of [`Entry`], which may be passed to FRP network. | ||
#[allow(missing_docs)] | ||
#[derive(Clone, Debug)] | ||
pub struct EntryData { | ||
display_object: display::object::Instance, | ||
label_thin: text::Text, | ||
label_bold: text::Text, | ||
} | ||
|
||
impl EntryData { | ||
fn new(app: &Application, text_layer: Option<&Layer>) -> Self { | ||
let display_object = display::object::Instance::new(); | ||
let label_thin = app.new_view::<ensogl_text::Text>(); | ||
let label_bold = app.new_view::<ensogl_text::Text>(); | ||
label_thin.set_long_text_truncation_mode(true); | ||
label_bold.set_long_text_truncation_mode(true); | ||
label_bold.set_property_default(text::Weight::Bold); | ||
display_object.add_child(&label_thin); | ||
if let Some(layer) = text_layer { | ||
label_thin.add_to_scene_layer(layer); | ||
label_bold.add_to_scene_layer(layer); | ||
} | ||
Self { display_object, label_thin, label_bold } | ||
} | ||
|
||
fn update_selected(&self, selected: bool) { | ||
if selected { | ||
self.display_object.remove_child(&self.label_thin); | ||
self.display_object.add_child(&self.label_bold); | ||
} else { | ||
self.display_object.remove_child(&self.label_bold); | ||
self.display_object.add_child(&self.label_thin); | ||
} | ||
} | ||
|
||
fn update_layout(&self, contour: entry::Contour, text_size: text::Size, text_offset: f32) { | ||
let label_pos = Vector2(text_offset - contour.size.x / 2.0, text_size.value / 2.0); | ||
self.label_thin.set_xy(label_pos); | ||
self.label_bold.set_xy(label_pos); | ||
} | ||
} | ||
|
||
|
||
// === Entry === | ||
|
||
/// A [`SimpleGridView`] entry - a label with background. | ||
#[derive(Clone, CloneRef, Debug)] | ||
pub struct Entry { | ||
frp: EntryFrp<Self>, | ||
data: Rc<EntryData>, | ||
} | ||
|
||
impl ensogl_grid_view::Entry for Entry { | ||
type Model = EntryModel; | ||
type Params = EntryParams; | ||
|
||
fn new(app: &Application, text_layer: Option<&Layer>) -> Self { | ||
let data = Rc::new(EntryData::new(app, text_layer)); | ||
let frp = EntryFrp::<Self>::new(); | ||
let input = &frp.private().input; | ||
let out = &frp.private().output; | ||
let network = frp.network(); | ||
|
||
out.hover_highlight_color.emit(color::Lcha::transparent()); | ||
|
||
enso_frp::extend! { network | ||
size <- input.set_size.on_change(); | ||
font <- input.set_params.map(|p| p.font.clone_ref()).on_change(); | ||
text_offset <- input.set_params.map(|p| p.text_offset).on_change(); | ||
focus_color <- input.set_params.map(|p| p.focus_color).on_change(); | ||
text_color <- input.set_params.map(|p| p.text_color).on_change(); | ||
text_size <- input.set_params.map(|p| p.text_size).on_change(); | ||
corners_radius <- input.set_params.map(|p| p.corners_radius).on_change(); | ||
selected_text_color <- input.set_params.map(|p| p.selected_text_color).on_change(); | ||
max_width <- input.set_params.map(|p| p.max_width).on_change(); | ||
|
||
contour <- all_with(&size, &corners_radius, |&size, &corners_radius| | ||
entry::Contour { size, corners_radius } | ||
); | ||
layout <- all(contour, text_size, text_offset); | ||
eval layout ((&(c, ts, to)) data.update_layout(c, ts, to)); | ||
selected <- input.set_model.map(|m| *m.selected); | ||
eval selected ((&s) data.update_selected(s)); | ||
|
||
text_size <- text_size.ref_into_some(); | ||
data.label_thin.set_property_default <+ text_size; | ||
data.label_bold.set_property_default <+ text_size; | ||
data.label_thin.set_property_default <+ text_color.ref_into_some(); | ||
data.label_bold.set_property_default <+ selected_text_color.ref_into_some(); | ||
data.label_thin.set_font <+ font; | ||
data.label_bold.set_font <+ font; | ||
|
||
desired_entry_width <- data.label_bold.width.map2(&text_offset, |w, offset| w + offset); | ||
limited_entry_width <- desired_entry_width.map2(&input.set_params, |width, params| { | ||
// Using min/max to avoid a panic in clamp when min_width > max_width. In those | ||
// cases, the max value is returned instead. | ||
#[allow(clippy::manual_clamp)] | ||
width.max(params.min_width).min(params.max_width) | ||
}); | ||
trace limited_entry_width; | ||
out.minimum_column_width <+ limited_entry_width; | ||
|
||
view_width <- max_width.map2(&text_offset, |width, offset| Some(width - offset)); | ||
data.label_thin.set_view_width <+ view_width; | ||
data.label_bold.set_view_width <+ view_width; | ||
|
||
content <- input.set_model.map(|m| m.text.clone_ref());; | ||
data.label_thin.set_content <+ content; | ||
data.label_bold.set_content <+ content; | ||
|
||
out.contour <+ contour; | ||
out.highlight_contour <+ contour; | ||
out.selection_highlight_color <+ focus_color; | ||
} | ||
Self { frp, data } | ||
} | ||
|
||
fn frp(&self) -> &EntryFrp<Self> { | ||
&self.frp | ||
} | ||
} | ||
|
||
impl display::Object for Entry { | ||
fn display_object(&self) -> &display::object::Instance { | ||
&self.data.display_object | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this name change? Did the logic of this layer change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looked like a mistake. Using text layer for whole grid is surprising and different from what all demo scenes do. Individual sublayers created here are guaranteeing correct draw order anyway, including the dedicated text sublayer created in the grid-view.
With this change,
node_searcher_text
is only used by the old searcher, so it could be removed with it.