Add logic to trigger click hats on mouse up on a draggable target

As long as the event was not a drag
This commit is contained in:
Paul Kaplan 2018-10-25 15:08:37 -04:00
parent 9bf7ef8573
commit e002db48f2
2 changed files with 56 additions and 32 deletions
src/io
test/unit

View file

@ -14,21 +14,11 @@ class Mouse {
}
/**
* Activate "event_whenthisspriteclicked" hats if needed.
* @param {number} x X position to be sent to the renderer.
* @param {number} y Y position to be sent to the renderer.
* @param {?bool} wasDragged Whether the click event was the result of
* a drag end.
* Activate "event_whenthisspriteclicked" hats.
* @param {Target} target to trigger hats on.
* @private
*/
_activateClickHats (x, y) {
if (this.runtime.renderer) {
const drawableID = this.runtime.renderer.pick(x, y);
for (let i = 0; i < this.runtime.targets.length; i++) {
const target = this.runtime.targets[i];
if (target.hasOwnProperty('drawableID') &&
target.drawableID === drawableID) {
// only activate click hat if the mouse up event wasn't
_activateClickHats (target) {
// Activate both "this sprite clicked" and "stage clicked"
// They were separated into two opcodes for labeling,
// but should act the same way.
@ -38,16 +28,28 @@ class Mouse {
null, target);
this.runtime.startHats('event_whenstageclicked',
null, target);
return;
}
/**
* Find a target by XY location
* @param {number} x X position to be sent to the renderer.
* @param {number} y Y position to be sent to the renderer.
* @return {Target} the target at that location
* @private
*/
_pickTarget (x, y) {
if (this.runtime.renderer) {
const drawableID = this.runtime.renderer.pick(x, y);
for (let i = 0; i < this.runtime.targets.length; i++) {
const target = this.runtime.targets[i];
if (target.hasOwnProperty('drawableID') &&
target.drawableID === drawableID) {
return target;
}
}
// If haven't returned, activate click hats for stage.
// Still using both blocks for sharing compatibility.
this.runtime.startHats('event_whenthisspriteclicked',
null, this.runtime.getTargetForStage());
this.runtime.startHats('event_whenstageclicked',
null, this.runtime.getTargetForStage());
}
// Return the stage if no target was found
return this.runtime.getTargetForStage();
}
/**
@ -74,12 +76,27 @@ class Mouse {
if (typeof data.isDown !== 'undefined') {
const previousDownState = this._isDown;
this._isDown = data.isDown;
// Do not trigger if down state has not changed
if (previousDownState === this._isDown) return;
// Never trigger click hats at the end of a drag
if (data.wasDragged) return;
// Do not activate click hats for clicks outside canvas bounds
if (!(data.x > 0 && data.x < data.canvasWidth &&
data.y > 0 && data.y < data.canvasHeight)) return;
const target = this._pickTarget(data.x, data.y);
const isNewMouseDown = !previousDownState && this._isDown;
// Make sure click is within the canvas bounds to activate click hats
if (isNewMouseDown &&
data.x > 0 && data.x < data.canvasWidth &&
data.y > 0 && data.y < data.canvasHeight) {
this._activateClickHats(data.x, data.y);
const isNewMouseUp = previousDownState && !this._isDown;
// Draggable targets start click hats on mouse up.
// Non-draggable targets start click hats on mouse down.
if (target.draggable && isNewMouseUp) {
this._activateClickHats(target);
} else if (!target.draggable && isNewMouseDown) {
this._activateClickHats(target);
}
}
}

View file

@ -82,6 +82,10 @@ test('mousedown activating click hats', t => {
canvasHeight: 360
};
const dummyTarget = {
draggable: false
};
const mouseDownEvent = Object.assign({}, mouseMoveEvent, {
isDown: true
});
@ -90,17 +94,19 @@ test('mousedown activating click hats', t => {
isDown: false
});
// Stub activateClickHats function for testing
// Stub activateClickHats and pick function for testing
let ranClickHats = false;
m._activateClickHats = () => {
ranClickHats = true;
};
m._pickTarget = () => dummyTarget;
// Mouse move without mousedown
m.postData(mouseMoveEvent);
t.strictEquals(ranClickHats, false);
// Mouse down event triggers the hats
// Mouse down event triggers the hats if target is not draggable
dummyTarget.draggable = false;
m.postData(mouseDownEvent);
t.strictEquals(ranClickHats, true);
@ -109,10 +115,11 @@ test('mousedown activating click hats', t => {
m.postData(mouseDownEvent);
t.strictEquals(ranClickHats, false);
// And it doesn't trigger on mouse up
// And it does trigger on mouse up if target is draggable
ranClickHats = false;
dummyTarget.draggable = true;
m.postData(mouseUpEvent);
t.strictEquals(ranClickHats, false);
t.strictEquals(ranClickHats, true);
// And hats don't trigger if mouse down is outside canvas
ranClickHats = false;