ability to add list view items in front of the list

This commit is contained in:
Dmitry Stepanov
2026-10-06 22:07:12 +03:00
parent 141b692cfe
commit 7c6a8eac46
5 changed files with 58 additions and 37 deletions
+7 -1
View File
@@ -498,7 +498,13 @@ impl AudioPanel {
.with_audio_bus(audio_bus_handle)
.build(&mut ui.build_ctx());
ui.send_sync(self.audio_buses, ListViewMessage::add_item(item));
ui.send_sync(
self.audio_buses,
ListViewMessage::AddItem {
node: item.to_base(),
in_front: false,
},
);
}
}
}
+7 -4
View File
@@ -327,10 +327,13 @@ impl Configurator {
self.history.last().unwrap(),
);
engine
.user_interfaces
.first()
.send(self.lv_history, ListViewMessage::AddItem(widget));
engine.user_interfaces.first().send(
self.lv_history,
ListViewMessage::AddItem {
node: widget,
in_front: false,
},
);
}
engine
+10 -8
View File
@@ -336,7 +336,7 @@ impl EntityCreator {
new_items.push(recent_item);
}
ui.send(self.recent_list, ListViewMessage::Items(new_items))
}
}
fn has_recent_item(&self, ui: &UserInterface, name: &str) -> bool {
if let Ok(recent_list) = ui.try_get(self.recent_list) {
@@ -379,7 +379,13 @@ impl EntityCreator {
let variant = constructors.try_get_variant(constructor_id)?;
if !self.has_recent_item(ui, variant.name.as_str()) {
let recent_item = make_recent_item(ui, &variant.name);
ui.send(self.recent_list, ListViewMessage::AddItem(recent_item));
ui.send(
self.recent_list,
ListViewMessage::AddItem {
node: recent_item,
in_front: true,
},
);
if let Some(scene_settings) =
scene_path.and_then(|p| settings.scene_settings.get_mut(p))
{
@@ -613,12 +619,8 @@ impl EntityCreator {
};
sender.do_command(AddWidgetCommand::new(sub_graph, parent, true));
}
EntityCreatorMode::CreateParent => {
// TODO
}
EntityCreatorMode::CreateReplacement => {
// TODO
}
// The rest is unsupported.
_ => (),
}
}
}
+7 -1
View File
@@ -258,7 +258,13 @@ impl Control for DropdownList {
self.sync_selected_item_preview(ui);
}
&DropdownListMessage::AddItem(item) => {
ui.send(*self.list_view, ListViewMessage::AddItem(item));
ui.send(
*self.list_view,
ListViewMessage::AddItem {
node: item,
in_front: false,
},
);
self.items.push(item);
}
&DropdownListMessage::Selection(selection) => {
+27 -23
View File
@@ -55,7 +55,14 @@ pub enum ListViewMessage {
/// A message, that is used to set new items of a list view.
Items(Vec<Handle<UiNode>>),
/// A message, that is used to add an item to a list view.
AddItem(Handle<UiNode>),
AddItem {
/// An item to add.
node: Handle<UiNode>,
/// Where to add the item - either in front or the back of the list.
/// Adding an item in front will result in [`Self::Selection`] message to be produced
/// in response with current selection shifted by one.
in_front: bool,
},
/// A message, that is used to remove an item from a list view.
RemoveItem(Handle<UiNode>),
/// A message, that is used to bring an item into view.
@@ -63,23 +70,6 @@ pub enum ListViewMessage {
}
impl MessageData for ListViewMessage {}
impl ListViewMessage {
/// Creates [`Self::AddItem`] message.
pub fn add_item(handle: Handle<impl ObjectOrVariant<UiNode>>) -> Self {
Self::AddItem(handle.to_base())
}
/// Creates [`Self::RemoveItem`] message.
pub fn remove_item(handle: Handle<impl ObjectOrVariant<UiNode>>) -> Self {
Self::RemoveItem(handle.to_base())
}
/// Creates [`Self::BringItemIntoView`] message.
pub fn bring_item_into_view(handle: Handle<impl ObjectOrVariant<UiNode>>) -> Self {
Self::BringItemIntoView(handle.to_base())
}
}
/// 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).
@@ -423,13 +413,27 @@ impl Control for ListView {
self.fix_selection(ui);
self.sync_decorators(ui);
}
&ListViewMessage::AddItem(item) => {
let item_container = generate_item_container(&mut ui.build_ctx(), item);
&ListViewMessage::AddItem { node, in_front } => {
let item_container = generate_item_container(&mut ui.build_ctx(), node);
ui.send(item_container, WidgetMessage::LinkWith(*self.panel));
if in_front {
ui.send(item_container, WidgetMessage::LinkWithReverse(*self.panel));
self.item_containers.push(item_container);
self.items.push(item);
self.item_containers.insert(0, item_container);
self.items.insert(0, node);
// Keep selection the same.
let mut new_selection = self.selection.clone();
for index in new_selection.iter_mut() {
*index += 1;
}
ui.send(self.handle, ListViewMessage::Selection(new_selection));
} else {
ui.send(item_container, WidgetMessage::LinkWith(*self.panel));
self.item_containers.push(item_container);
self.items.push(node);
}
}
ListViewMessage::Selection(selection) => {
if &self.selection != selection {