Merge pull request #1244 from LarissaSmith/master

Fix more issues with tracking multiple pointers.
This commit is contained in:
Ian Gilman 2017-07-12 16:00:38 -07:00 committed by GitHub
commit 28f9e9e35e

View File

@ -317,6 +317,25 @@
return this; return this;
}, },
/**
* Returns the {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} for all but the given pointer device type.
* @function
* @param {String} type - The pointer device type: "mouse", "touch", "pen", etc.
* @returns {Array.<OpenSeadragon.MouseTracker.GesturePointList>}
*/
getActivePointersListsExceptType: function ( type ) {
var delegate = THIS[ this.hash ];
var listArray = [];
for (var i = 0; i < delegate.activePointersLists.length; ++i) {
if (delegate.activePointersLists[i].type !== type) {
listArray.push(delegate.activePointersLists[i]);
}
}
return listArray;
},
/** /**
* Returns the {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} for the given pointer device type, * Returns the {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} for the given pointer device type,
* creating and caching a new {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} if one doesn't already exist for the type. * creating and caching a new {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} if one doesn't already exist for the type.
@ -1216,6 +1235,30 @@
} }
} }
return null; return null;
},
/**
* @function Increment this pointer's contact count.
* It will evaluate whether this pointer type is allowed to have multiple contacts.
*/
addContact: function() {
++this.contacts;
if (this.contacts > 1 && (this.type === "mouse" || this.type === "pen")) {
this.contacts = 1;
}
},
/**
* @function Decrement this pointer's contact count.
* It will make sure the count does not go below 0.
*/
removeContact: function() {
--this.contacts;
if (this.contacts < 0) {
this.contacts = 0;
}
} }
}; };
@ -2020,23 +2063,26 @@
* @private * @private
* @inner * @inner
*/ */
function abortTouchContacts( tracker, event, pointsList ) { function abortContacts( tracker, event, pointsList ) {
var i, var i,
gPointCount = pointsList.getLength(), gPointCount = pointsList.getLength(),
abortGPoints = []; abortGPoints = [];
for ( i = 0; i < gPointCount; i++ ) { // Check contact count for hoverable pointer types before aborting
abortGPoints.push( pointsList.getByIndex( i ) ); if (pointsList.type === 'touch' || pointsList.contacts > 0) {
} for ( i = 0; i < gPointCount; i++ ) {
abortGPoints.push( pointsList.getByIndex( i ) );
}
if ( abortGPoints.length > 0 ) { if ( abortGPoints.length > 0 ) {
// simulate touchend // simulate touchend/mouseup
updatePointersUp( tracker, event, abortGPoints, 0 ); // 0 means primary button press/release or touch contact updatePointersUp( tracker, event, abortGPoints, 0 ); // 0 means primary button press/release or touch contact
// release pointer capture // release pointer capture
pointsList.captureCount = 1; pointsList.captureCount = 1;
releasePointer( tracker, 'touch' ); releasePointer( tracker, pointsList.type );
// simulate touchleave // simulate touchleave/mouseout
updatePointersExit( tracker, event, abortGPoints ); updatePointersExit( tracker, event, abortGPoints );
}
} }
} }
@ -2058,7 +2104,7 @@
if ( pointsList.getLength() > event.touches.length - touchCount ) { if ( pointsList.getLength() > event.touches.length - touchCount ) {
$.console.warn('Tracked touch contact count doesn\'t match event.touches.length. Removing all tracked touch pointers.'); $.console.warn('Tracked touch contact count doesn\'t match event.touches.length. Removing all tracked touch pointers.');
abortTouchContacts( tracker, event, pointsList ); abortContacts( tracker, event, pointsList );
} }
for ( i = 0; i < touchCount; i++ ) { for ( i = 0; i < touchCount; i++ ) {
@ -2228,7 +2274,7 @@
function onTouchCancel( tracker, event ) { function onTouchCancel( tracker, event ) {
var pointsList = tracker.getActivePointersListByType('touch'); var pointsList = tracker.getActivePointersListByType('touch');
abortTouchContacts( tracker, event, pointsList ); abortContacts( tracker, event, pointsList );
} }
@ -2705,6 +2751,14 @@
} }
} }
// Some pointers may steal control from another pointer without firing the appropriate release events
// e.g. Touching a screen while click-dragging with certain mice.
var otherPointsLists = tracker.getActivePointersListsExceptType(gPoints[ 0 ].type);
for (i = 0; i < otherPointsLists.length; i++) {
//If another pointer has contact, simulate the release
abortContacts(tracker, event, otherPointsLists[i]); // No-op if no active pointer
}
// Only capture and track primary button, pen, and touch contacts // Only capture and track primary button, pen, and touch contacts
if ( buttonChanged !== 0 ) { if ( buttonChanged !== 0 ) {
// Aux Press // Aux Press
@ -2755,7 +2809,7 @@
startTrackingPointer( pointsList, curGPoint ); startTrackingPointer( pointsList, curGPoint );
} }
pointsList.contacts++; pointsList.addContact();
//$.console.log('contacts++ ', pointsList.contacts); //$.console.log('contacts++ ', pointsList.contacts);
if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) { if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) {
@ -2895,11 +2949,10 @@
} }
// A primary mouse button may have been released while the non-primary button was down // A primary mouse button may have been released while the non-primary button was down
if (pointsList.contacts > 0 && pointsList.type === 'mouse') { var otherPointsList = tracker.getActivePointersListByType("mouse");
// Stop tracking the mouse; see https://github.com/openseadragon/openseadragon/pull/1223 // Stop tracking the mouse; see https://github.com/openseadragon/openseadragon/pull/1223
pointsList.contacts--; abortContacts(tracker, event, otherPointsList); // No-op if no active pointer
return true;
}
return false; return false;
} }
@ -2928,7 +2981,7 @@
if ( wasCaptured ) { if ( wasCaptured ) {
// Pointer was activated in our element but could have been removed in any element since events are captured to our element // Pointer was activated in our element but could have been removed in any element since events are captured to our element
pointsList.contacts--; pointsList.removeContact();
//$.console.log('contacts-- ', pointsList.contacts); //$.console.log('contacts-- ', pointsList.contacts);
if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) { if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) {