Skip to content

Commit b7e66ec

Browse files
author
Brian Vaughn
committed
Changed scroll wheel behavior
Vertical wheel now zooms. Horizontal wheel pans. (Vertical wheel with shift zooms.) Wheel events of any kind clear the current tooltip as well.
1 parent 216f4cd commit b7e66ec

File tree

5 files changed

+93
-64
lines changed

5 files changed

+93
-64
lines changed

packages/react-devtools-scheduling-profiler/src/CanvasPage.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,39 @@ function AutoSizedCanvas({data, height, width}: AutoSizedCanvasProps) {
310310
return;
311311
}
312312

313+
// Wheel events should always hide the current toolltip.
314+
switch (interaction.type) {
315+
case 'wheel-control':
316+
case 'wheel-meta':
317+
case 'wheel-plain':
318+
case 'wheel-shift':
319+
setHoveredEvent(prevHoverEvent => {
320+
if (prevHoverEvent === null) {
321+
return prevHoverEvent;
322+
} else if (
323+
prevHoverEvent.flamechartStackFrame !== null ||
324+
prevHoverEvent.measure !== null ||
325+
prevHoverEvent.nativeEvent !== null ||
326+
prevHoverEvent.schedulingEvent !== null ||
327+
prevHoverEvent.suspenseEvent !== null ||
328+
prevHoverEvent.userTimingMark !== null
329+
) {
330+
return {
331+
data: prevHoverEvent.data,
332+
flamechartStackFrame: null,
333+
measure: null,
334+
nativeEvent: null,
335+
schedulingEvent: null,
336+
suspenseEvent: null,
337+
userTimingMark: null,
338+
};
339+
} else {
340+
return prevHoverEvent;
341+
}
342+
});
343+
break;
344+
}
345+
313346
const surface = surfaceRef.current;
314347
surface.handleInteraction(interaction);
315348

packages/react-devtools-scheduling-profiler/src/view-base/HorizontalPanAndZoomView.js

Lines changed: 35 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ import type {
1414
MouseUpInteraction,
1515
WheelPlainInteraction,
1616
WheelWithShiftInteraction,
17-
WheelWithControlInteraction,
18-
WheelWithMetaInteraction,
1917
} from './useCanvasInteraction';
2018
import type {Rect} from './geometry';
2119
import type {ScrollState} from './utils/scrollState';
@@ -202,7 +200,7 @@ export class HorizontalPanAndZoomView extends View {
202200
}
203201
}
204202

