FileBrowserListener::fileClicked or selectionChanged


Either the fileClicked should be called when the user use the keyboard to select a file (for example, while holding shift + down arrow), either selectionChanged should have the modifier keys passed in.
Currently I’m using “const ModifierKeys mods = Desktop::getInstance().getMainMouseSource().getCurrentModifiers();” but it’s not the same, as I don’t have the modifier used when the event was generated.

What do you think ?

It’s not possible to pass modifiers to selectionChanged(), because it could be called programatically, in which case the modifiers would be irrelevant or misleading. And it shouldn’t call fileClicked() unless the file was actually clicked!

Why you need to know the modifiers? What are you actually trying to do?

The user is selecting a bench of files (named Base_xxxxx.ext with xxxxx a decimal number).

Currently, each selection is reflected in a status bar (something like “x files selected : lists of file”). When the user select a single file, the software count files with the same naming pattern and display the number of similar files (something like 235 files selected when clicking on a file called “base_0002.ext” in a directory with 235 files).

When the user clicks on a file with Shift or Ctrl, the status bar reacts by bypassing the automatic file counting, and actually displaying the number of files really selected.
That works well.

However, when the user click on a single file, and then use the keyboard holding down Shift and press Up or Down, 2 files are selected, but fileClicked is not called
"selectionChanged" is called, but it’s not currently possible to figure out if the user just pressed “Up” (in that case, the software should count the files), or Shift + Up (or Ctrl + Up).

Is is that important to know that the file was “clicked” ?
Really, I’m sure all Juce based software suffer from the same issue, that is, most user will implement their callback in fileClicked, and will miss the user intended selection (if you click and then use the keyboard to navigate the file tree, then press a button, it’ll use the clicked item, not the currently selected item).
I think a better approach would be to abstract how a file was selected (keyboard or mouse), but still be able to figure out the user intention from the modifier keys.

Also, unrelated bug, but if you select a file by clicking, then hold down Shift and press Up, it selects the file above. Then if you press down, it doesn’t unselect it. If you have a lot of files selected this way, it’s hard to know where is the current selection cursor.

Blimey, that’s a bit of an obscure requirement!

Isn’t it just a case of displaying different details if there’s more than one item selected? Seems over-complicated to make something like the status bar info depend on what keys are held down.

Yes, I’ve been meaning to sort that out…

The effect is not the same when Shift or Ctrl is down. Try with Windows’s file explorer, when holding down Ctrl, and using the navigation keys, it doesn’t select the items, but move a kind of rectangle over them, you can select them by pressing space (with Ctrl still down).

I’m not fond of this, but users are expecting this.
The best solution from my point of view, would be to remove fileClicked/selectionChanged and instead merge both in a single callback, BUT the file component should act like the native one in that case (and it would simplify my code a lot).

I can’t think of a clean solution to suggest… perhaps you could use ListBox::getLastRowSelected() to find out the row that was just highlighted?

I’ve done it with few modification on my side, but I don’t think they are “clean” enough to be included in main tree.
I’m using the “deselect file row” code idea from the other thread, and I’ve modified the paint callback for the row.

Does it work this way on mac ?
That is, you click on a file in a list, hold Ctrl down and navigate with the keyboard, does it select the files, or simply overbox them ?

[quote]Does it work this way on mac ?
That is, you click on a file in a list, hold Ctrl down and navigate with the keyboard, does it select the files, or simply overbox them ?[/quote]

No, it just selects them in a sensible and non-confusing way. I’ve always thought the windows approach was crap, IMHO. I’m fairly computer-literate, and have been using Windows for nearly 20 years, but even I don’t really know what’ll happen when I press ctrl and/or shift… will it select the file? will it move the strange dotted outline? Will it resize the strange dotted outline? Then how do I make it turn the dotted outline into a selection? And when it does that, do I lose my current selection? Unintuitive garbage.

In fact, I understand why it does this. If you don’t have a mouse (ok, uncommon, but still), you need a way to perform the same actions with the keyboard as with the mouse.
X allows to simulate the mouse pointer (with the numerical keyboard) so it’s a different approach.
If you want to cherry-pick items without using a mouse, it seems it’s not possible with Mac.

If you hold down Ctrl + Shift under windows, and then navigate with the keyboard, it acts like if only Shift was used.
If you hold down Ctrl, up key moves the selection overlay. If you release Ctrl, the selection overlay stays here, you can press space select it.
If you select the x-th file and then navigate to the y-th file with Ctrl down, and then, hold Shift down, it selects all files between x-th and y-th.

There is a difference here with just holding down Shift + navigating, as Shift select all files between the first and the current position.
For example, if you choose to display your icon as a grid, let’s say 6x6 items are displayed, and select the one at pos (3, 2), holding down shift and going to (4, 3), will select (3,2) (4,2) (5,2) (0,3) (1,3) (2,3) (3,3) (4,3).
If you do the same thing with Ctrl down, and use shift for the very last move, the selected items will be (3,2) (4,2) (3,3) (4,3) (that is: all the items overlaping the rectangle made by the 2 selection corners).

It’s hard to explain, but a bit intuitive to use in fact (still, I’m not using this myself, the describtion above comes from my first test after user reported the behaviour he expected).
I admit, this means many states to track if you want to emulate such a thing.