mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 19:34:01 +00:00
feat(data): an own-rule selection owner keeps its whole old click handler
Vessels' click rule (sibling ownership, cyclone background, card hit test, unkeyed records) does not map onto the plain or look-under rules: an owner with onClick(ctx) gets every click with the top pick, no gesture rule (its old LEFT_CLICK handler), and is another layer to the rest.
This commit is contained in:
1 parent
6eec8f6cb0
commit
6b27b21cc4
2 files changed
+61
-2
No files matched your search
@@ -20,6 +20,10 @@
|
|||||||
// nothing, is empty space for it (it releases its selection); a click that
|
// nothing, is empty space for it (it releases its selection); a click that
|
||||||
// only meets what it looks under does nothing; no gesture rule (its old
|
// only meets what it looks under does nothing; no gesture rule (its old
|
||||||
// handler took every click). To the others it is another layer.
|
// handler took every click). To the others it is another layer.
|
||||||
|
// An own-rule owner (`onClick(ctx)`: vessels) keeps its whole old click
|
||||||
|
// handler: it gets every click with the top pick and decides itself (no
|
||||||
|
// gesture rule, as its old LEFT_CLICK handler); to the others it is another
|
||||||
|
// layer.
|
||||||
|
|
||||||
import { isPointerFree as pointerFree } from './inputOwnership.js';
|
import { isPointerFree as pointerFree } from './inputOwnership.js';
|
||||||
import {
|
import {
|
||||||
@@ -104,7 +108,9 @@ export function createSelectionDispatcher(
|
|||||||
}
|
}
|
||||||
return lookedUnder ? 'under' : null;
|
return lookedUnder ? 'under' : null;
|
||||||
};
|
};
|
||||||
const plain = (owner) => typeof owner.lookUnder !== 'function';
|
const ownRule = (owner) => typeof owner.onClick === 'function';
|
||||||
|
const plain = (owner) =>
|
||||||
|
typeof owner.lookUnder !== 'function' && !ownRule(owner);
|
||||||
|
|
||||||
const onClick = (event) => {
|
const onClick = (event) => {
|
||||||
if (press) finish(event.position);
|
if (press) finish(event.position);
|
||||||
@@ -119,6 +125,15 @@ export function createSelectionDispatcher(
|
|||||||
};
|
};
|
||||||
for (const [name, owner] of [...owners]) {
|
for (const [name, owner] of [...owners]) {
|
||||||
if (plain(owner)) continue;
|
if (plain(owner)) continue;
|
||||||
|
if (ownRule(owner)) {
|
||||||
|
// Its old handler ran alone: a throw there leaves the others be.
|
||||||
|
try {
|
||||||
|
owner.onClick(ctx);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const target = lookUnderTarget(name, owner, event);
|
const target = lookUnderTarget(name, owner, event);
|
||||||
if (target === 'under') continue;
|
if (target === 'under') continue;
|
||||||
if (target && target !== 'other')
|
if (target && target !== 'other')
|
||||||
@@ -205,7 +220,7 @@ export function createSelectionDispatcher(
|
|||||||
* @param {string} name the owning layer's id
|
* @param {string} name the owning layer's id
|
||||||
* @param {{ owns: (id: string) => boolean, onSelect?: Function, onEmptyClick?: Function,
|
* @param {{ owns: (id: string) => boolean, onSelect?: Function, onEmptyClick?: Function,
|
||||||
* onEscape?: Function, passThrough?: (picked: object) => boolean, drillThrough?: boolean,
|
* onEscape?: Function, passThrough?: (picked: object) => boolean, drillThrough?: boolean,
|
||||||
* lookUnder?: (id: string) => boolean }} owner
|
* lookUnder?: (id: string) => boolean, onClick?: (ctx: object) => void }} owner
|
||||||
* @returns {() => void} unregister
|
* @returns {() => void} unregister
|
||||||
*/
|
*/
|
||||||
register(name, owner) {
|
register(name, owner) {
|
||||||
|
|||||||
@@ -256,3 +256,47 @@ test('a look-under owner (local ADS-B) keeps its own click rule beside the other
|
|||||||
unregisterPickOwner('cctv');
|
unregisterPickOwner('cctv');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('an own-rule owner (vessels) gets every click with its top pick and is another layer to the rest', () => {
|
||||||
|
const { dispatcher, click, escape } = setup({
|
||||||
|
10: [{ id: { mmsi: '111' } }], // its own object (Cesium: the record)
|
||||||
|
20: [{ id: 'ae01ce' }], // flights' contact
|
||||||
|
30: [], // empty map
|
||||||
|
});
|
||||||
|
const seen = [];
|
||||||
|
const flights = recorder();
|
||||||
|
let owned = true;
|
||||||
|
dispatcher.register('ais-live-vessels', {
|
||||||
|
owns: (id) => owned && id === '111',
|
||||||
|
onClick: (ctx) =>
|
||||||
|
seen.push([ctx.position.x, ctx.picked?.id ?? null, ctx.gesture.travelPx]),
|
||||||
|
});
|
||||||
|
dispatcher.register('flights', {
|
||||||
|
owns: (id) => id === 'ae01ce',
|
||||||
|
...flights.handlers,
|
||||||
|
});
|
||||||
|
click(10);
|
||||||
|
click(20);
|
||||||
|
click(30);
|
||||||
|
// No gesture rule: a long press and a drag still reach it (LEFT_CLICK).
|
||||||
|
click(30, { ms: 900 });
|
||||||
|
click(30, { travel: 40 });
|
||||||
|
escape();
|
||||||
|
assert.deepEqual(seen, [
|
||||||
|
[10, { mmsi: '111' }, 0],
|
||||||
|
[20, 'ae01ce', 0],
|
||||||
|
[30, null, 0],
|
||||||
|
[30, null, 0],
|
||||||
|
[70, null, 40],
|
||||||
|
]);
|
||||||
|
// To flights a vessel is another layer's object: not its empty space.
|
||||||
|
assert.deepEqual(flights.calls, [
|
||||||
|
['select', 'ae01ce', undefined],
|
||||||
|
['empty', 0],
|
||||||
|
['escape'],
|
||||||
|
]);
|
||||||
|
// A disowned vessel pick (the layer disabled) is empty space again.
|
||||||
|
owned = false;
|
||||||
|
click(10);
|
||||||
|
assert.deepEqual(flights.calls.at(-1), ['empty', 0]);
|
||||||
|
});
|
||||||
Reference in new issue
Block a user