[Mobile] Context Menu

Context menu next to object header
now dismisses when touching away
from it. Also, when long touching
an object, the context menu appears.
Set on 500ms timeout.
This commit is contained in:
Shivam Dave 2015-07-28 17:09:15 -07:00
parent 356fa73c91
commit 84b9e4d781
4 changed files with 46 additions and 38 deletions

View File

@ -42,22 +42,13 @@ define(
var dismissBubble, var dismissBubble,
pendingBubble, pendingBubble,
mousePosition, mousePosition,
touchPosition, scopeOff;
scopeOff,
touchDELAY = 500;
function trackPosition(event) { function trackPosition(event) {
// Record mouse position, so bubble can be shown at latest // Record mouse position, so bubble can be shown at latest
// mouse position (not just where the mouse entered) // mouse position (not just where the mouse entered)
mousePosition = [ event.clientX, event.clientY ]; mousePosition = [ event.clientX, event.clientY ];
} }
// function trackTouchPosition(event) {
// var tEvent = event.changedTouches[0];
// // Record mouse position, so bubble can be shown at latest
// // mouse position (not just where the mouse entered)
// touchPosition = [ tEvent.clientX + 44, tEvent.clientY ];
// }
function hideBubble() { function hideBubble() {
// If a bubble is showing, dismiss it // If a bubble is showing, dismiss it
@ -76,7 +67,6 @@ define(
// Also clear mouse position so we don't have a ton of tiny // Also clear mouse position so we don't have a ton of tiny
// arrays allocated while user mouses over things // arrays allocated while user mouses over things
mousePosition = undefined; mousePosition = undefined;
touchPosition = undefined;
} }
function showBubble(event) { function showBubble(event) {
@ -102,23 +92,6 @@ define(
element.on('mouseleave', hideBubble); element.on('mouseleave', hideBubble);
} }
// function showTouchBubble(event) {
// // Makes sure user is only touching one place
// if (event.touches.length < 2) {
// trackTouchPosition(event);
// pendingBubble = $timeout(function () {
// dismissBubble = infoService.display(
// "info-table",
// domainObject.getModel().name,
// domainObject.useCapability('metadata'),
// touchPosition
// );
// }, touchDELAY);
//
// element.on('touchend', hideBubble);
// }
// }
// Checks if you are on a mobile device, if the device is // Checks if you are on a mobile device, if the device is
// not mobile (queryService.isMobile() = false), then // not mobile (queryService.isMobile() = false), then
// the pendingBubble and therefore hovering is allowed // the pendingBubble and therefore hovering is allowed

View File

@ -26,7 +26,7 @@
{ {
"key": "menu", "key": "menu",
"implementation": "gestures/ContextMenuGesture.js", "implementation": "gestures/ContextMenuGesture.js",
"depends": ["queryService"] "depends": ["$timeout", "queryService"]
} }
], ],
"components": [ "components": [
@ -54,7 +54,7 @@
{ {
"key": "menu", "key": "menu",
"implementation": "actions/ContextMenuAction.js", "implementation": "actions/ContextMenuAction.js",
"depends": [ "$compile", "$document", "$window", "$rootScope" ] "depends": [ "$compile", "$document", "$window", "$rootScope", "queryService" ]
} }
] ]
} }

View File

@ -47,7 +47,7 @@ define(
* @param actionContexr the context in which the action * @param actionContexr the context in which the action
* should be performed * should be performed
*/ */
function ContextMenuAction($compile, $document, $window, $rootScope, actionContext) { function ContextMenuAction($compile, $document, $window, $rootScope, queryService, actionContext) {
function perform() { function perform() {
var winDim = [$window.innerWidth, $window.innerHeight], var winDim = [$window.innerWidth, $window.innerHeight],
@ -94,13 +94,26 @@ define(
body.append(menu); body.append(menu);
// Stop propagation so that clicks on the menu do not close the menu // Stop propagation so that clicks on the menu do not close the menu
menu.on('mousedown', function (event) { // Stop propagation so that touches on the menu do not close the menu
event.stopPropagation(); if (!queryService.isMobile(navigator.userAgent)) {
}); menu.on('mousedown', function (event) {
event.stopPropagation();
});
} else if (queryService.isMobile(navigator.userAgent)) {
menu.on('touchstart', function (event) {
event.stopPropagation();
});
}
// Dismiss the menu when body is clicked elsewhere // Dismiss the menu when body is clicked/touched elsewhere
// ('mousedown' because 'click' breaks left-click context menus) // ('mousedown' because 'click' breaks left-click context menus)
body.on('mousedown', dismiss); // ('touchstart' because 'touch' breaks context menus up)
if (!queryService.isMobile(navigator.userAgent)) {
body.on('mousedown', dismiss);
} else if (queryService.isMobile(navigator.userAgent)) {
body.on('touchstart', dismiss);
}
// Don't launch browser's context menu // Don't launch browser's context menu
actionContext.event.preventDefault(); actionContext.event.preventDefault();

View File

@ -39,9 +39,11 @@ define(
* @param {DomainObject} domainObject the object on which actions * @param {DomainObject} domainObject the object on which actions
* in the context menu will be performed * in the context menu will be performed
*/ */
function ContextMenuGesture(queryService, element, domainObject) { function ContextMenuGesture($timeout, queryService, element, domainObject) {
var actionContext, var actionContext,
stop; stop,
isPressing,
longTouchTime = 500;
// When context menu event occurs, show object actions instead // When context menu event occurs, show object actions instead
if (!queryService.isMobile(navigator.userAgent)) { if (!queryService.isMobile(navigator.userAgent)) {
@ -49,6 +51,26 @@ define(
actionContext = {key: 'menu', domainObject: domainObject, event: event}; actionContext = {key: 'menu', domainObject: domainObject, event: event};
stop = domainObject.getCapability('action').perform(actionContext); stop = domainObject.getCapability('action').perform(actionContext);
}); });
} else if (queryService.isMobile(navigator.userAgent)) {
// If on mobile device, then start timeout for the single touch event
// during the timeout 'isPressing' is true.
element.on('touchstart', function (event) {
if (event.touches.length < 2) {
isPressing = true;
// After the timeout, if 'isPressing' is
// true, display context menu for object
$timeout(function () {
if (isPressing) {
actionContext = {key: 'menu', domainObject: domainObject, event: event};
stop = domainObject.getCapability('action').perform(actionContext);
}
}, longTouchTime);
}
});
// Whenever the touch event ends, 'isPressing' is false.
element.on('touchend', function (event) {
isPressing = false;
});
} }
return { return {