List view
List view is used to display lists with arbitrary items. It supports multiple selection and by default, it stacks the items vertically (this can be changed by providing a custom panel for the items, see the section below).
Example
ListView
can be created using ListViewBuilder
:
#![allow(unused)] fn main() { fn create_list(ctx: &mut BuildContext) -> Handle<UiNode> { ListViewBuilder::new(WidgetBuilder::new()) .with_items(vec![ TextBuilder::new(WidgetBuilder::new()) .with_text("Item0") .build(ctx), TextBuilder::new(WidgetBuilder::new()) .with_text("Item1") .build(ctx), ]) .build(ctx) } }
Keep in mind, that the items of the list view can be pretty much any other widget. They also don't have to be the same type, you can mix any type of widgets.
Custom Items Panel
By default, list view creates inner StackPanel
to arrange its items. It is enough for most cases, however,
in rare cases you might want to use something else. For example, you could use WrapPanel
to create list view with
selectable "tiles":
#![allow(unused)] fn main() { fn create_list_with_panel(ctx: &mut BuildContext) -> Handle<UiNode> { ListViewBuilder::new(WidgetBuilder::new()) // Using WrapPanel instead of StackPanel: .with_items_panel(WrapPanelBuilder::new(WidgetBuilder::new()).build(ctx)) .with_items(vec![ TextBuilder::new(WidgetBuilder::new()) .with_text("Item0") .build(ctx), TextBuilder::new(WidgetBuilder::new()) .with_text("Item1") .build(ctx), ]) .build(ctx) } }
Selection
List view supports any number of selected items (you can add items to the current selecting by holding Ctrl key),
you can change it at runtime by sending [ListViewMessage::SelectionChanged
] message with
[MessageDirection::ToWidget
] like so:
#![allow(unused)] fn main() { fn change_selection(my_list_view: Handle<UiNode>, ui: &UserInterface) { ui.send_message(ListViewMessage::selection( my_list_view, MessageDirection::ToWidget, vec![1], )); } }
It is also possible to not have selected item at all, to do this you need to send an empty vector as a selection.
To catch the moment when selection has changed (either by a user or by the ListViewMessage::SelectionChanged
)
you need to listen to the same message but with opposite direction, like so:
#![allow(unused)] fn main() { fn do_something(my_list_view: Handle<UiNode>, message: &UiMessage) { if let Some(ListViewMessage::SelectionChanged(selection)) = message.data() { if message.destination() == my_list_view && message.direction() == MessageDirection::FromWidget { println!("New selection is: {:?}", selection); } } } }
Adding/removing items
To change items of the list view you can use the variety of following messages: ListViewMessage::AddItem,
ListViewMessage::RemoveItem,
ListViewMessage::Items. To decide which one to use, is very simple - if you adding/removing a few items, use
ListViewMessage::AddItemand
ListViewMessage::RemoveItem, otherwise use
ListViewMessage::Items`, which changes the items at once.
#![allow(unused)] fn main() { fn change_items(my_list_view: Handle<UiNode>, ui: &mut UserInterface) { let ctx = &mut ui.build_ctx(); // Build new items first. let items = vec![ TextBuilder::new(WidgetBuilder::new()) .with_text("Item0") .build(ctx), TextBuilder::new(WidgetBuilder::new()) .with_text("Item1") .build(ctx), ]; // Then send the message with their handles to the list view. ui.send_message(ListViewMessage::items( my_list_view, MessageDirection::ToWidget, items, )); } }
Bringing a particular item into view
It is possible to bring a particular item into view, which is useful when you have hundreds or thousands of items and
you
want to bring only particular item into view. It could be done by sending a ListViewMessage::BringItemIntoView
message:
#![allow(unused)] fn main() { fn bring_item_into_view(my_list_view: Handle<UiNode>, my_item: Handle<UiNode>, ui: &UserInterface) { ui.send_message(ListViewMessage::bring_item_into_view( my_list_view, MessageDirection::ToWidget, my_item, )); } }