205-
_handleWheelPlain(interaction: WheelPlainInteraction) {
203+
_handleWheel(interaction: WheelPlainInteraction | WheelWithShiftInteraction) {
206204
const {
207205
location,
208206
delta: {deltaX, deltaY},
@@ -214,51 +212,41 @@ export class HorizontalPanAndZoomView extends View {
214212

215213
const absDeltaX = Math.abs(deltaX);
216214
const absDeltaY = Math.abs(deltaY);
217-
if (absDeltaY > absDeltaX) {
218-
return; // Scrolling vertically
219-
}
220-
if (absDeltaX < MOVE_WHEEL_DELTA_THRESHOLD) {
221-
return;
222-
}
223-
224-
const newState = translateState({
225-
state: this._scrollState,
226-
delta: -deltaX,
227-
containerLength: this.frame.size.width,
228-
});
229-
this._setStateAndInformCallbacksIfChanged(newState);
230-
}
231-
232-
_handleWheelZoom(
233-
interaction:
234-
| WheelWithShiftInteraction
235-
| WheelWithControlInteraction
236-
| WheelWithMetaInteraction,
237-
) {
238-
const {
239-
location,
240-
delta: {deltaY},
241-
} = interaction.payload;
242215

243-
if (!rectContainsPoint(location, this.frame)) {
244-
return; // Not scrolling on view
245-
}
246-
247-
const absDeltaY = Math.abs(deltaY);
248-
if (absDeltaY < MOVE_WHEEL_DELTA_THRESHOLD) {
249-
return;
216+
// Vertical scrolling zooms in and out (unless the SHIFT modifier is used).
217+
// Horizontal scrolling pans.
218+
if (absDeltaY > absDeltaX) {
219+
if (absDeltaY < MOVE_WHEEL_DELTA_THRESHOLD) {
220+
return;
221+
}
222+
223+
if (interaction.type === 'wheel-shift') {
224+
// Shift modifier is for scrolling, not zooming.
225+
return;
226+
}
227+
228+
const newState = zoomState({
229+
state: this._scrollState,
230+
multiplier: 1 + 0.005 * -deltaY,
231+
fixedPoint: location.x - this._scrollState.offset,
232+
233+
minContentLength: this._intrinsicContentWidth * MIN_ZOOM_LEVEL,
234+
maxContentLength: this._intrinsicContentWidth * MAX_ZOOM_LEVEL,
235+
containerLength: this.frame.size.width,
236+
});
237+
this._setStateAndInformCallbacksIfChanged(newState);
238+
} else {
239+
if (absDeltaX < MOVE_WHEEL_DELTA_THRESHOLD) {
240+
return;
241+
}
242+
243+
const newState = translateState({
244+
state: this._scrollState,
245+
delta: -deltaX,
246+
containerLength: this.frame.size.width,
247+
});
248+
this._setStateAndInformCallbacksIfChanged(newState);
250249
}
251-
252-
const newState = zoomState({
253-
state: this._scrollState,
254-
multiplier: 1 + 0.005 * -deltaY,
255-
fixedPoint: location.x - this._scrollState.offset,
256-
257-
minContentLength: this._intrinsicContentWidth * MIN_ZOOM_LEVEL,
258-
maxContentLength: this._intrinsicContentWidth * MAX_ZOOM_LEVEL,
259-
containerLength: this.frame.size.width,
260-
});
261-
this._setStateAndInformCallbacksIfChanged(newState);
262250
}
263251

264252
handleInteraction(interaction: Interaction, viewRefs: ViewRefs) {
@@ -273,12 +261,8 @@ export class HorizontalPanAndZoomView extends View {
273261
this._handleMouseUp(interaction, viewRefs);
274262
break;
275263
case 'wheel-plain':
276-
this._handleWheelPlain(interaction);
277-
break;
278264
case 'wheel-shift':
279-
case 'wheel-control':
280-
case 'wheel-meta':
281-
this._handleWheelZoom(interaction);
265+
this._handleWheel(interaction);
282266
break;
283267
}
284268
}

packages/react-devtools-scheduling-profiler/src/view-base/ResizableView.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ class ResizeBar extends View {
216216

217217
export class ResizableView extends View {
218218
_canvasRef: {current: HTMLCanvasElement | null};
219-
_didDrag: boolean = false;
220219
_layoutState: LayoutState;
221220
_resizeBar: ResizeBar;
222221
_resizingState: ResizingState | null = null;
@@ -327,11 +326,6 @@ export class ResizableView extends View {
327326
}
328327

329328
_handleClick(interaction: ClickInteraction) {
330-
if (this._didDrag) {
331-
// Ignore click events that come after drag-to-resize.
332-
return;
333-
}
334-
335329
const cursorInView = rectContainsPoint(
336330
interaction.payload.location,
337331
this.frame,
@@ -364,7 +358,6 @@ export class ResizableView extends View {
364358
const cursorLocation = interaction.payload.location;
365359
const resizeBarFrame = this._resizeBar.frame;
366360
if (rectContainsPoint(cursorLocation, resizeBarFrame)) {
367-
this._didDrag = false;
368361
const mouseY = cursorLocation.y;
369362
this._resizingState = {
370363
cursorOffsetInBarFrame: mouseY - resizeBarFrame.origin.y,
@@ -376,7 +369,6 @@ export class ResizableView extends View {
376369
_handleMouseMove(interaction: MouseMoveInteraction) {
377370
const {_resizingState} = this;
378371
if (_resizingState) {
379-
this._didDrag = true;
380372
this._resizingState = {
381373
..._resizingState,
382374
mouseY: interaction.payload.location.y,

packages/react-devtools-scheduling-profiler/src/view-base/VerticalScrollView.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type {
1212
MouseDownInteraction,
1313
MouseMoveInteraction,
1414
MouseUpInteraction,
15-
WheelPlainInteraction,
15+
WheelWithShiftInteraction,
1616
} from './useCanvasInteraction';
1717
import type {Rect} from './geometry';
1818
import type {ScrollState} from './utils/scrollState';
@@ -157,7 +157,7 @@ export class VerticalScrollView extends View {
157157
}
158158
}
159159

160-
_handleWheelPlain(interaction: WheelPlainInteraction) {
160+
_handleWheelShift(interaction: WheelWithShiftInteraction) {
161161
const {
162162
location,
163163
delta: {deltaX, deltaY},
@@ -195,8 +195,8 @@ export class VerticalScrollView extends View {
195195
case 'mouseup':
196196
this._handleMouseUp(interaction);
197197
break;
198-
case 'wheel-plain':
199-
this._handleWheelPlain(interaction);
198+
case 'wheel-shift':
199+
this._handleWheelShift(interaction);
200200
break;
201201
}
202202
}

packages/react-devtools-scheduling-profiler/src/view-base/useCanvasInteraction.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import type {NormalizedWheelDelta} from './utils/normalizeWheel';
1111
import type {Point} from './geometry';
1212

13-
import {useEffect} from 'react';
13+
import {useEffect, useRef} from 'react';
1414
import {normalizeWheel} from './utils/normalizeWheel';
1515

1616
export type ClickInteraction = {|
@@ -115,6 +115,9 @@ export function useCanvasInteraction(
115115
canvasRef: {|current: HTMLCanvasElement | null|},
116116
interactor: (interaction: Interaction) => void,
117117
) {
118+
const isMouseDownRef = useRef<boolean>(false);
119+
const didMouseMoveWhileDownRef = useRef<boolean>(false);
120+
118121
useEffect(() => {
119122
const canvas = canvasRef.current;
120123
if (!canvas) {
@@ -130,6 +133,10 @@ export function useCanvasInteraction(
130133
}
131134

132135
const onCanvasClick: MouseEventHandler = event => {
136+
if (didMouseMoveWhileDownRef.current) {
137+
return;
138+
}
139+
133140
interactor({
134141
type: 'click',
135142
payload: {
@@ -140,6 +147,10 @@ export function useCanvasInteraction(
140147
};
141148

142149
const onCanvasDoubleClick: MouseEventHandler = event => {
150+
if (didMouseMoveWhileDownRef.current) {
151+
return;
152+
}
153+
143154
interactor({
144155
type: 'double-click',
145156
payload: {
@@ -150,6 +161,9 @@ export function useCanvasInteraction(
150161
};
151162

152163
const onCanvasMouseDown: MouseEventHandler = event => {
164+
didMouseMoveWhileDownRef.current = false;
165+
isMouseDownRef.current = true;
166+
153167
interactor({
154168
type: 'mousedown',
155169
payload: {
@@ -160,6 +174,10 @@ export function useCanvasInteraction(
160174
};
161175

162176
const onDocumentMouseMove: MouseEventHandler = event => {
177+
if (isMouseDownRef.current) {
178+
didMouseMoveWhileDownRef.current = true;
179+
}
180+
163181
interactor({
164182
type: 'mousemove',
165183
payload: {
@@ -170,6 +188,8 @@ export function useCanvasInteraction(
170188
};
171189

172190
const onDocumentMouseUp: MouseEventHandler = event => {
191+
isMouseDownRef.current = false;
192+
173193
interactor({
174194
type: 'mouseup',
175195
payload: {

0 commit comments

Comments
 (0)