diff --git a/editor/src/animation/toolbar.rs b/editor/src/animation/toolbar.rs index 9df3e1e2d..3620310a5 100644 --- a/editor/src/animation/toolbar.rs +++ b/editor/src/animation/toolbar.rs @@ -860,7 +860,7 @@ impl Toolbar { .node(self.animations) .query_component::() .unwrap() - .items()[*index]; + .items[*index]; let animation = ui .node(item) .user_data_cloned::>>>() diff --git a/editor/src/inspector/editors/script.rs b/editor/src/inspector/editors/script.rs index 2ffe5d1c9..52d6e83ee 100644 --- a/editor/src/inspector/editors/script.rs +++ b/editor/src/inspector/editors/script.rs @@ -117,7 +117,7 @@ impl Control for ScriptPropertyEditor { .node(self.variant_selector) .cast::() .expect("Must be DropdownList") - .items() + .items .iter() .map(|el| { ui.node(*el) @@ -181,7 +181,7 @@ impl Control for ScriptPropertyEditor { .node(self.variant_selector) .cast::() .expect("Must be DropdownList") - .items()[*i]; + .items[*i]; let new_selected_script_data = ui .node(selected_item) @@ -423,7 +423,7 @@ impl PropertyEditorDefinition for ScriptPropertyEditorDefinition { .expect("Must be a DropDownList"); // Script list might change over time if some plugins were reloaded. - if variant_selector_ref.items().len() + if variant_selector_ref.items.len() != editor_environment .serialization_context .script_constructors diff --git a/fyrox-ui/src/dropdown_list.rs b/fyrox-ui/src/dropdown_list.rs index 6df134eab..3c476db42 100644 --- a/fyrox-ui/src/dropdown_list.rs +++ b/fyrox-ui/src/dropdown_list.rs @@ -1,5 +1,8 @@ //! Drop-down list. This is control which shows currently selected item and provides drop-down //! list to select its current item. It is build using composition with standard list view. +//! See [`DropdownList`] docs for more info and usage examples. + +#![warn(missing_docs)] use crate::{ border::BorderBuilder, @@ -22,32 +25,120 @@ use std::{ sync::mpsc::Sender, }; +/// A set of possible messages for [`DropdownList`] widget. #[derive(Debug, Clone, PartialEq, Eq)] pub enum DropdownListMessage { + /// A message, that is used to set new selection and receive selection changes. SelectionChanged(Option), + /// A message, that is used to set new items of a dropdown list. Items(Vec>), + /// A message, that is used to add an item to a dropdown list. AddItem(Handle), + /// A message, that is used to open a dropdown list. Open, + /// A message, that is used to close a dropdown list. Close, } impl DropdownListMessage { - define_constructor!(DropdownListMessage:SelectionChanged => fn selection(Option), layout: false); - define_constructor!(DropdownListMessage:Items => fn items(Vec>), layout: false); - define_constructor!(DropdownListMessage:AddItem => fn add_item(Handle), layout: false); - define_constructor!(DropdownListMessage:Open => fn open(), layout: false); - define_constructor!(DropdownListMessage:Close => fn close(), layout: false); + define_constructor!( + /// Creates [`DropdownListMessage::SelectionChanged`] message. + DropdownListMessage:SelectionChanged => fn selection(Option), layout: false + ); + define_constructor!( + /// Creates [`DropdownListMessage::Items`] message. + DropdownListMessage:Items => fn items(Vec>), layout: false + ); + define_constructor!( + /// Creates [`DropdownListMessage::AddItem`] message. + DropdownListMessage:AddItem => fn add_item(Handle), layout: false + ); + define_constructor!( + /// Creates [`DropdownListMessage::Open`] message. + DropdownListMessage:Open => fn open(), layout: false + ); + define_constructor!( + /// Creates [`DropdownListMessage::Close`] message. + DropdownListMessage:Close => fn close(), layout: false + ); } +/// Drop-down list is a control which shows currently selected item and provides drop-down +/// list to select its current item. It is used to show a single selected item in compact way. +/// +/// ## Example +/// +/// A dropdown list with two text items with the last one selected, could be created like so: +/// +/// ```rust +/// # use fyrox_ui::{ +/// # core::pool::Handle, dropdown_list::DropdownListBuilder, text::TextBuilder, +/// # widget::WidgetBuilder, BuildContext, UiNode, +/// # }; +/// # +/// fn create_drop_down_list(ctx: &mut BuildContext) -> Handle { +/// DropdownListBuilder::new(WidgetBuilder::new()) +/// .with_items(vec![ +/// TextBuilder::new(WidgetBuilder::new()) +/// .with_text("Item 0") +/// .build(ctx), +/// TextBuilder::new(WidgetBuilder::new()) +/// .with_text("Item 1") +/// .build(ctx), +/// ]) +/// .with_selected(1) +/// .build(ctx) +/// } +/// ``` +/// +/// Keep in mind, that items of a dropdown list could be any widget, but usually each item is wrapped +/// in some other widget that shows current state of items (selected, hovered, clicked, etc.). One +/// of the most convenient way of doing this is to use Decorator widget: +/// +/// ```rust +/// # use fyrox_ui::{ +/// # border::BorderBuilder, core::pool::Handle, decorator::DecoratorBuilder, +/// # dropdown_list::DropdownListBuilder, text::TextBuilder, widget::WidgetBuilder, BuildContext, +/// # UiNode, +/// # }; +/// # +/// fn make_item(text: &str, ctx: &mut BuildContext) -> Handle { +/// DecoratorBuilder::new(BorderBuilder::new( +/// WidgetBuilder::new().with_child( +/// TextBuilder::new(WidgetBuilder::new()) +/// .with_text(text) +/// .build(ctx), +/// ), +/// )) +/// .build(ctx) +/// } +/// +/// fn create_drop_down_list_with_decorators(ctx: &mut BuildContext) -> Handle { +/// DropdownListBuilder::new(WidgetBuilder::new()) +/// .with_items(vec![make_item("Item 0", ctx), make_item("Item 1", ctx)]) +/// .with_selected(1) +/// .build(ctx) +/// } +/// ``` +/// +/// #[derive(Default, Clone, Debug, Visit, Reflect, ComponentProvider)] pub struct DropdownList { + /// Base widget of the dropdown list. pub widget: Widget, + /// A handle of the inner popup of the dropdown list. It holds the actual items of the list. pub popup: InheritableVariable>, + /// A list of handles of items of the dropdown list. pub items: InheritableVariable>>, + /// A handle to the `ListView` widget, that holds the items of the dropdown list. pub list_view: InheritableVariable>, + /// A handle to a currently selected item. pub current: InheritableVariable>, + /// An index of currently selected item (or [`None`] if there's nothing selected). pub selection: InheritableVariable>, + /// A flag, that defines whether the dropdown list's popup should close after selection or not. pub close_on_selection: InheritableVariable, + /// A handle to an inner Grid widget, that holds currently selected item and other decorators. pub main_grid: InheritableVariable>, } @@ -214,18 +305,6 @@ impl Control for DropdownList { } impl DropdownList { - pub fn selection(&self) -> Option { - *self.selection - } - - pub fn close_on_selection(&self) -> bool { - *self.close_on_selection - } - - pub fn items(&self) -> &[Handle] { - &self.items - } - fn sync_selected_item_preview(&mut self, ui: &mut UserInterface) { // Copy node from current selection in list view. This is not // always suitable because if an item has some visual behaviour @@ -261,6 +340,7 @@ impl DropdownList { } } +/// Dropdown list builder allows to create [`DropdownList`] widgets and add them a user interface. pub struct DropdownListBuilder { widget_builder: WidgetBuilder, items: Vec>, @@ -269,6 +349,7 @@ pub struct DropdownListBuilder { } impl DropdownListBuilder { + /// Creates new dropdown list builder. pub fn new(widget_builder: WidgetBuilder) -> Self { Self { widget_builder, @@ -278,26 +359,31 @@ impl DropdownListBuilder { } } + /// Sets the desired items of the dropdown list. pub fn with_items(mut self, items: Vec>) -> Self { self.items = items; self } + /// Sets the selected item of the dropdown list. pub fn with_selected(mut self, index: usize) -> Self { self.selected = Some(index); self } + /// Sets the desired items of the dropdown list. pub fn with_opt_selected(mut self, index: Option) -> Self { self.selected = index; self } + /// Sets a flag, that defines whether the dropdown list should close on selection or not. pub fn with_close_on_selection(mut self, value: bool) -> Self { self.close_on_selection = value; self } + /// Finishes list building and adds it to the given user interface. pub fn build(self, ctx: &mut BuildContext) -> Handle where Self: Sized, diff --git a/fyrox-ui/src/inspector/editors/enumeration.rs b/fyrox-ui/src/inspector/editors/enumeration.rs index 37f79f388..bbff290dc 100644 --- a/fyrox-ui/src/inspector/editors/enumeration.rs +++ b/fyrox-ui/src/inspector/editors/enumeration.rs @@ -456,7 +456,7 @@ where .expect("Must be a DropDownList"); let variant_index = (self.index_generator)(value); - if Some(variant_index) != variant_selector_ref.selection() { + if Some(variant_index) != *variant_selector_ref.selection { let environment = ctx .ui .node(instance_ref.inspector)