Implement the shift click gesture to select several adjacent threads in the timeline#4138
Conversation
b861724 to
b6e8f9a
Compare
Codecov Report
@@ Coverage Diff @@
## main #4138 +/- ##
==========================================
+ Coverage 88.33% 88.46% +0.13%
==========================================
Files 280 280
Lines 24409 24510 +101
Branches 6491 6533 +42
==========================================
+ Hits 21561 21683 +122
+ Misses 2645 2625 -20
+ Partials 203 202 -1
Continue to review full report at Codecov.
|
94e4d4c to
ea45ec6
Compare
ea45ec6 to
33fcee5
Compare
3fd5ecd to
5f305b2
Compare
|
This works quite well! I've noticed one case that I think can be tweaked: "Shift selection after Cmd selection"
Expected selection: 1, 3, 4, 5 (this is what macOS Finder does) |
|
I also noticed some weirdness with the IPC tracks, but that's probably something that can be fixed as a follow-up. For example, in the "Utility AudioDecoder" process, the "MediaPDecoder #1" thread is framed by two IPC tracks. Clicking one of those IPC tracks and then shift-clicking the other creates a selection which only contains the thread-track in between. Cmd+clicking the tracks individually has a different result. |
Ah, that's interesting!
Ah that's interesting too! This is quite similar to the previous issue in that when we don't use Ctrl we replace the previous selection. I can see how it's weird in this case though and I'll think about how to fix it easily. |
Interestingly: libreoffice spreadsheets works like MacOS X' finder, but google spreadsheets works like my implementation. |
5f305b2 to
1ab1c13
Compare
That one was easy to fix. I'm trying to implement the other behavior. |
1ab1c13 to
964e667
Compare
|
Now this case doesn't work as expected anymore: 1 is selected, Cmd 3, Shift 5, Shift 2, expected: 1, 2, 3 I haven't looked at your code at all, but I would implement it as follows: type State = {|
currentSelection: Set<TrackId>,
selectionAtLastNonShiftClick: Set<TrackId>,
clickedTrackAtLastNonShiftClick: TrackId,
|};
function onClick(state: State, clickedTrack: TrackId): State {
const newSelection = new Set([clickedTrack]);
return {
currentSelection: newSelection,
selectionAtLastNonShiftClick: newSelection,
clickedTrackAtLastNonShiftClick: clickedTrack,
}
}
function onCmdClick(state: State, clickedTrack: TrackId): State {
const newSelection = new Set([...state.currentSelection, clickedTrack]);
return {
currentSelection: newSelection,
selectionAtLastNonShiftClick: newSelection,
clickedTrackAtLastNonShiftClick: clickedTrack,
}
}
function onShiftClick(state: State, clickedTrack: TrackId): State {
const shiftSelection = computeTracksBetween(state.clickedTrackAtLastNonShiftClick, clickedTrack);
const newSelection = new Set([...state.selectionAtLastNonShiftClick, ...shiftSelection]);
return {
...state,
currentSelection: newSelection,
}
} |
Oh, correction, it wasn't working at all before either. So I should rather say: Thank you for implementing the Cmd-then-shift behavior, but here's a case that can still be improved to match macOS Finder more closely. |
5438b44 to
a267764
Compare
5b85355 to
61d33ae
Compare
I agree, I expect this to work too, and it doesn't. This works as expected without the Ctrl thing.
This is pretty close to what I did but maybe I added piles on top of other piles and I could now possibly simplify this a bit. For example my code used to work in a quite stateless way initially, always recomputing the full range when shift was used and replacing the full selection, but then I added more state to control it. I like how you wrote that shift click reuse the previous selection, which builds on the assumption that the previous click either already replaced the previous selection or added to the previous selection, and I haven't thought of this idea before. So thanks! |
|
OK, I know what my bug is, and what you propose (saving the |
61d33ae to
3cc7a3c
Compare
| invertCallstack, | ||
| selectedThreadIndexes, | ||
| } = this.props; | ||
| const modifiers = getTrackSelectionModifiers(event); |
There was a problem hiding this comment.
Here it looks like it's a lot of changes, but if you look at the changes without the whitespace changes you'll see the code has just been reordered.
a92915d to
71f7278
Compare
| * information in the state. Because of all possible cases this isn't trivial. | ||
| * This will return null for tracks that are not selectable. | ||
| */ | ||
| function getInformationFromTrackReference( |
There was a problem hiding this comment.
This commit might be easier to follow with whitespace changes.
|
I reimplemented most of the patch following Markus' excellent suggestion (I wish I thought of that earlier :D), now I believe all mentioned use cases work as expected. It should be easier to look commit by commit. |
| let selectedTab = | ||
| clickedTrackInformation.relatedTab ?? getSelectedTab(getState()); | ||
| const visibleTabs = getThreadSelectors( | ||
| clickedTrackInformation.relatedThreadIndex | ||
| ).getUsefulTabs(getState()); | ||
| if (!visibleTabs.includes(selectedTab)) { | ||
| // If the user switches to another track that doesn't have the current | ||
| // selectedTab then switch to the first tab. | ||
| selectedTab = visibleTabs[0]; | ||
| } |
There was a problem hiding this comment.
I wasn't sure what to do with the selectedTab, should we change it for all modes? Maybe we'd want to change it only for setOneTrackSelection... I thought it would be easy to change in a follow-up if needed.
canova
left a comment
There was a problem hiding this comment.
Looks great, thanks for the feature and adding lots of tests! I've added a few nits mostly.
| } | ||
| } | ||
|
|
||
| // Add the global track if it's not a virtual track and not out of the range. |
There was a problem hiding this comment.
By "virtual" you mean a global tack with a thread, right?
There was a problem hiding this comment.
"virtual track" means here a global track that is not a thread (such as what we get when importing sometimes).
But the comment says "add the global track if it's not virtual", maybe that's where you got confused?
… to accept shift modifiers
…rence to a separate function
71f7278 to
7caaf80
Compare
|
Thanks so much for the review! I believe I handled all your comments and will merge now! |
Gestures that work:
Here is a deploy preview
Fixes #2710
Screencast_20220721_184835.mp4