]> git.proxmox.com Git - sencha-touch.git/blob - src/src/util/TapRepeater.js
import Sencha Touch 2.4.2 source
[sencha-touch.git] / src / src / util / TapRepeater.js
1 /**
2 * A wrapper class which can be applied to any element. Fires a "tap" event while
3 * touching the device. The interval between firings may be specified in the config but
4 * defaults to 20 milliseconds.
5 */
6 Ext.define('Ext.util.TapRepeater', {
7 requires: ['Ext.DateExtras'],
8
9 mixins: {
10 observable: 'Ext.mixin.Observable'
11 },
12
13 /**
14 * @event touchstart
15 * Fires when the touch is started.
16 * @param {Ext.util.TapRepeater} this
17 * @param {Ext.event.Event} e
18 */
19
20 /**
21 * @event tap
22 * Fires on a specified interval during the time the element is pressed.
23 * @param {Ext.util.TapRepeater} this
24 * @param {Ext.event.Event} e
25 */
26
27 /**
28 * @event touchend
29 * Fires when the touch is ended.
30 * @param {Ext.util.TapRepeater} this
31 * @param {Ext.event.Event} e
32 */
33
34 config: {
35 el: null,
36 accelerate: true,
37 interval: 10,
38 delay: 250,
39 preventDefault: true,
40 stopDefault: false,
41 timer: 0,
42 pressCls: null
43 },
44
45 /**
46 * Creates new TapRepeater.
47 * @param {Object} config
48 */
49 constructor: function(config) {
50 var me = this;
51 //<debug warn>
52 for (var configName in config) {
53 if (me.self.prototype.config && !(configName in me.self.prototype.config)) {
54 me[configName] = config[configName];
55 Ext.Logger.warn('Applied config as instance property: "' + configName + '"', me);
56 }
57 }
58 //</debug>
59 me.initConfig(config);
60 },
61
62 updateEl: function(newEl, oldEl) {
63 var eventCfg = {
64 touchstart: 'onTouchStart',
65 touchend: 'onTouchEnd',
66 tap: 'eventOptions',
67 scope: this
68 };
69 if (oldEl) {
70 oldEl.un(eventCfg)
71 }
72 newEl.on(eventCfg);
73 },
74
75 // @private
76 eventOptions: function(e) {
77 if (this.getPreventDefault()) {
78 e.preventDefault();
79 }
80 if (this.getStopDefault()) {
81 e.stopEvent();
82 }
83 },
84
85 // @private
86 destroy: function() {
87 this.clearListeners();
88 Ext.destroy(this.el);
89 },
90
91 // @private
92 onTouchStart: function(e) {
93 var me = this,
94 pressCls = me.getPressCls();
95 clearTimeout(me.getTimer());
96 if (pressCls) {
97 me.getEl().addCls(pressCls);
98 }
99 me.tapStartTime = new Date();
100
101 me.fireEvent('touchstart', me, e);
102 me.fireEvent('tap', me, e);
103
104 // Do not honor delay or interval if acceleration wanted.
105 if (me.getAccelerate()) {
106 me.delay = 400;
107 }
108 me.setTimer(Ext.defer(me.tap, me.getDelay() || me.getInterval(), me, [e]));
109 },
110
111 // @private
112 tap: function(e) {
113 var me = this;
114 me.fireEvent('tap', me, e);
115 me.setTimer(Ext.defer(me.tap, me.getAccelerate() ? me.easeOutExpo(Ext.Date.getElapsed(me.tapStartTime),
116 400,
117 -390,
118 12000) : me.getInterval(), me, [e]));
119 },
120
121 // Easing calculation
122 // @private
123 easeOutExpo: function(t, b, c, d) {
124 return (t == d) ? b + c : c * ( - Math.pow(2, -10 * t / d) + 1) + b;
125 },
126
127 // @private
128 onTouchEnd: function(e) {
129 var me = this;
130 clearTimeout(me.getTimer());
131 me.getEl().removeCls(me.getPressCls());
132 me.fireEvent('touchend', me, e);
133 }
134 });