3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.util.ClickRepeater
17 * @extends Ext.util.Observable
19 * A wrapper class which can be applied to any element. Fires a "click" event while the
20 * mouse is pressed. The interval between firings may be specified in the config but
21 * defaults to 20 milliseconds.
23 * Optionally, a CSS class may be applied to the element during the time it is pressed.
26 Ext.define('Ext.util.ClickRepeater', {
27 extend: 'Ext.util.Observable',
30 * Creates new ClickRepeater.
31 * @param {String/HTMLElement/Ext.Element} el The element or its ID to listen on
32 * @param {Object} config (optional) Config object.
34 constructor : function(el, config){
35 this.el = Ext.get(el);
36 this.el.unselectable();
38 Ext.apply(this, config);
43 * Fires when the mouse button is depressed.
44 * @param {Ext.util.ClickRepeater} this
45 * @param {Ext.EventObject} e
50 * Fires on a specified interval during the time the element is pressed.
51 * @param {Ext.util.ClickRepeater} this
52 * @param {Ext.EventObject} e
57 * Fires when the mouse key is released.
58 * @param {Ext.util.ClickRepeater} this
59 * @param {Ext.EventObject} e
69 // allow inline handler
71 this.on("click", this.handler, this.scope || this);
78 * @cfg {String/HTMLElement/Ext.Element} el The element to act as a button.
82 * @cfg {String} pressedCls A CSS class name to be applied to the element while pressed.
86 * @cfg {Boolean} accelerate True if autorepeating should start slowly and accelerate.
87 * "interval" and "delay" are ignored.
91 * @cfg {Number} interval The interval between firings of the "click" event. Default 20 ms.
96 * @cfg {Number} delay The initial delay before the repeating event begins firing.
97 * Similar to an autorepeat key delay.
102 * @cfg {Boolean} preventDefault True to prevent the default click event
104 preventDefault : true,
106 * @cfg {Boolean} stopDefault True to stop the default click event
113 * Enables the repeater and allows events to fire.
117 this.el.on('mousedown', this.handleMouseDown, this);
119 this.el.on('dblclick', this.handleDblClick, this);
121 if(this.preventDefault || this.stopDefault){
122 this.el.on('click', this.eventOptions, this);
125 this.disabled = false;
129 * Disables the repeater and stops events from firing.
131 disable: function(/* private */ force){
132 if(force || !this.disabled){
133 clearTimeout(this.timer);
135 this.el.removeCls(this.pressedCls);
137 Ext.getDoc().un('mouseup', this.handleMouseUp, this);
138 this.el.removeAllListeners();
140 this.disabled = true;
144 * Convenience function for setting disabled/enabled by boolean.
145 * @param {Boolean} disabled
147 setDisabled: function(disabled){
148 this[disabled ? 'disable' : 'enable']();
151 eventOptions: function(e){
152 if(this.preventDefault){
155 if(this.stopDefault){
161 destroy : function() {
163 Ext.destroy(this.el);
164 this.clearListeners();
167 handleDblClick : function(e){
168 clearTimeout(this.timer);
171 this.fireEvent("mousedown", this, e);
172 this.fireEvent("click", this, e);
176 handleMouseDown : function(e){
177 clearTimeout(this.timer);
180 this.el.addCls(this.pressedCls);
182 this.mousedownTime = new Date();
184 Ext.getDoc().on("mouseup", this.handleMouseUp, this);
185 this.el.on("mouseout", this.handleMouseOut, this);
187 this.fireEvent("mousedown", this, e);
188 this.fireEvent("click", this, e);
190 // Do not honor delay or interval if acceleration wanted.
191 if (this.accelerate) {
195 // Re-wrap the event object in a non-shared object, so it doesn't lose its context if
196 // the global shared EventObject gets a new Event put into it before the timer fires.
197 e = new Ext.EventObjectImpl(e);
199 this.timer = Ext.defer(this.click, this.delay || this.interval, this, [e]);
204 this.fireEvent("click", this, e);
205 this.timer = Ext.defer(this.click, this.accelerate ?
206 this.easeOutExpo(Ext.Date.getElapsed(this.mousedownTime),
210 this.interval, this, [e]);
213 easeOutExpo : function (t, b, c, d) {
214 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
218 handleMouseOut : function(){
219 clearTimeout(this.timer);
221 this.el.removeCls(this.pressedCls);
223 this.el.on("mouseover", this.handleMouseReturn, this);
227 handleMouseReturn : function(){
228 this.el.un("mouseover", this.handleMouseReturn, this);
230 this.el.addCls(this.pressedCls);
236 handleMouseUp : function(e){
237 clearTimeout(this.timer);
238 this.el.un("mouseover", this.handleMouseReturn, this);
239 this.el.un("mouseout", this.handleMouseOut, this);
240 Ext.getDoc().un("mouseup", this.handleMouseUp, this);
242 this.el.removeCls(this.pressedCls);
244 this.fireEvent("mouseup", this, e);