imgui
imgui copied to clipboard
Range Selection / Multiple selection for TreeNode (Shift+click, Shift+arrows)
It's very straightforward to use Ctrl key to select multiple nodes in the tree. However, it seems when to the shift key multiple selection, the problem becomes complicated. The shift selection is very common in desktop applications.
Shift key selection logic is basically like this:
- we select some node(s)
- then press shift and keep it down
- mouse click some node below or above the node(s) we already selected in step 1
- the result is we added more selected or removed from selected based on different cases
Is there a way to achieve this feature?
Hello,
I've actually been working on this in the past few weeks. It's not an easy problem to solve because there are various subtleties with how to handle CTRL/SHIFT combinations along with Mouse and Keyboard while still allow for clipping to be used.
Anyway. I've got a prototype version that I'll be iterating on (it doesn't work with TreeNode yet, only for Selectable) and hopefully can push something in the upcoming few weeks. Your feedback will be welcome then.
Here are some internals WIP gif I made along the way


Thanks for the all the work! It seems to be more complicated for the tree nodes because of the hierarchy I guess? Looking forward to the new feature!
It's not really a problem of hierarchy, but the current API require an extra parameter to pass it data that identify items (often an index). This identification is needed because at the beginning or end of a list imgui needs to communicate requests for range-selection. Considering the explosion of TreeNode API entry point we may need a different approach here.
Currently the WIP api use something like that for Selectable:
// Multi-selection system
// This enables standard multi-selection idioms (CTRL+Click/Arrow, SHIFT+Click/Arrow, etc) in a way that allow items to be fully clipped (= not submitted at all) when not visible.
// Read comments near ImGuiMultiSelectData for details.
ImGuiMultiSelectData* BeginMultiSelect(ImGuiMultiSelectFlags flags, void* range_ref, bool range_ref_is_selected);
ImGuiMultiSelectData* EndMultiSelect();
bool MultiSelectable(const char* label, bool selected, void* item_data, ImGuiSelectableFlags extra_flags = 0, ImVec2 size = ImVec2(0,0)); // return true when selection needs toggling
With the extra void* item_data.
I already have a few things to improve with the current API and I will of course add TreeNode in the mix. Perhaps moving to a separate call SetNextMultiSelectData(void*) and use regular entry point (and remove MutliSelectable()).
I reworked the range-select/multi-select API and made it work with TreeNode(). Here's a quick GIF.

It's a little awkward looking because TreeNode don't have the same form of highlight as Selectable() so there is spacing with you range select multiple items.
This API is little quite early/experimental but I'll probably push it to a branch at some point. It would also be healthy to create a full-featured demo with TreeNode featuring Range-Selection, Drag and Drop, etc.
Hi @ocornut. This prototype looks great!
But right now I have request to do multiselection for nested tree (powered by imGui::TreeNode) and there are two major issues:
- correct\fast clipping respecting that TreeNode may be nested
- multiselection itself (including the case when child TreeNodes require selection)
Maybe you have some ideas how to solve these issues?
Hello @bsviglo, Your requests / issues are too vague and ambiguous. Please get into more specific details.
Hi @ocornut. Sorry for being ambiguous in my explanation. I'll try to explain visually what I mean.
On this animated screen I have a world outliner which allows me to visualize and select any object in the scene hierarchy. So far I've managed to select each scene object indivudually but without clipping & range selection.

Basically I'd like to achieve the following:
- be able to select any object individually or by range select. And be able to combine selection where some object may be roots while others may be childred on other root tree nodes.
- Efficiently skip unnessecary calculations (they are pretty expensive) to visualize tree node (similar to Imgui clipper, but taking into account that we're clipping not a plain list of data but arbitrary deep tree).
Hopefully, it becomes more clear now.
Hi @ocornut do you consider implementing ImGuiTreeClipper helper in the near future?
It looks like a first class citizen for any kind of tree visualization techniques (scene outliner, hierarchy view, tree like document structure, etc)
And having this helper builtin in library will be very convinient
I'd like to have a solution for this implemented but probably won't have time in the near future. Feel free to try working on a solution.!
2021 update To clarify, the range_select branch been maintained and rebased over master regularly, and designed to merge in docking.
It hasn't been merged because I was rather unhappy with the API. But YOU CAN USE THIS IF YOU NEED IT. If the API change I'll write things down here.
Recently I went through it and listed what I think I could do before "shipping" it:
- [x] Could we replace RangeSrc/RangeDst to integer indices for simplicity? Technically less flexible but so more much obvious.... The current scheme was designed to allow user to manage clipping + range-select over uncontiguous but ordered data sets (e.g. arrays but also e.g. double linked list). Since there's likely a filtering indirection done by the user, switching to require random access and using int would make api simpler and terser to use.
- [x] User having to store RangeRef is an UI artifact and generally undesirable, should aim to remove: means users needs to call another function to provide selected state.
- [x] Possible confusion between user-stored selection and 'ImGuiMultiSelectData' name?
- [ ] Introduce new style colors (currently interpolating). Probably generalize some extra concepts (focused/unfocused selection color).
I know this sounds surreal but I've been working on this on and off since my original answer in 2018. It's been used in production on some project for years but I wasn't happy with the API and never formally released it.
I thought I was 80% done, but trying to finish the remaining 20% recently I've been going through countless hoops, redesign, improvements, and writing new demos (filters, trees, deletion, grid etc..) And trying to get the demos to a decent quality levels usually drags in a bunch of misc unrelated features (many of them have been incorporated over the years).
Anyhow. This is very alive and at some point I will open a new thread and ask for more public feedback.
I have merged multi-select into master.
See https://github.com/ocornut/imgui/wiki/Multi-Select for some details.
I will open a thread shortly to gather feedback/bugs so please post so that one thread instead.
I need to clarify: this particular issue as worded is not fully solved as of today, because using multi-select for tree node is rather unobvious and and not easy currently. In fact, there's no demo for it yet (I'm working on one) and the multi-select branch is currently mostly demoing using Selectable() with multi-select.
Basically you need some sort of linear/random access to your tree, which may be emulated with some linear traversal code, but as it happens, a more advanced tree in a more advanced app is going to want to use a clipper and a filter, and those feature need the same sort of access that multi-select needs. I'm currently working on this.