2013-09-30 07:44:31 +00:00
|
|
|
Elm.Native.Touch = {};
|
|
|
|
Elm.Native.Touch.make = function(elm) {
|
2013-02-20 22:36:16 +00:00
|
|
|
|
2013-03-09 06:57:13 +00:00
|
|
|
elm.Native = elm.Native || {};
|
2013-09-30 08:32:27 +00:00
|
|
|
elm.Native.Touch = elm.Native.Touch || {};
|
|
|
|
if (elm.Native.Touch.values) return elm.Native.Touch.values;
|
2013-03-09 06:57:13 +00:00
|
|
|
|
2013-09-30 07:44:31 +00:00
|
|
|
var Signal = Elm.Signal.make(elm);
|
|
|
|
var JS = Elm.JavaScript.make(elm);
|
|
|
|
var _ = Elm.Native.Utils.make(elm);
|
2013-03-09 06:57:13 +00:00
|
|
|
|
2013-02-20 22:36:16 +00:00
|
|
|
function Dict() {
|
|
|
|
this.keys = [];
|
|
|
|
this.values = [];
|
|
|
|
|
|
|
|
this.insert = function(key,value) {
|
|
|
|
this.keys.push(key);
|
|
|
|
this.values.push(value);
|
|
|
|
};
|
|
|
|
this.lookup = function(key) {
|
|
|
|
var i = this.keys.indexOf(key)
|
|
|
|
return i >= 0 ? this.values[i] : {x:0,y:0,t:0};
|
|
|
|
};
|
|
|
|
this.remove = function(key) {
|
|
|
|
var i = this.keys.indexOf(key);
|
|
|
|
if (i < 0) return;
|
|
|
|
var t = this.values[i];
|
|
|
|
this.keys.splice(i,1);
|
|
|
|
this.values.splice(i,1);
|
|
|
|
return t;
|
|
|
|
};
|
2013-05-06 00:51:30 +00:00
|
|
|
this.clear = function() {
|
|
|
|
this.keys = [];
|
|
|
|
this.values = [];
|
|
|
|
};
|
2013-02-20 22:36:16 +00:00
|
|
|
}
|
|
|
|
|
2013-03-09 06:57:13 +00:00
|
|
|
var root = Signal.constant([]),
|
2013-02-20 22:36:16 +00:00
|
|
|
tapTime = 500,
|
|
|
|
hasTap = false,
|
|
|
|
tap = {_:{},x:0,y:0},
|
|
|
|
dict = new Dict();
|
|
|
|
|
|
|
|
function touch(t) {
|
|
|
|
var r = dict.lookup(t.identifier);
|
|
|
|
return {_ : {},
|
|
|
|
id: t.identifier,
|
2013-05-14 14:29:06 +00:00
|
|
|
x : t.pageX - elm.node.offsetX,
|
|
|
|
y : t.pageY - elm.node.offsetY,
|
2013-02-20 22:36:16 +00:00
|
|
|
x0: r.x,
|
|
|
|
y0: r.y,
|
|
|
|
t0: r.t
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2013-05-14 14:29:06 +00:00
|
|
|
var node = elm.display === ElmRuntime.Display.FULLSCREEN ? document : elm.node;
|
2013-05-06 00:51:30 +00:00
|
|
|
|
2013-02-20 22:36:16 +00:00
|
|
|
function start(e) {
|
2013-05-14 14:29:06 +00:00
|
|
|
dict.insert(e.identifier,
|
|
|
|
{x: e.pageX - elm.node.offsetX,
|
|
|
|
y: e.pageY - elm.node.offsetY,
|
|
|
|
t: Date.now()});
|
2013-02-20 22:36:16 +00:00
|
|
|
}
|
|
|
|
function end(e) {
|
|
|
|
var t = dict.remove(e.identifier);
|
|
|
|
if (Date.now() - t.t < tapTime) {
|
2013-05-14 14:29:06 +00:00
|
|
|
hasTap = true;
|
|
|
|
tap = {_:{}, x:t.x, y:t.y};
|
2013-02-20 22:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function listen(name, f) {
|
|
|
|
function update(e) {
|
|
|
|
for (var i = e.changedTouches.length; i--; ) { f(e.changedTouches[i]); }
|
|
|
|
var ts = new Array(e.touches.length);
|
|
|
|
for (var i = e.touches.length; i--; ) { ts[i] = touch(e.touches[i]); }
|
2013-06-03 06:46:02 +00:00
|
|
|
elm.notify(root.id, ts);
|
2013-02-20 22:36:16 +00:00
|
|
|
e.preventDefault();
|
|
|
|
}
|
2013-06-03 06:46:02 +00:00
|
|
|
elm.addListener([root.id], node, name, update);
|
2013-02-20 22:36:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
listen("touchstart", start);
|
|
|
|
listen("touchmove", function(_){});
|
|
|
|
listen("touchend", end);
|
|
|
|
listen("touchcancel", end);
|
|
|
|
listen("touchleave", end);
|
|
|
|
|
2013-05-06 02:17:29 +00:00
|
|
|
var mouseID = -1;
|
2013-05-06 00:51:30 +00:00
|
|
|
function move(e) {
|
|
|
|
for (var i = root.value.length; i--; ) {
|
2013-05-06 02:17:29 +00:00
|
|
|
if (root.value[i].id === mouseID) {
|
2013-05-14 14:29:06 +00:00
|
|
|
root.value[i].x = e.pageX - elm.node.offsetX;
|
|
|
|
root.value[i].y = e.pageY - elm.node.offsetY;
|
2013-05-06 00:51:30 +00:00
|
|
|
elm.notify(root.id, root.value);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-06-03 06:46:02 +00:00
|
|
|
elm.addListener([root.id], node, "mousedown", function down(e) {
|
2013-05-06 00:51:30 +00:00
|
|
|
node.addEventListener("mousemove", move);
|
2013-05-06 02:17:29 +00:00
|
|
|
e.identifier = mouseID;
|
2013-05-06 00:51:30 +00:00
|
|
|
start(e);
|
2013-05-21 08:03:51 +00:00
|
|
|
root.value.push(touch(e));
|
2013-05-06 00:51:30 +00:00
|
|
|
elm.notify(root.id, root.value);
|
|
|
|
});
|
2013-06-03 06:46:02 +00:00
|
|
|
elm.addListener([root.id], node, "mouseup", function up(e) {
|
2013-05-06 00:51:30 +00:00
|
|
|
node.removeEventListener("mousemove", move);
|
2013-05-06 02:17:29 +00:00
|
|
|
e.identifier = mouseID;
|
2013-05-06 00:51:30 +00:00
|
|
|
end(e);
|
|
|
|
for (var i = root.value.length; i--; ) {
|
2013-05-06 02:17:29 +00:00
|
|
|
if (root.value[i].id === mouseID) {
|
2013-05-06 00:51:30 +00:00
|
|
|
root.value.splice(i, 1);
|
2013-05-06 02:17:29 +00:00
|
|
|
--mouseID;
|
2013-05-06 00:51:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
elm.notify(root.id, root.value);
|
|
|
|
});
|
2013-06-03 06:46:02 +00:00
|
|
|
elm.addListener([root.id], node, "blur", function blur(e) {
|
2013-05-06 00:51:30 +00:00
|
|
|
node.removeEventListener("mousemove", move);
|
2013-07-15 02:11:02 +00:00
|
|
|
if (root.value.length > 0) {
|
2013-05-06 02:17:29 +00:00
|
|
|
elm.notify(root.id, []);
|
|
|
|
--mouseID;
|
|
|
|
}
|
2013-05-06 00:51:30 +00:00
|
|
|
dict.clear();
|
|
|
|
});
|
|
|
|
|
2013-02-20 22:36:16 +00:00
|
|
|
function dependency(f) {
|
2013-03-09 06:57:13 +00:00
|
|
|
var sig = A2( Signal.lift, f, root );
|
2013-02-20 22:36:16 +00:00
|
|
|
root.defaultNumberOfKids += 1;
|
|
|
|
sig.defaultNumberOfKids = 0;
|
|
|
|
return sig;
|
|
|
|
}
|
|
|
|
|
2013-05-06 00:51:30 +00:00
|
|
|
var touches = dependency(JS.toList);
|
2013-02-20 22:36:16 +00:00
|
|
|
|
|
|
|
var taps = function() {
|
|
|
|
var sig = dependency(function(_) { return tap; });
|
|
|
|
sig.defaultNumberOfKids = 1;
|
|
|
|
function pred(_) { var b = hasTap; hasTap = false; return b; }
|
2013-03-09 06:57:13 +00:00
|
|
|
var sig2 = A3( Signal.keepIf, pred, {_:{},x:0,y:0}, sig);
|
2013-02-20 22:36:16 +00:00
|
|
|
sig2.defaultNumberOfKids = 0;
|
|
|
|
return sig2;
|
|
|
|
}();
|
|
|
|
|
2013-09-30 08:32:27 +00:00
|
|
|
return elm.Native.Touch.values = { touches: touches, taps: taps };
|
2013-03-09 06:57:13 +00:00
|
|
|
|
|
|
|
};
|