Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up hover handling #4081

Merged
merged 1 commit into from
Jan 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions modules/core/src/lib/deck-picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import GL from '@luma.gl/constants';
import assert from '../utils/assert';
import PickLayersPass from '../passes/pick-layers-pass';
import {getClosestObject, getUniqueObjects} from './picking/query-object';
import {processPickInfo, callLayerPickingCallbacks, getLayerPickingInfo} from './picking/pick-info';
import {processPickInfo, getLayerPickingInfo} from './picking/pick-info';

export default class DeckPicker {
constructor(gl) {
Expand Down Expand Up @@ -125,7 +125,6 @@ export default class DeckPicker {
radius = 0,
depth = 1,
mode = 'query',
event,
unproject3D,
onViewportActive
}) {
Expand Down Expand Up @@ -213,10 +212,10 @@ export default class DeckPicker {
pixelRatio
});

const processedPickInfos = callLayerPickingCallbacks(infos, mode, event);

if (processedPickInfos) {
processedPickInfos.forEach(info => result.push(info));
for (const info of infos.values()) {
if (info.layer) {
result.push(info);
}
}

// If no object is picked stop.
Expand Down
24 changes: 16 additions & 8 deletions modules/core/src/lib/deck.js
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,6 @@ export default class Deck {
this.layerManager.context.mousePosition = {x: _pickRequest.x, y: _pickRequest.y};
}

_pickRequest.callback = this.props.onHover;
_pickRequest.event = event;
_pickRequest.mode = 'hover';
}
Expand All @@ -541,19 +540,28 @@ export default class Deck {
_pickAndCallback() {
const {_pickRequest} = this;

if (_pickRequest.mode) {
// perform picking
if (_pickRequest.event) {
// Perform picking
const {result, emptyInfo} = this._pick('pickObject', 'pickObject Time', _pickRequest);
const shouldGenerateInfo = _pickRequest.callback || this.props.getTooltip;
const pickedInfo = shouldGenerateInfo && (result.find(info => info.index >= 0) || emptyInfo);
const pickedInfo = result[0] || emptyInfo;

// Update tooltip
if (this.props.getTooltip) {
const displayInfo = this.props.getTooltip(pickedInfo);
this.tooltip.setTooltip(displayInfo, pickedInfo.x, pickedInfo.y);
}
if (_pickRequest.callback && !pickedInfo.handled) {
_pickRequest.callback(pickedInfo, _pickRequest.event);

// Execute callbacks
let handled = false;
if (pickedInfo.layer) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does it decide whether should call onHover or onClick to handle picking here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_pickRequest is only used for throttling hover events. Click is handled immediately in onPointerDown.

handled = pickedInfo.layer.onHover(pickedInfo, _pickRequest.event);
}
if (!handled && this.props.onHover) {
this.props.onHover(pickedInfo, _pickRequest.event);
}
_pickRequest.mode = null;

// Clear pending pickRequest
_pickRequest.event = null;
}
}

Expand Down
32 changes: 0 additions & 32 deletions modules/core/src/lib/picking/pick-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,35 +149,3 @@ function getViewportFromCoordinates({viewports}) {
const viewport = viewports[0];
return viewport;
}

// Per-layer event handlers (e.g. onClick, onHover) are provided by the
// user and out of deck.gl's control. It's very much possible that
// the user calls React lifecycle methods in these function, such as
// ReactComponent.setState(). React lifecycle methods sometimes induce
// a re-render and re-generation of props of deck.gl and its layers,
// which invalidates all layers currently passed to this very function.

// Therefore, per-layer event handlers must be invoked at the end
// of the picking operation. NO operation that relies on the states of current
// layers should be called after this code.
export function callLayerPickingCallbacks(infos, mode, event) {
const unhandledPickInfos = [];

infos.forEach(info => {
if (!info.layer) {
return;
}

switch (mode) {
case 'hover':
info.handled = info.layer.onHover(info, event);
break;
case 'query':
default:
}

unhandledPickInfos.push(info);
});

return unhandledPickInfos;
}