BoxSelect, tap select, unselect and shift select with control/shift modifier keys like windows explorer

What I want to do:

I want to use the box select tool to drag a box around some rectangles with greedy mode and continuous mode on.

Once I’ve got my boxes selected:
I want to hold down ctrl and click boxes to drop them from my selection if they are selected already.
if they are not selected already, I want to add them to my selection.
If i Have no boxes selected yet, I would like to select the box being ctrl + clicked.

If I hold shift and drag another box, I’d like any glyphs I hit to be added to my selection.

If I hold control and drag a box I’d like any glyphs I hit that are already selected to be dropped, and any glyphs I haven’t selected to be added to my selection.

If I regular left click outside of any glyph, I’d like my selection to be cleared.

If I regular left click on any glyph replace my selection with just that one glyph I clicked

I tried to accomplish this with the box select and tap tool turned on at the same time, but the control and shift clicks behave in a manner I don’t understand.

from bokeh.plotting import figure, show, output_file
from bokeh.models import  BoxZoomTool,ResetTool,LassoSelectTool,PanTool,BoxSelectTool,WheelZoomTool,TapTool,Tap

p = figure(width=400, height=400
           , tools=[
              , ResetTool()
              , PanTool()
              , WheelZoomTool()
              , BoxSelectTool(continuous=True, greedy=True)
              , 'tap'
p.quad(top=[2, 3, 4], bottom=[1, 2, 3], left=[1, 2, 3],
       right=[1.2, 2.5, 3.7], color="#B3DE69")

output_file(filename="custom_filename.html", title="Static HTML file")


What I’ve read so far:

“Toggle selection of objects with shift+click”

" Allow to configure selection tool mode"

There’s a lot going on here. I’m not sure you’ll be able to get everything you want out of the box, but let’s try taking on some of the pieces one at a time.

First, make sure you have at least Bokeh 3.1 and then you can pass persistent=True to BoxSelectTool. That will get you the editable/draggable box selection work that was added in this PR. I would expect the shift-interactions to already work additively.

cc @mateusz for comments as well.

Hey thanks for the reply! Ive written tools like this before in JMP/jmp scripting language and in the javascript addon “dragselect”

Just tested the persisting behavior, but it’s not quite what I’m looking for either. The box stays on the screen as a movable/resizeable shape. That’s kind of useful but it still only allows you to work with things that will fit in 1 and only 1 rectangle.

Just retested with persistent=False the shift + select works as intended for adding shapes to the selection (in both cases actually). Just persistent=True allows you to resize the latest box by hand to modify the selected area, which is pretty cool and I can think of a different application for that in another project :slightly_smiling_face:

I think if this doesn’t exist out of the box ill need to understand:
How a selection event is stored called
How to retrieve the array of selected objects
How to apply a modifier key “ctrl” so manipulate my array of selected objects / new selections and sync up visual states in the plot accordingly.
how to manipulate that stored array
how to apply modifier keys to achieve the behaviors im trying to create.

Thanks for the tip on “persisting” the box select that gave me some insight that the plot wasnt retaining a state but maybe just showing the visual leftovers from the select event.

@Bryan I’m doing my own reading of course, but if you have any link to a relevant example of applying a key modifier to the box select and altering its behavior, I can start from that and probably apply it to the tap tool as well. Then by having box select and tap tool on at the same time I can just catch both events independently and change what they do to suit.