Commit da122e2a authored by Neil Fraser's avatar Neil Fraser

Enable long-press context menus.

parent 764452eb
This diff is collapsed.
......@@ -87,6 +87,9 @@ Blockly.BlockSvg.prototype.initSvg = function() {
if (!Blockly.readOnly && !this.eventsInit_) {
Blockly.bindEvent_(this.getSvgRoot(), 'mousedown', this,
this.onMouseDown_);
var thisBlock = this;
Blockly.bindEvent_(this.getSvgRoot(), 'touchstart', null,
function(e) {Blockly.longStart_(e, thisBlock);});
}
// Bind an onchange function, if it exists.
if (goog.isFunction(this.onchange) && !this.eventsInit_) {
......@@ -677,6 +680,7 @@ Blockly.BlockSvg.prototype.onMouseMove_ = function(e) {
if (dr > Blockly.DRAG_RADIUS) {
// Switch to unrestricted dragging.
Blockly.dragMode_ = 2;
Blockly.longStop_();
// Push this block to the very top of the stack.
this_.setParent(null);
this_.setDragging_(true);
......
......@@ -207,6 +207,11 @@ Blockly.BUMP_DELAY = 250;
*/
Blockly.COLLAPSE_CHARS = 30;
/**
* Length in ms for a touch to become a long press.
*/
Blockly.LONGPRESS = 750;
/**
* The main workspace (defined by inject.js).
* @type {Blockly.Workspace}
......@@ -359,6 +364,11 @@ Blockly.onMouseMove_ = function(e) {
// Move the scrollbars and the page will scroll automatically.
Blockly.mainWorkspace.scrollbar.set(-x - metrics.contentLeft,
-y - metrics.contentTop);
// Cancel the long-press if the drag has moved too far.
var dr = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
if (dr > Blockly.DRAG_RADIUS) {
Blockly.longStop_();
}
e.stopPropagation();
}
};
......@@ -422,6 +432,47 @@ Blockly.terminateDrag_ = function() {
Blockly.Flyout.terminateDrag_();
};
/**
* PID of queued long-press task.
* @private
*/
Blockly.longPid_ = 0;
/**
* Context menus on touch devices are activated using a long-press.
* Unfortunately the contextmenu touch event is currently (2015) only suported
* by Chrome. This function is fired on any touchstart event, queues a task,
* which after about a second opens the context menu. The tasks is killed
* if the touch event terminates early.
* @param {!Event} e Touch start event.
* @param {Blockly.Block} block The block under the touchstart event, or null
* if the event was on the workspace.
* @private
*/
Blockly.longStart_ = function(e, block) {
Blockly.longStop_();
Blockly.longPid_ = setTimeout(function() {
e.button = 2; // Simulate a right button click.
if (block) {
block.onMouseDown_(e);
} else {
Blockly.onMouseDown_(e);
}
}, Blockly.LONGPRESS);
};
/**
* Nope, that's not a long-press. Either touchend or touchcancel was fired,
* or a drag hath begun. Kill the queued long-press task.
* @private
*/
Blockly.longStop_ = function() {
if (Blockly.longPid_) {
clearTimeout(Blockly.longPid_);
Blockly.longPid_ = 0;
}
};
/**
* Copy a block onto the local clipboard.
* @param {!Blockly.Block} block Block to be copied.
......
......@@ -395,7 +395,6 @@ Blockly.createDom_ = function(container) {
document.body.appendChild(Blockly.WidgetDiv.DIV);
};
/**
* Initialize Blockly with various handlers.
* @private
......@@ -412,11 +411,16 @@ Blockly.init_ = function() {
Blockly.bindEvent_(Blockly.WidgetDiv.DIV, 'contextmenu', null,
Blockly.onContextMenu_);
Blockly.bindEvent_(Blockly.svg, 'touchstart', null,
function(e) {Blockly.longStart_(e, null);});
if (!Blockly.documentEventsBound_) {
// Only bind the window/document events once.
// Destroying and reinjecting Blockly should not bind again.
Blockly.bindEvent_(window, 'resize', document, Blockly.svgResize);
Blockly.bindEvent_(document, 'keydown', null, Blockly.onKeyDown_);
Blockly.bindEvent_(document, 'touchend', null, Blockly.longStop_);
Blockly.bindEvent_(document, 'touchcancel', null, Blockly.longStop_);
// Don't use bindEvent_ for document's mouseup since that would create a
// corresponding touch handler that would squeltch the ability to interact
// with non-Blockly elements.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment