From e37eb5270ad732af486ef2f3372d40ff4a4a6c4a Mon Sep 17 00:00:00 2001 From: Sotiri Bakagiannis Date: Tue, 14 Jul 2020 12:57:20 +0100 Subject: [PATCH 1/5] core/Mouse: add isPressedIn method --- js/core/Mouse.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/js/core/Mouse.js b/js/core/Mouse.js index 4b3baa5..3e0dd72 100644 --- a/js/core/Mouse.js +++ b/js/core/Mouse.js @@ -149,6 +149,33 @@ export class Mouse extends PsychObject } } + /** + * Helper method for checking whether a stimulus has had any button presses within bounds. + * + *

Note: Since there can only be one button pressed at a time, there is no point passing in a "buttons" array like PsychoPy. Pass in a "wanted" array index for the target button instead.

+ * + * @name module:core.Mouse#isPressedIn + * @function + * @public + * @param {object|module:visual.VisualStim} [stimulus= undefined] A type of stimulus implementing a `contains()` method. + * @param {number} [wanted= undefined] The target button index. + * @return {boolean} Whether mouse with button(s) pressed is contained within stimulus. + */ + isPressedIn(stimulus, wanted) + { + // Will throw if stimulus is falsy or non-object like + if (typeof stimulus.contains === 'function') + { + const { buttons } = this.psychoJS.eventManager.getMouseInfo(); + // If no specific button wanted, any pressed will do + const pressed = Number.isInteger(wanted) ? buttons.pressed[wanted] > 0 : buttons.pressed.some(v => v > 0); + + return pressed && stimulus.contains(this); + } + + return false; + } + /** * Determine whether the mouse has moved beyond a certain distance. From d023ed3b8ccebf2a4343b0d65fd4a7c4c6e28b2f Mon Sep 17 00:00:00 2001 From: Sotiri Bakagiannis Date: Thu, 16 Jul 2020 17:20:59 +0100 Subject: [PATCH 2/5] core/Mouse: tweak isPressedIn to cover all types of arguments Bring in line with PsychoPy by accepting arguments as follows: (a) mouse.isPressedIn({"shape": myStim, "buttons": 1}) (b) mouse.isPressedIn(myStim, {"buttons": 1}) (c) mouse.isPressedIn(myStim, 1) --- js/core/Mouse.js | 51 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/js/core/Mouse.js b/js/core/Mouse.js index 3e0dd72..e7cd7b0 100644 --- a/js/core/Mouse.js +++ b/js/core/Mouse.js @@ -152,25 +152,52 @@ export class Mouse extends PsychObject /** * Helper method for checking whether a stimulus has had any button presses within bounds. * - *

Note: Since there can only be one button pressed at a time, there is no point passing in a "buttons" array like PsychoPy. Pass in a "wanted" array index for the target button instead.

- * * @name module:core.Mouse#isPressedIn * @function * @public - * @param {object|module:visual.VisualStim} [stimulus= undefined] A type of stimulus implementing a `contains()` method. - * @param {number} [wanted= undefined] The target button index. + * @param {object|module:visual.VisualStim} [shape= undefined] A type of stimulus implementing a `contains()` method. + * @param {object|number} [buttons= undefined] The target button index. * @return {boolean} Whether mouse with button(s) pressed is contained within stimulus. */ - isPressedIn(stimulus, wanted) + isPressedIn(...args) { - // Will throw if stimulus is falsy or non-object like - if (typeof stimulus.contains === 'function') - { - const { buttons } = this.psychoJS.eventManager.getMouseInfo(); - // If no specific button wanted, any pressed will do - const pressed = Number.isInteger(wanted) ? buttons.pressed[wanted] > 0 : buttons.pressed.some(v => v > 0); + // Helper to check if some object features a certain key + const hasKey = key => object => !!(object && object[key]); - return pressed && stimulus.contains(this); + // Look for options given in object literal form, cut out falsy inputs + const [{ shape: shapeMaybe, buttons: buttonsMaybe } = {}] = args.filter(v => !!v); + + // Shapes are expected to be instances of stimuli, or at + // the very least objects featuring a `contains()` method + const isShape = hasKey('contains'); + + // Go through arguments array looking for a shape if options object offers none + const shapeFound = isShape(shapeMaybe) ? shapeMaybe : args.find(isShape); + // Default to input (pass through) + const shape = shapeFound || shapeMaybe; + + // Buttons values may be extracted from an object literal + // featuring the `buttons` key, or found as integers + // in the arguments array + const hasButtons = hasKey('buttons'); + const { isInteger } = Number; + // Prioritize buttons value given as part of an options object literal, + // then look for the first occurrence in the arguments array of either + // an integer or an extra object with a `buttons` key + const buttonsFound = isInteger(buttonsMaybe) ? buttonsMaybe : args.find(o => hasButtons(o) || isInteger(o)); + // Worst case scenario `wanted` ends up being an empty object literal + const { buttons: wanted = buttonsFound || buttonsMaybe } = buttonsFound || {}; + + // Will throw if stimulus is falsy or non-object like + if (typeof shape.contains === 'function') + { + const mouseInfo = this.psychoJS.eventManager.getMouseInfo(); + const { pressed } = mouseInfo.buttons; + + // If no specific button wanted, any pressed will do + const hasButtonPressed = isInteger(wanted) ? pressed[wanted] > 0 : pressed.some(v => v > 0); + + return hasButtonPressed && shape.contains(this); } return false; From 460ba1998d543d623c379b91d8672bc8cb64017e Mon Sep 17 00:00:00 2001 From: Sotiri Bakagiannis Date: Fri, 17 Jul 2020 12:30:15 +0100 Subject: [PATCH 3/5] core/Mouse: clean up comments --- js/core/Mouse.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/core/Mouse.js b/js/core/Mouse.js index e7cd7b0..66ddb40 100644 --- a/js/core/Mouse.js +++ b/js/core/Mouse.js @@ -176,16 +176,16 @@ export class Mouse extends PsychObject // Default to input (pass through) const shape = shapeFound || shapeMaybe; - // Buttons values may be extracted from an object literal + // Buttons values may be extracted from an object // featuring the `buttons` key, or found as integers // in the arguments array const hasButtons = hasKey('buttons'); const { isInteger } = Number; - // Prioritize buttons value given as part of an options object literal, + // Prioritize buttons value given as part of an options object, // then look for the first occurrence in the arguments array of either // an integer or an extra object with a `buttons` key const buttonsFound = isInteger(buttonsMaybe) ? buttonsMaybe : args.find(o => hasButtons(o) || isInteger(o)); - // Worst case scenario `wanted` ends up being an empty object literal + // Worst case scenario `wanted` ends up being an empty object const { buttons: wanted = buttonsFound || buttonsMaybe } = buttonsFound || {}; // Will throw if stimulus is falsy or non-object like From 2909dabf832a76203ca7c583db93e050e07b050b Mon Sep 17 00:00:00 2001 From: Sotiri Bakagiannis Date: Fri, 17 Jul 2020 15:06:58 +0100 Subject: [PATCH 4/5] core/Mouse: clean up mostly JSDoc --- js/core/Mouse.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/js/core/Mouse.js b/js/core/Mouse.js index 66ddb40..2eaf0d1 100644 --- a/js/core/Mouse.js +++ b/js/core/Mouse.js @@ -149,24 +149,28 @@ export class Mouse extends PsychObject } } + /** * Helper method for checking whether a stimulus has had any button presses within bounds. * * @name module:core.Mouse#isPressedIn * @function * @public - * @param {object|module:visual.VisualStim} [shape= undefined] A type of stimulus implementing a `contains()` method. - * @param {object|number} [buttons= undefined] The target button index. + * @param {object|module:visual.VisualStim} shape A type of visual stimulus or object having a `contains()` method. + * @param {object|number} [buttons] The target button index potentially tucked inside an object. + * @param {object} [options] + * @param {object|module:visual.VisualStim} [options.shape] + * @param {number} [options.buttons] * @return {boolean} Whether mouse with button(s) pressed is contained within stimulus. */ isPressedIn(...args) { - // Helper to check if some object features a certain key - const hasKey = key => object => !!(object && object[key]); - // Look for options given in object literal form, cut out falsy inputs const [{ shape: shapeMaybe, buttons: buttonsMaybe } = {}] = args.filter(v => !!v); + // Helper to check if some object features a certain key + const hasKey = key => object => !!(object && object[key]); + // Shapes are expected to be instances of stimuli, or at // the very least objects featuring a `contains()` method const isShape = hasKey('contains'); From 43dedcb7f71f797c262cd313097e8495b6e5f0fc Mon Sep 17 00:00:00 2001 From: Sotiri Bakagiannis Date: Fri, 17 Jul 2020 16:46:36 +0100 Subject: [PATCH 5/5] core/Mouse: clean up JSDoc --- js/core/Mouse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/core/Mouse.js b/js/core/Mouse.js index 2eaf0d1..8428c3c 100644 --- a/js/core/Mouse.js +++ b/js/core/Mouse.js @@ -161,7 +161,7 @@ export class Mouse extends PsychObject * @param {object} [options] * @param {object|module:visual.VisualStim} [options.shape] * @param {number} [options.buttons] - * @return {boolean} Whether mouse with button(s) pressed is contained within stimulus. + * @return {boolean} Whether button pressed is contained within stimulus. */ isPressedIn(...args) {