Scheduling profiler: UX tweaks (#21971)

This commit is contained in:
Brian Vaughn
2021-07-27 14:34:05 -04:00
committed by GitHub
parent 87239321b0
commit d95434082f
10 changed files with 75 additions and 156 deletions
@@ -507,7 +507,7 @@ function AutoSizedCanvas({data, height, width}: AutoSizedCanvasProps) {
);
}}
</ContextMenu>
{!isContextMenuShown && (
{!isContextMenuShown && !surfaceRef.current.hasActiveView() && (
<EventTooltip
data={data}
hoveredEvent={hoveredEvent}
@@ -17,7 +17,7 @@ import type {
MouseMoveInteraction,
Rect,
Size,
ViewRef,
ViewRefs,
} from '../view-base';
import {
@@ -246,11 +246,7 @@ class FlamechartStackLayerView extends View {
/**
* @private
*/
_handleMouseMove(
interaction: MouseMoveInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
_handleMouseMove(interaction: MouseMoveInteraction, viewRefs: ViewRefs) {
const {_stackLayer, frame, _intrinsicSize, _onHover, visibleArea} = this;
const {location} = interaction.payload;
if (!_onHover || !rectContainsPoint(location, visibleArea)) {
@@ -270,7 +266,7 @@ class FlamechartStackLayerView extends View {
const x = Math.floor(timestampToPosition(timestamp, scaleFactor, frame));
if (x <= location.x && x + width >= location.x) {
this.currentCursor = 'pointer';
hoveredViewRef.current = this;
viewRefs.hoveredView = this;
_onHover(flamechartStackFrame);
return;
}
@@ -287,14 +283,10 @@ class FlamechartStackLayerView extends View {
_didGrab: boolean = false;
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
handleInteraction(interaction: Interaction, viewRefs: ViewRefs) {
switch (interaction.type) {
case 'mousemove':
this._handleMouseMove(interaction, activeViewRef, hoveredViewRef);
this._handleMouseMove(interaction, viewRefs);
break;
}
}
@@ -13,7 +13,7 @@ import type {
MouseMoveInteraction,
Rect,
Size,
ViewRef,
ViewRefs,
} from '../view-base';
import {
@@ -255,11 +255,7 @@ export class NativeEventsView extends View {
/**
* @private
*/
_handleMouseMove(
interaction: MouseMoveInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
_handleMouseMove(interaction: MouseMoveInteraction, viewRefs: ViewRefs) {
const {frame, _intrinsicSize, onHover, visibleArea} = this;
if (!onHover) {
return;
@@ -290,7 +286,7 @@ export class NativeEventsView extends View {
) {
this.currentCursor = 'pointer';
hoveredViewRef.current = this;
viewRefs.hoveredView = this;
onHover(nativeEvent);
return;
@@ -301,14 +297,10 @@ export class NativeEventsView extends View {
onHover(null);
}
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
handleInteraction(interaction: Interaction, viewRefs: ViewRefs) {
switch (interaction.type) {
case 'mousemove':
this._handleMouseMove(interaction, activeViewRef, hoveredViewRef);
this._handleMouseMove(interaction, viewRefs);
break;
}
}
@@ -13,7 +13,7 @@ import type {
MouseMoveInteraction,
Rect,
Size,
ViewRef,
ViewRefs,
} from '../view-base';
import {
@@ -231,11 +231,7 @@ export class ReactEventsView extends View {
/**
* @private
*/
_handleMouseMove(
interaction: MouseMoveInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
_handleMouseMove(interaction: MouseMoveInteraction, viewRefs: ViewRefs) {
const {frame, onHover, visibleArea} = this;
if (!onHover) {
return;
@@ -271,7 +267,7 @@ export class ReactEventsView extends View {
hoverTimestamp <= timestamp + eventTimestampAllowance
) {
this.currentCursor = 'pointer';
hoveredViewRef.current = this;
viewRefs.hoveredView = this;
onHover(event);
return;
}
@@ -280,14 +276,10 @@ export class ReactEventsView extends View {
onHover(null);
}
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
handleInteraction(interaction: Interaction, viewRefs: ViewRefs) {
switch (interaction.type) {
case 'mousemove':
this._handleMouseMove(interaction, activeViewRef, hoveredViewRef);
this._handleMouseMove(interaction, viewRefs);
break;
}
}
@@ -13,7 +13,7 @@ import type {
MouseMoveInteraction,
Rect,
Size,
ViewRef,
ViewRefs,
} from '../view-base';
import {
@@ -256,11 +256,7 @@ export class ReactMeasuresView extends View {
/**
* @private
*/
_handleMouseMove(
interaction: MouseMoveInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
_handleMouseMove(interaction: MouseMoveInteraction, viewRefs: ViewRefs) {
const {
frame,
_intrinsicSize,
@@ -311,7 +307,7 @@ export class ReactMeasuresView extends View {
hoverTimestamp <= timestamp + duration
) {
this.currentCursor = 'pointer';
hoveredViewRef.current = this;
viewRefs.hoveredView = this;
onHover(measure);
return;
}
@@ -320,14 +316,10 @@ export class ReactMeasuresView extends View {
onHover(null);
}
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
handleInteraction(interaction: Interaction, viewRefs: ViewRefs) {
switch (interaction.type) {
case 'mousemove':
this._handleMouseMove(interaction, activeViewRef, hoveredViewRef);
this._handleMouseMove(interaction, viewRefs);
break;
}
}
@@ -13,7 +13,7 @@ import type {
MouseMoveInteraction,
Rect,
Size,
ViewRef,
ViewRefs,
} from '../view-base';
import {
@@ -191,11 +191,7 @@ export class UserTimingMarksView extends View {
/**
* @private
*/
_handleMouseMove(
interaction: MouseMoveInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
_handleMouseMove(interaction: MouseMoveInteraction, viewRefs: ViewRefs) {
const {frame, onHover, visibleArea} = this;
if (!onHover) {
return;
@@ -229,7 +225,7 @@ export class UserTimingMarksView extends View {
hoverTimestamp <= timestamp + markTimestampAllowance
) {
this.currentCursor = 'pointer';
hoveredViewRef.current = this;
viewRefs.hoveredView = this;
onHover(mark);
return;
}
@@ -238,14 +234,10 @@ export class UserTimingMarksView extends View {
onHover(null);
}
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
handleInteraction(interaction: Interaction, viewRefs: ViewRefs) {
switch (interaction.type) {
case 'mousemove':
this._handleMouseMove(interaction, activeViewRef, hoveredViewRef);
this._handleMouseMove(interaction, viewRefs);
break;
}
}
@@ -19,7 +19,7 @@ import type {
} from './useCanvasInteraction';
import type {Rect} from './geometry';
import type {ScrollState} from './utils/scrollState';
import type {ViewRef} from './Surface';
import type {ViewRefs} from './Surface';
import {Surface} from './Surface';
import {View} from './View';
@@ -156,34 +156,26 @@ export class HorizontalPanAndZoomView extends View {
this._setScrollState(newState);
}
_handleMouseDown(
interaction: MouseDownInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
_handleMouseDown(interaction: MouseDownInteraction, viewRefs: ViewRefs) {
if (rectContainsPoint(interaction.payload.location, this.frame)) {
this._isPanning = true;
activeViewRef.current = this;
viewRefs.activeView = this;
this.currentCursor = 'grabbing';
}
}
_handleMouseMove(
interaction: MouseMoveInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
_handleMouseMove(interaction: MouseMoveInteraction, viewRefs: ViewRefs) {
const isHovered = rectContainsPoint(
interaction.payload.location,
this.frame,
);
if (isHovered) {
hoveredViewRef.current = this;
viewRefs.hoveredView = this;
}
if (activeViewRef.current === this) {
if (viewRefs.activeView === this) {
this.currentCursor = 'grabbing';
} else if (isHovered) {
this.currentCursor = 'grab';
@@ -200,17 +192,13 @@ export class HorizontalPanAndZoomView extends View {
this._setStateAndInformCallbacksIfChanged(newState);
}
_handleMouseUp(
interaction: MouseUpInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
_handleMouseUp(interaction: MouseUpInteraction, viewRefs: ViewRefs) {
if (this._isPanning) {
this._isPanning = false;
}
if (activeViewRef.current === this) {
activeViewRef.current = null;
if (viewRefs.activeView === this) {
viewRefs.activeView = null;
}
}
@@ -273,20 +261,16 @@ export class HorizontalPanAndZoomView extends View {
this._setStateAndInformCallbacksIfChanged(newState);
}
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
handleInteraction(interaction: Interaction, viewRefs: ViewRefs) {
switch (interaction.type) {
case 'mousedown':
this._handleMouseDown(interaction, activeViewRef, hoveredViewRef);
this._handleMouseDown(interaction, viewRefs);
break;
case 'mousemove':
this._handleMouseMove(interaction, activeViewRef, hoveredViewRef);
this._handleMouseMove(interaction, viewRefs);
break;
case 'mouseup':
this._handleMouseUp(interaction, activeViewRef, hoveredViewRef);
this._handleMouseUp(interaction, viewRefs);
break;
case 'wheel-plain':
this._handleWheelPlain(interaction);
@@ -14,7 +14,7 @@ import type {
MouseUpInteraction,
} from './useCanvasInteraction';
import type {Rect, Size} from './geometry';
import type {ViewRef} from './Surface';
import type {ViewRefs} from './Surface';
import {COLORS} from '../content-views/constants';
import nullthrows from 'nullthrows';
@@ -83,36 +83,28 @@ class ResizeBar extends View {
this._updateColor();
}
_handleMouseDown(
interaction: MouseDownInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
_handleMouseDown(interaction: MouseDownInteraction, viewRefs: ViewRefs) {
const cursorInView = rectContainsPoint(
interaction.payload.location,
this.frame,
);
if (cursorInView) {
this._setInteractionState('dragging');
activeViewRef.current = this;
viewRefs.activeView = this;
}
}
_handleMouseMove(
interaction: MouseMoveInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
_handleMouseMove(interaction: MouseMoveInteraction, viewRefs: ViewRefs) {
const cursorInView = rectContainsPoint(
interaction.payload.location,
this.frame,
);
if (cursorInView || activeViewRef.current === this) {
if (cursorInView || viewRefs.activeView === this) {
this.currentCursor = 'ns-resize';
}
if (cursorInView) {
hoveredViewRef.current = this;
viewRefs.hoveredView = this;
}
if (this._interactionState === 'dragging') {
@@ -121,11 +113,7 @@ class ResizeBar extends View {
this._setInteractionState(cursorInView ? 'hovered' : 'normal');
}
_handleMouseUp(
interaction: MouseUpInteraction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
_handleMouseUp(interaction: MouseUpInteraction, viewRefs: ViewRefs) {
const cursorInView = rectContainsPoint(
interaction.payload.location,
this.frame,
@@ -134,25 +122,21 @@ class ResizeBar extends View {
this._setInteractionState(cursorInView ? 'hovered' : 'normal');
}
if (activeViewRef.current === this) {
activeViewRef.current = null;
if (viewRefs.activeView === this) {
viewRefs.activeView = null;
}
}
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
handleInteraction(interaction: Interaction, viewRefs: ViewRefs) {
switch (interaction.type) {
case 'mousedown':
this._handleMouseDown(interaction, activeViewRef, hoveredViewRef);
this._handleMouseDown(interaction, viewRefs);
return;
case 'mousemove':
this._handleMouseMove(interaction, activeViewRef, hoveredViewRef);
this._handleMouseMove(interaction, viewRefs);
return;
case 'mouseup':
this._handleMouseUp(interaction, activeViewRef, hoveredViewRef);
this._handleMouseUp(interaction, viewRefs);
return;
}
}
@@ -339,11 +323,7 @@ export class ResizableSplitView extends View {
}
}
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {
handleInteraction(interaction: Interaction, viewRefs: ViewRefs) {
switch (interaction.type) {
case 'mousedown':
this._handleMouseDown(interaction);
@@ -10,13 +10,15 @@
import type {Interaction} from './useCanvasInteraction';
import type {Size} from './geometry';
import {createRef} from 'react';
import memoize from 'memoize-one';
import {View} from './View';
import {zeroPoint} from './geometry';
export type ViewRef = {|current: View | null|};
export type ViewRefs = {|
activeView: View | null,
hoveredView: View | null,
|};
// hidpi canvas: https://www.html5rocks.com/en/tutorials/canvas/hidpi/
function configureRetinaCanvas(canvas, height, width) {
@@ -55,8 +57,14 @@ export class Surface {
_context: ?CanvasRenderingContext2D;
_canvasSize: ?Size;
_activeViewRef: ViewRef = createRef();
_hoveredViewRef: ViewRef = createRef();
_viewRefs: ViewRefs = {
activeView: null,
hoveredView: null,
};
hasActiveView(): boolean {
return this._viewRefs.activeView !== null;
}
setCanvas(canvas: HTMLCanvasElement, canvasSize: Size) {
this._context = getCanvasContext(
@@ -88,17 +96,14 @@ export class Surface {
}
getCurrentCursor(): string | null {
const activeView = this._activeViewRef.current;
const {activeView, hoveredView} = this._viewRefs;
if (activeView !== null) {
return activeView.currentCursor;
} else if (hoveredView !== null) {
return hoveredView.currentCursor;
} else {
const hoveredView = this._hoveredViewRef.current;
if (hoveredView !== null) {
return hoveredView.currentCursor;
}
return null;
}
return null;
}
handleInteraction(interaction: Interaction) {
@@ -107,8 +112,7 @@ export class Surface {
}
this.rootView.handleInteractionAndPropagateToSubviews(
interaction,
this._activeViewRef,
this._hoveredViewRef,
this._viewRefs,
);
}
}
@@ -10,7 +10,7 @@
import type {Interaction} from './useCanvasInteraction';
import type {Rect, Size} from './geometry';
import type {Layouter} from './layouter';
import type {ViewRef} from './Surface';
import type {ViewRefs} from './Surface';
import {Surface} from './Surface';
import {
@@ -256,11 +256,7 @@ export class View {
// Internal note: Do not call directly! Use
// `handleInteractionAndPropagateToSubviews` so that interactions are
// propagated to subviews.
handleInteraction(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
) {}
handleInteraction(interaction: Interaction, viewRefs: ViewRefs) {}
/**
* Handle an `interaction` and propagates it to all of this view's
@@ -274,16 +270,11 @@ export class View {
*/
handleInteractionAndPropagateToSubviews(
interaction: Interaction,
activeViewRef: ViewRef,
hoveredViewRef: ViewRef,
viewRefs: ViewRefs,
) {
this.handleInteraction(interaction, activeViewRef, hoveredViewRef);
this.handleInteraction(interaction, viewRefs);
this.subviews.forEach(subview =>
subview.handleInteractionAndPropagateToSubviews(
interaction,
activeViewRef,
hoveredViewRef,
),
subview.handleInteractionAndPropagateToSubviews(interaction, viewRefs),
);
}
}