Skip to content

Commit

Permalink
Sceduling profiler: Added custom view cursors (#21970)
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Vaughn authored Jul 27, 2021
1 parent 4cc8ec6 commit 8723932
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 55 deletions.
10 changes: 8 additions & 2 deletions packages/react-devtools-scheduling-profiler/src/CanvasPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,16 @@ function AutoSizedCanvas({data, height, width}: AutoSizedCanvasProps) {
}, [width, height]);

const interactor = useCallback(interaction => {
if (canvasRef.current === null) {
const canvas = canvasRef.current;
if (canvas === null) {
return;
}
surfaceRef.current.handleInteraction(interaction);

const surface = surfaceRef.current;
surface.handleInteraction(interaction);

canvas.style.cursor = surface.getCurrentCursor() || 'default';

// Defer drawing to canvas until React's commit phase, to avoid drawing
// twice and to ensure that both the canvas and DOM elements managed by
// React are in sync.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ import type {
FlamechartStackFrame,
FlamechartStackLayer,
} from '../types';
import type {Interaction, MouseMoveInteraction, Rect, Size} from '../view-base';
import type {
Interaction,
MouseMoveInteraction,
Rect,
Size,
ViewRef,
} from '../view-base';

import {
ColorView,
Expand Down Expand Up @@ -240,7 +246,11 @@ class FlamechartStackLayerView extends View {
/**
* @private
*/
_handleMouseMove(interaction: MouseMoveInteraction) {
_handleMouseMove(
interaction: MouseMoveInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
const {_stackLayer, frame, _intrinsicSize, _onHover, visibleArea} = this;
const {location} = interaction.payload;
if (!_onHover || !rectContainsPoint(location, visibleArea)) {
Expand All @@ -259,6 +269,8 @@ class FlamechartStackLayerView extends View {
const width = durationToWidth(duration, scaleFactor);
const x = Math.floor(timestampToPosition(timestamp, scaleFactor, frame));
if (x <= location.x && x + width >= location.x) {
this.currentCursor = 'pointer';
hoveredViewRef.current = this;
_onHover(flamechartStackFrame);
return;
}
Expand All @@ -273,10 +285,16 @@ class FlamechartStackLayerView extends View {
_onHover(null);
}

handleInteraction(interaction: Interaction) {
_didGrab: boolean = false;

handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
switch (interaction.type) {
case 'mousemove':
this._handleMouseMove(interaction);
this._handleMouseMove(interaction, activeViewRef, hoveredViewRef);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
*/

import type {NativeEvent, ReactProfilerData} from '../types';
import type {Interaction, MouseMoveInteraction, Rect, Size} from '../view-base';
import type {
Interaction,
MouseMoveInteraction,
Rect,
Size,
ViewRef,
} from '../view-base';

import {
durationToWidth,
Expand Down Expand Up @@ -72,7 +78,6 @@ export class NativeEventsView extends View {
this._profilerData = profilerData;

this._performPreflightComputations();
console.log(this._depthToNativeEvent);
}

_performPreflightComputations() {
Expand Down Expand Up @@ -250,7 +255,11 @@ export class NativeEventsView extends View {
/**
* @private
*/
_handleMouseMove(interaction: MouseMoveInteraction) {
_handleMouseMove(
interaction: MouseMoveInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
const {frame, _intrinsicSize, onHover, visibleArea} = this;
if (!onHover) {
return;
Expand Down Expand Up @@ -279,6 +288,10 @@ export class NativeEventsView extends View {
hoverTimestamp >= timestamp &&
hoverTimestamp <= timestamp + duration
) {
this.currentCursor = 'pointer';

hoveredViewRef.current = this;

onHover(nativeEvent);
return;
}
Expand All @@ -288,10 +301,14 @@ export class NativeEventsView extends View {
onHover(null);
}

handleInteraction(interaction: Interaction) {
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
switch (interaction.type) {
case 'mousemove':
this._handleMouseMove(interaction);
this._handleMouseMove(interaction, activeViewRef, hoveredViewRef);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
*/

import type {ReactEvent, ReactProfilerData} from '../types';
import type {Interaction, MouseMoveInteraction, Rect, Size} from '../view-base';
import type {
Interaction,
MouseMoveInteraction,
Rect,
Size,
ViewRef,
} from '../view-base';

import {
positioningScaleFactor,
Expand Down Expand Up @@ -225,7 +231,11 @@ export class ReactEventsView extends View {
/**
* @private
*/
_handleMouseMove(interaction: MouseMoveInteraction) {
_handleMouseMove(
interaction: MouseMoveInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
const {frame, onHover, visibleArea} = this;
if (!onHover) {
return;
Expand Down Expand Up @@ -260,6 +270,8 @@ export class ReactEventsView extends View {
timestamp - eventTimestampAllowance <= hoverTimestamp &&
hoverTimestamp <= timestamp + eventTimestampAllowance
) {
this.currentCursor = 'pointer';
hoveredViewRef.current = this;
onHover(event);
return;
}
Expand All @@ -268,10 +280,14 @@ export class ReactEventsView extends View {
onHover(null);
}

handleInteraction(interaction: Interaction) {
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
switch (interaction.type) {
case 'mousemove':
this._handleMouseMove(interaction);
this._handleMouseMove(interaction, activeViewRef, hoveredViewRef);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
*/

import type {ReactLane, ReactMeasure, ReactProfilerData} from '../types';
import type {Interaction, MouseMoveInteraction, Rect, Size} from '../view-base';
import type {
Interaction,
MouseMoveInteraction,
Rect,
Size,
ViewRef,
} from '../view-base';

import {
durationToWidth,
Expand Down Expand Up @@ -250,7 +256,11 @@ export class ReactMeasuresView extends View {
/**
* @private
*/
_handleMouseMove(interaction: MouseMoveInteraction) {
_handleMouseMove(
interaction: MouseMoveInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
const {
frame,
_intrinsicSize,
Expand Down Expand Up @@ -300,6 +310,8 @@ export class ReactMeasuresView extends View {
hoverTimestamp >= timestamp &&
hoverTimestamp <= timestamp + duration
) {
this.currentCursor = 'pointer';
hoveredViewRef.current = this;
onHover(measure);
return;
}
Expand All @@ -308,10 +320,14 @@ export class ReactMeasuresView extends View {
onHover(null);
}

handleInteraction(interaction: Interaction) {
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
switch (interaction.type) {
case 'mousemove':
this._handleMouseMove(interaction);
this._handleMouseMove(interaction, activeViewRef, hoveredViewRef);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
*/

import type {UserTimingMark} from '../types';
import type {Interaction, MouseMoveInteraction, Rect, Size} from '../view-base';
import type {
Interaction,
MouseMoveInteraction,
Rect,
Size,
ViewRef,
} from '../view-base';

import {
positioningScaleFactor,
Expand Down Expand Up @@ -185,7 +191,11 @@ export class UserTimingMarksView extends View {
/**
* @private
*/
_handleMouseMove(interaction: MouseMoveInteraction) {
_handleMouseMove(
interaction: MouseMoveInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
const {frame, onHover, visibleArea} = this;
if (!onHover) {
return;
Expand Down Expand Up @@ -218,6 +228,8 @@ export class UserTimingMarksView extends View {
timestamp - markTimestampAllowance <= hoverTimestamp &&
hoverTimestamp <= timestamp + markTimestampAllowance
) {
this.currentCursor = 'pointer';
hoveredViewRef.current = this;
onHover(mark);
return;
}
Expand All @@ -226,10 +238,14 @@ export class UserTimingMarksView extends View {
onHover(null);
}

handleInteraction(interaction: Interaction) {
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
switch (interaction.type) {
case 'mousemove':
this._handleMouseMove(interaction);
this._handleMouseMove(interaction, activeViewRef, hoveredViewRef);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type {
} from './useCanvasInteraction';
import type {Rect} from './geometry';
import type {ScrollState} from './utils/scrollState';
import type {ViewRef} from './Surface';

import {Surface} from './Surface';
import {View} from './View';
Expand Down Expand Up @@ -155,13 +156,39 @@ export class HorizontalPanAndZoomView extends View {
this._setScrollState(newState);
}

_handleMouseDown(interaction: MouseDownInteraction) {
_handleMouseDown(
interaction: MouseDownInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
if (rectContainsPoint(interaction.payload.location, this.frame)) {
this._isPanning = true;

activeViewRef.current = this;

this.currentCursor = 'grabbing';
}
}

_handleMouseMove(interaction: MouseMoveInteraction) {
_handleMouseMove(
interaction: MouseMoveInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
const isHovered = rectContainsPoint(
interaction.payload.location,
this.frame,
);
if (isHovered) {
hoveredViewRef.current = this;
}

if (activeViewRef.current === this) {
this.currentCursor = 'grabbing';
} else if (isHovered) {
this.currentCursor = 'grab';
}

if (!this._isPanning) {
return;
}
Expand All @@ -173,10 +200,18 @@ export class HorizontalPanAndZoomView extends View {
this._setStateAndInformCallbacksIfChanged(newState);
}

_handleMouseUp(interaction: MouseUpInteraction) {
_handleMouseUp(
interaction: MouseUpInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
if (this._isPanning) {
this._isPanning = false;
}

if (activeViewRef.current === this) {
activeViewRef.current = null;
}
}

_handleWheelPlain(interaction: WheelPlainInteraction) {
Expand Down Expand Up @@ -238,16 +273,20 @@ export class HorizontalPanAndZoomView extends View {
this._setStateAndInformCallbacksIfChanged(newState);
}

handleInteraction(interaction: Interaction) {
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
switch (interaction.type) {
case 'mousedown':
this._handleMouseDown(interaction);
this._handleMouseDown(interaction, activeViewRef, hoveredViewRef);
break;
case 'mousemove':
this._handleMouseMove(interaction);
this._handleMouseMove(interaction, activeViewRef, hoveredViewRef);
break;
case 'mouseup':
this._handleMouseUp(interaction);
this._handleMouseUp(interaction, activeViewRef, hoveredViewRef);
break;
case 'wheel-plain':
this._handleWheelPlain(interaction);
Expand Down
Loading

0 comments on commit 8723932

Please sign in to comment.