1
0
mirror of https://github.com/psychopy/psychojs.git synced 2025-05-10 10:40:54 +00:00

Merge pull request #508 from lightest/CU-2au7jhz_snap_slidermarker_to_cursor_on_pointerdown

Slider: improved pointer events handling
This commit is contained in:
Alain Pitiot 2022-06-23 09:12:33 +02:00 committed by GitHub
commit 10bebd2bbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -256,6 +256,10 @@ export class Slider extends util.mix(VisualStim).with(ColorMixin, WindowMixin)
{
this._psychoJS.experimentLogger.exp(`Created ${this.name} = ${this.toString()}`);
}
this._handlePointerDownBinded = this._handlePointerDown.bind(this);
this._handlePointerUpBinded = this._handlePointerUp.bind(this);
this._handlePointerMoveBinded = this._handlePointerMove.bind(this);
}
/**
@ -737,6 +741,21 @@ export class Slider extends util.mix(VisualStim).with(ColorMixin, WindowMixin)
this._needUpdate = true;
}
/**
* Release the PIXI representation, if there is one.
*
* @name module:core.Slider#release
* @function
* @public
*
* @param {boolean} [log= false] - whether or not to log
*/
release (log = false)
{
this._removeEventListeners();
super.release(log);
}
/**
* Update the stimulus, if necessary.
*
@ -828,6 +847,100 @@ export class Slider extends util.mix(VisualStim).with(ColorMixin, WindowMixin)
}
}
/**
* Handle pointerdown event.
*
* @name module:visual.Slider#_handlePointerDown
* @private
*/
_handlePointerDown (e) {
if (e.data.button === 0)
{
this._markerDragging = true;
if (!this._frozenMarker)
{
const mouseLocalPos_px = e.data.getLocalPosition(this._pixi);
const rating = this._posToRating([mouseLocalPos_px.x, mouseLocalPos_px.y]);
this.setMarkerPos(rating);
}
}
e.stopPropagation();
}
/**
* Handle pointermove event.
*
* @name module:visual.Slider#_handlePointerMove
* @private
*/
_handlePointerMove (e)
{
if (this._markerDragging)
{
if (!this._frozenMarker)
{
const mouseLocalPos_px = e.data.getLocalPosition(this._pixi);
const rating = this._posToRating([mouseLocalPos_px.x, mouseLocalPos_px.y]);
this.setMarkerPos(rating);
}
e.stopPropagation();
}
}
/**
* Handle pointerup event.
*
* @name module:visual.Slider#_handlePointerUp
* @private
*/
_handlePointerUp (e)
{
if (this._markerDragging)
{
this._markerDragging = false;
if (!this._frozenMarker)
{
const mouseLocalPos_px = e.data.getLocalPosition(this._pixi);
const rating = this._posToRating([mouseLocalPos_px.x, mouseLocalPos_px.y]);
this.recordRating(rating);
}
e.stopPropagation();
}
}
/**
* Add event listeners.
*
* @name module:visual.Slider#_addEventListeners
* @private
*/
_addEventListeners ()
{
this._pixi.on("pointerdown", this._handlePointerDownBinded);
this._win._rootContainer.on("pointermove", this._handlePointerMoveBinded);
this._win._rootContainer.on("pointerup", this._handlePointerUpBinded);
}
/**
* Remove event listeners.
*
* @name module:visual.Slider#_removeEventListeners
* @private
*/
_removeEventListeners ()
{
if (this._pixi)
{
this._pixi.off("pointerdown", this._handlePointerDownBinded);
}
this._win._rootContainer.off("pointermove", this._handlePointerMoveBinded);
this._win._rootContainer.off("pointerup", this._handlePointerUpBinded);
}
/**
* Setup the PIXI components of the slider (bar, ticks, labels, marker, etc.).
*
@ -855,6 +968,7 @@ export class Slider extends util.mix(VisualStim).with(ColorMixin, WindowMixin)
if (typeof this._pixi !== "undefined")
{
this._removeEventListeners();
this._pixi.destroy(true);
}
this._pixi = new PIXI.Container();
@ -899,6 +1013,7 @@ export class Slider extends util.mix(VisualStim).with(ColorMixin, WindowMixin)
// markers:
this._setupMarker();
this._addEventListeners();
}
/**
@ -1040,111 +1155,6 @@ export class Slider extends util.mix(VisualStim).with(ColorMixin, WindowMixin)
const self = this;
self._markerDragging = false;
this._marker.pointerdown = this._marker.mousedown = this._marker.touchstart = (event) =>
{
if (event.data.button === 0)
{
self._markerDragging = true;
/* not quite right, just yet (as of May 2020)
// set markerPos, but not rating:
const mouseLocalPos_px = event.data.getLocalPosition(self._pixi);
const rating = self._posToRating([mouseLocalPos_px.x, mouseLocalPos_px.y]);
self._markerPos = self._granularise(rating);
self._needMarkerUpdate = true;
*/
}
event.stopPropagation();
};
// pointer was released inside the marker: if we were dragging, we record the rating
this._marker.pointerup = this._marker.mouseup = this._marker.touchend = (event) =>
{
if (self._markerDragging)
{
self._markerDragging = false;
if (!this._frozenMarker)
{
const mouseLocalPos_px = event.data.getLocalPosition(self._pixi);
const rating = self._posToRating([mouseLocalPos_px.x, mouseLocalPos_px.y]);
self.recordRating(rating);
}
event.stopPropagation();
}
};
// pointer was released outside of the marker: cancel the dragging
this._marker.pointerupoutside = this._marker.mouseupoutside = this._marker.touchendoutside = (event) =>
{
if (self._markerDragging)
{
self._markerDragging = false;
if (!this._frozenMarker)
{
const mouseLocalPos_px = event.data.getLocalPosition(self._pixi);
const rating = self._posToRating([mouseLocalPos_px.x, mouseLocalPos_px.y]);
self.recordRating(rating);
}
event.stopPropagation();
}
};
// pointer is moving: if we are dragging, we move the marker position
this._marker.pointermove = (event) =>
{
if (self._markerDragging)
{
if (!this._frozenMarker)
{
const mouseLocalPos_px = event.data.getLocalPosition(self._pixi);
const rating = self._posToRating([mouseLocalPos_px.x, mouseLocalPos_px.y]);
self.setMarkerPos(rating);
}
event.stopPropagation();
}
};
// (*) slider mouse events outside of marker
// note: this only works thanks to eventCaptureRectangle
/* not quite right just yet (as of May 2020)
this._pixi.pointerdown = this._pixi.mousedown = this._pixi.touchstart = (event) =>
{
if (event.data.button === 0)
{
self._markerDragging = true;
// set markerPos, but not rating:
const mouseLocalPos_px = event.data.getLocalPosition(self._body);
const rating = self._posToRating([mouseLocalPos_px.x, mouseLocalPos_px.y]);
self._markerPos = self._granularise(rating);
// update the marker:
self._needMarkerUpdate = true;
self._updateMarker();
}
event.stopPropagation();
};
*/
this._pixi.pointerup = this._pixi.mouseup = this._pixi.touchend = (event) =>
{
if (!this._frozenMarker)
{
const mouseLocalPos_px = event.data.getLocalPosition(self._body);
const rating = self._posToRating([mouseLocalPos_px.x, mouseLocalPos_px.y]);
self.recordRating(rating);
}
event.stopPropagation();
};
// mouse wheel over slider:
if (this._isSliderStyle)
{