2014-01-30 17:49:15 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the Doodle3D project (http://doodle3d.com).
|
|
|
|
*
|
|
|
|
* Copyright (c) 2013, Doodle3D
|
|
|
|
* This software is licensed under the terms of the GNU GPL v2 or later.
|
|
|
|
* See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details.
|
|
|
|
*/
|
|
|
|
|
2014-01-30 15:45:03 +01:00
|
|
|
// prototype inheritance
|
|
|
|
// http://robertnyman.com/2008/10/06/javascript-inheritance-how-and-why/
|
2014-01-31 14:34:44 +01:00
|
|
|
Button.prototype = new jQuery();
|
2014-01-30 15:45:03 +01:00
|
|
|
function Button() {
|
|
|
|
|
2014-02-02 00:37:05 +01:00
|
|
|
this.enabled = true;
|
2014-01-31 15:21:05 +01:00
|
|
|
|
2014-01-30 15:45:03 +01:00
|
|
|
var _clickEnabled = true;
|
|
|
|
var _downTimerFPS = 20;
|
2014-01-31 14:34:44 +01:00
|
|
|
var _timer;
|
2014-01-30 15:45:03 +01:00
|
|
|
var _x,_y;
|
|
|
|
var _isDown = false;
|
|
|
|
var _self = this;
|
|
|
|
|
|
|
|
// call jQuery constuctor
|
|
|
|
// http://blog.santoshrajan.com/2008/10/what-john-resig-did-not-tell-you.html
|
|
|
|
this.constructor.prototype.init.apply(this, arguments);
|
|
|
|
|
|
|
|
// prevent multiple event handlers etc
|
|
|
|
// make sure you do a more general conversion last
|
2014-01-31 14:34:44 +01:00
|
|
|
if(this.data("isButton")) {
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
this.data("isButton",true);
|
|
|
|
}
|
2014-01-30 15:45:03 +01:00
|
|
|
|
|
|
|
this.enable = function() {
|
2014-02-02 01:03:07 +01:00
|
|
|
if(_self.enabled === true) { return; }
|
2014-01-30 15:45:03 +01:00
|
|
|
_self.removeClass("disabled");
|
|
|
|
_self.enabled = true;
|
2014-01-31 14:34:44 +01:00
|
|
|
};
|
2014-01-30 15:45:03 +01:00
|
|
|
this.disable = function() {
|
2014-01-31 15:21:05 +01:00
|
|
|
if(_self.enabled === false) { return; }
|
2014-01-30 15:45:03 +01:00
|
|
|
_self.addClass("disabled");
|
|
|
|
_self.enabled = false;
|
2014-01-31 14:34:44 +01:00
|
|
|
};
|
2014-02-02 01:03:07 +01:00
|
|
|
// if the element starts with a disable class, we properly disable it
|
|
|
|
if(this.hasClass("disabled")) {
|
|
|
|
this.disable();
|
|
|
|
}
|
2014-01-30 15:45:03 +01:00
|
|
|
|
|
|
|
function updateCursor(e) {
|
|
|
|
// retrieve cursor position relative to element
|
2014-01-31 14:34:44 +01:00
|
|
|
if (e.offsetX !== undefined) {
|
2014-01-30 15:45:03 +01:00
|
|
|
_x = e.offsetX;
|
|
|
|
_y = e.offsetY;
|
2014-01-31 14:34:44 +01:00
|
|
|
} else {
|
2014-01-30 15:45:03 +01:00
|
|
|
var offset = _self.offset();
|
2014-01-31 14:34:44 +01:00
|
|
|
if(e.pageX !== undefined) {
|
|
|
|
// http://www.quirksmode.org/mobile/tableViewport_desktop.html#t11
|
|
|
|
_x = e.pageX - offset.left;
|
|
|
|
_y = e.pageY - offset.top;
|
|
|
|
} else if(e.originalEvent !== undefined && e.originalEvent.pageX !== undefined) {
|
|
|
|
//http://css-tricks.com/the-javascript-behind-touch-friendly-sliders/
|
|
|
|
_x = e.originalEvent.pageX - offset.left;
|
|
|
|
_y = e.originalEvent.pageY - offset.top;
|
|
|
|
}
|
2014-01-30 15:45:03 +01:00
|
|
|
|
2014-01-31 14:34:44 +01:00
|
|
|
//android+chrome-specific hack
|
|
|
|
if (e.originalEvent.changedTouches !== undefined) {
|
|
|
|
_x = e.originalEvent.changedTouches[0].pageX - offset.left;
|
|
|
|
_y = e.originalEvent.changedTouches[0].pageY - offset.top;
|
|
|
|
}
|
2014-01-09 17:05:03 +01:00
|
|
|
}
|
2014-01-30 15:45:03 +01:00
|
|
|
}
|
|
|
|
function startDownTimer() {
|
2014-01-31 14:34:44 +01:00
|
|
|
if (_timer === undefined) {
|
2014-01-30 15:45:03 +01:00
|
|
|
_timer = setInterval(onDownTimerInterval, 1000/_downTimerFPS);
|
|
|
|
_isDown = true;
|
2014-01-09 17:05:03 +01:00
|
|
|
}
|
2014-01-30 15:45:03 +01:00
|
|
|
}
|
|
|
|
function stopDownTimer() {
|
|
|
|
clearInterval(_timer);
|
|
|
|
_timer = undefined;
|
|
|
|
_isDown = false;
|
|
|
|
// _x = undefined;
|
|
|
|
// _y = undefined;
|
|
|
|
}
|
|
|
|
function onDownTimerInterval() {
|
2014-01-31 14:34:44 +01:00
|
|
|
if(!_self.enabled) { return; }
|
|
|
|
if (_x !== undefined && _y !== undefined) {
|
2014-01-30 15:45:03 +01:00
|
|
|
_self.trigger("onButtonHold",{x:_x,y:_y});
|
|
|
|
} else {
|
|
|
|
console.log("Button: warning... _x or _y not set...");
|
2014-01-09 17:05:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-30 15:45:03 +01:00
|
|
|
// Event handlers
|
|
|
|
$(document).mouseup(function(e) {
|
|
|
|
stopDownTimer();
|
|
|
|
});
|
|
|
|
this.on("touchstart", function(e) {
|
2014-01-31 14:34:44 +01:00
|
|
|
if(!_self.enabled) { return; }
|
2014-01-30 15:45:03 +01:00
|
|
|
_clickEnabled = false;
|
|
|
|
updateCursor(e);
|
|
|
|
startDownTimer();
|
|
|
|
_self.trigger("onButtonClick",{x:_x,y:_y});
|
|
|
|
e.preventDefault();
|
|
|
|
});
|
|
|
|
this.on("touchend", function(e) {
|
|
|
|
updateCursor(e);
|
|
|
|
stopDownTimer();
|
|
|
|
});
|
|
|
|
this.on("touchmove", function(e) {
|
2014-01-31 14:34:44 +01:00
|
|
|
if(!_self.enabled) { return; }
|
2014-01-30 15:45:03 +01:00
|
|
|
updateCursor(e);
|
|
|
|
startDownTimer();
|
|
|
|
});
|
|
|
|
this.mousedown(function(e) {
|
2014-01-31 14:34:44 +01:00
|
|
|
if(!_self.enabled) { return; }
|
2014-01-30 15:45:03 +01:00
|
|
|
updateCursor(e);
|
|
|
|
startDownTimer();
|
|
|
|
});
|
|
|
|
this.mouseup(function(e) {
|
|
|
|
updateCursor(e);
|
|
|
|
stopDownTimer();
|
|
|
|
});
|
|
|
|
this.mousemove(function(e) {
|
2014-01-31 14:34:44 +01:00
|
|
|
if(!_self.enabled) { return; }
|
2014-01-30 15:45:03 +01:00
|
|
|
updateCursor(e);
|
|
|
|
//if (_isDown) mousedrag(e);
|
|
|
|
});
|
|
|
|
//this.mousedrag(function(e) {
|
|
|
|
// updateCursor(e);
|
|
|
|
//});
|
|
|
|
this.contextmenu(function(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
});
|
|
|
|
this.click(function(e) {
|
2014-01-31 14:34:44 +01:00
|
|
|
if(!_self.enabled || !_clickEnabled) { return; }
|
2014-01-30 15:45:03 +01:00
|
|
|
updateCursor(e);
|
|
|
|
stopDownTimer();
|
|
|
|
_self.trigger("onButtonClick",{x:_x,y:_y});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// to work with multiple objects we need a jQuery plugin
|
|
|
|
$.fn.Button = function() {
|
|
|
|
return $(this).each(function(){
|
|
|
|
new Button(this);
|
|
|
|
});
|
2014-01-31 14:34:44 +01:00
|
|
|
};
|