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.
This PR adds support for multi-select.
Dear ImGui 1.91.0 added a multi-select system for multi-selection idioms such as Shift/Ctrl + mouse/keyboard, box-selection and more. See the Dear ImGui wiki for details. This PR adds the corresponding bindings.
Additions and changes
Multi-select is used with a builder, and there are shortcut functions for common cases.
MultiSelectFlags
can be used for configuration. Tokens are used to interact with a multi-selection, including access toMultiSelectIo
structs created by Dear ImGui, which contain all information about selection changes as well as additional details. Apart from the basic bindings for the Dear ImGui API,MultiSelectIo
also includes an iterator over selection changes for individual items (RequestItems
), which is mainly intended to simplify user implementations ofSelectionStorage
.Selection data is maintained by user code. The
SelectionStorage
trait is used for storage types for selection data.SelectionBasicStorage
is a self-contained implementation provided by Dear ImGui, andSelectionExternalStorage
can wrap a storage provided by the user.This PR also includes an addition to
ListClipper
to support multi-select with clipping, and a fix for emptyImVector
s required by the multi-select implementation.Lastly, I updated the Cargo.toml files of imgui and imgui-sys to actually use the MSRV set in the workspace. Rust version 1.81.0 introduced a change for
extern "C"
functions so that uncaught panics now cause an abort instead of UB. The callbacks inSelectionBasicStorage
andSelectionExternalStorage
rely on this behavior for soundness.Progress of implementation
The core multi-select system is fully functional. There are a few details left to add or improve, but I wanted to open this as a draft PR to get feedback on the API and implementation. In particular, I would appreciate feedback on these issues:
BeginMultiSelect
andEndMultiSelect
. A nestedBeginMultiSelect
would invalidate the pointer returned from the previous one. I don't know if there is a good way to encode this with Rust lifetimes, so it is checked dynamically withUi::multi_select_lock
. The other lifetime limits (EndMultiSelect
and end of frame) are enforced statically. We could allow nesting by just cloning the returned structs instead of referencing them, but forImGuiMultiSelectIO::RangeSrcReset
, the user actually needs write access.SelectionBasicStorage
andSelectionExternalStorage
unfortunately require a'static
lifetime. This is currently required for soundness, but also prevents some valid uses, so a sound way to relax these bounds would be desirable.ImGuiSelectionBasicStorage
storesImGuiID
s, but uses them as plain ints. The current imgui-rs bindings forImGuiID
don't allow simple casts, which makes ids hard to use here, soSelectionBasicStorage
simply usesu32
instead.