Add MultiSelection Resource to enable selecting multiple entities. Up…#403
Add MultiSelection Resource to enable selecting multiple entities. Up…#403JohnTGZ wants to merge 3 commits intoopen-rmf:mainfrom
Conversation
|
@xiyuoh Hi, please take a look and provide any thoughts/suggestions on the implementation, thank you! |
mxgrey
left a comment
There was a problem hiding this comment.
Thanks for kicking off this feature development. I've wanted a multi-select for a long time but I've been held back by how intertwined the selection mechanisms are.
I've left some recommendations for changes that I think we need to make before we can move forward with this PR. The current approach you've made is very minimal in lines of code changed and minimal in disruption, which are good qualities, but I fear it's creating a fragmented selection pipeline that will leave us with some technical debt in the long run.
| if let Some(multi_selection) = world.get_resource::<MultiSelection>() { | ||
| // If multiple entities are selected, we skip showing the Inspect plugin. | ||
| if multi_selection.0.len() > 1 { | ||
| ui.label("Using multi-selection of entities. Disabling Inspector widget."); |
There was a problem hiding this comment.
Instead of disabling the inspector widget, I think we should show something like a list of the objects that are currently selected.
I would recommend introducing a DeselctionWidget as a contrast to the SelectionWidget. Instead of a finger icon to indicate selecting the object, we can use an x icon to indicate de-selcting it. When the user hovers the x, it has the same hover effect as the SelectionWidget, but clicking on the x will remove the object from the list of selected items.
| mut selected: Query<&mut Selected>, | ||
| mut selection: ResMut<Selection>, | ||
| mut multi_selection: ResMut<MultiSelection>, | ||
| keyboard_input: Res<ButtonInput<KeyCode>>, |
There was a problem hiding this comment.
I don't think we should use keyboard_input directly here, for a bunch of reasons:
- This hard-codes the use of left shift as the thing that differentiates between multi-select vs single-select, but we may want to allow key remapping or other ways to toggle multi-select
- Not all interaction modes can make use of multi-select. For example it wouldn't make sense to build up a selection of multiple anchors while creating a lane.
I think what I would suggest instead is to add a field to the Select structure that indicates whether or not multi-select is allowed. Then it's up to the systems that generate the Select event to decide if multi-select is supported for the action. We can introduce a resource
#[derive(Resource)]
pub struct InspectionSettings {
pub multi_select: bool,
}which the inspector mode will use to decide whether the Select event should have multi-select enabled or not. This InspectionSettings resource can have its multi_select field toggled by a system that listens for when the left shift key goes up or down. In the future we can generalize that to allow keybindings, and downstream users can introduce their own way to toggle the setting.
There was a problem hiding this comment.
I think this approach is better. I was wondering what would be the best way to restrict multi-selection to say model_instances and not lanes, anchors etc. and this does the trick and is more scalable.
To summarize:
- We update the
Selectevent to have amulti_selectfield which will determine if we are able to select multiple entities:
pub struct Select {
#[deref]
pub selection_candidate: Option<SelectionCandidate>,
pub multi_select: bool,
}-
Add a system that monitors
Res<ButtonInput<KeyCode>>, where upon change in the SHIFT keyboard input, it will update theInspectionSettingsresource. -
The individual inspector functions will read the
InspectionSettingsresource to update themulti_selectfield ofSelectwhen triggering aSelectevent. -
The
selection_updateservice receives theSelectevent and reads it to determine whether to enable/disable multi-selection
There was a problem hiding this comment.
In the midst of implementing this and there are some things Im unclear about and your advice would help:
- Where is a good place to put the
InspectionSettingsresource? I am inclined to put it incrates/rmf_site_picking/src/select/resources.rs - For checking if the SHIFT key goes up or down, I was thinking to extend deselect_on_esc to check for
.pressed(…)or.released(…)on SHIFT and then, updating theInspectionSettingsresource accordingly.
There was a problem hiding this comment.
Okay that might not work, because the input to deselect_on_esc is a KeyCode and not ButtonInput<KeyCode>. Im thinking that using an async service might not be the best either, and perhaps a typical Bevy system should suffice
|
Hi @mxgrey , thank you for all the suggestions. I have re-implemented the multi-selection mechanism as follows:
I have yet to implement the de-selection mechanism but would like to get some feedback on the current implementation. |
Signed-off-by: JohnTGZ <johntangz@google.com>
d510e17 to
3eb9e33
Compare
Signed-off-by: John TGZ <johntangz@google.com>
Signed-off-by: JohnTGZ <johntangz@google.com>
|
Hi Grey, sorry for the long gap in between addressing the review comments. I have addressed the review comments and made the following changes:
|



New feature implementation
Implemented feature
This PR implements the ability to select multiple models in the site which is briefly described in issue #337 .
User workflow:
Implementation description
One of the primary changes involves introducing the
MultiSelectionresource which is aHashSetto hold multiple entities.While multiple entities are selected by holding down the SHIFT key:
Inspectwidget is disabled.MultiSelectionresource will be updated to hold the selected entitiesGenAI declaration