commit extjs-2.2.1
[extjs.git] / source / widgets / tips / ToolTip.js
1 /*\r
2  * Ext JS Library 2.2.1\r
3  * Copyright(c) 2006-2009, Ext JS, LLC.\r
4  * licensing@extjs.com\r
5  * \r
6  * http://extjs.com/license\r
7  */\r
8 \r
9 /**\r
10  * @class Ext.ToolTip\r
11  * @extends Ext.Tip\r
12  * A standard tooltip implementation for providing additional information when hovering over a target element.\r
13  * @constructor\r
14  * Create a new Tooltip\r
15  * @param {Object} config The configuration options\r
16  */\r
17 Ext.ToolTip = Ext.extend(Ext.Tip, {\r
18     /**\r
19      * @cfg {Mixed} target The target HTMLElement, Ext.Element or id to associate with this tooltip.\r
20      */\r
21     /**\r
22      * @cfg {Boolean} autoHide True to automatically hide the tooltip after the mouse exits the target element\r
23      * or after the {@link #dismissDelay} has expired if set (defaults to true).  If {@link closable} = true a close\r
24      * tool button will be rendered into the tooltip header.\r
25      */\r
26     /**\r
27      * @cfg {Number} showDelay Delay in milliseconds before the tooltip displays after the mouse enters the\r
28      * target element (defaults to 500)\r
29      */\r
30     showDelay: 500,\r
31     /**\r
32      * @cfg {Number} hideDelay Delay in milliseconds after the mouse exits the target element but before the\r
33      * tooltip actually hides (defaults to 200).  Set to 0 for the tooltip to hide immediately.\r
34      */\r
35     hideDelay: 200,\r
36     /**\r
37      * @cfg {Number} dismissDelay Delay in milliseconds before the tooltip automatically hides (defaults to 5000).\r
38      * To disable automatic hiding, set dismissDelay = 0.\r
39      */\r
40     dismissDelay: 5000,\r
41     /**\r
42      * @cfg {Array} mouseOffset An XY offset from the mouse position where the tooltip should be shown (defaults to [15,18]).\r
43      */\r
44     mouseOffset: [15,18],\r
45     /**\r
46      * @cfg {Boolean} trackMouse True to have the tooltip follow the mouse as it moves over the target element (defaults to false).\r
47      */\r
48     trackMouse : false,\r
49     constrainPosition: true,\r
50 \r
51     // private\r
52     initComponent: function(){\r
53         Ext.ToolTip.superclass.initComponent.call(this);\r
54         this.lastActive = new Date();\r
55         this.initTarget();\r
56     },\r
57 \r
58     // private\r
59     initTarget : function(){\r
60         if(this.target){\r
61             this.target = Ext.get(this.target);\r
62             this.target.on('mouseover', this.onTargetOver, this);\r
63             this.target.on('mouseout', this.onTargetOut, this);\r
64             this.target.on('mousemove', this.onMouseMove, this);\r
65         }\r
66     },\r
67 \r
68     // private\r
69     onMouseMove : function(e){\r
70         this.targetXY = e.getXY();\r
71         if(!this.hidden && this.trackMouse){\r
72             this.setPagePosition(this.getTargetXY());\r
73         }\r
74     },\r
75 \r
76     // private\r
77     getTargetXY : function(){\r
78         return [this.targetXY[0]+this.mouseOffset[0], this.targetXY[1]+this.mouseOffset[1]];\r
79     },\r
80 \r
81     // private\r
82     onTargetOver : function(e){\r
83         if(this.disabled || e.within(this.target.dom, true)){\r
84             return;\r
85         }\r
86         this.clearTimer('hide');\r
87         this.targetXY = e.getXY();\r
88         this.delayShow();\r
89     },\r
90 \r
91     // private\r
92     delayShow : function(){\r
93         if(this.hidden && !this.showTimer){\r
94             if(this.lastActive.getElapsed() < this.quickShowInterval){\r
95                 this.show();\r
96             }else{\r
97                 this.showTimer = this.show.defer(this.showDelay, this);\r
98             }\r
99         }else if(!this.hidden && this.autoHide !== false){\r
100             this.show();\r
101         }\r
102     },\r
103 \r
104     // private\r
105     onTargetOut : function(e){\r
106         if(this.disabled || e.within(this.target.dom, true)){\r
107             return;\r
108         }\r
109         this.clearTimer('show');\r
110         if(this.autoHide !== false){\r
111             this.delayHide();\r
112         }\r
113     },\r
114 \r
115     // private\r
116     delayHide : function(){\r
117         if(!this.hidden && !this.hideTimer){\r
118             this.hideTimer = this.hide.defer(this.hideDelay, this);\r
119         }\r
120     },\r
121 \r
122     /**\r
123      * Hides this tooltip if visible.\r
124      */\r
125     hide: function(){\r
126         this.clearTimer('dismiss');\r
127         this.lastActive = new Date();\r
128         Ext.ToolTip.superclass.hide.call(this);\r
129     },\r
130 \r
131     /**\r
132      * Shows this tooltip at the current event target XY position.\r
133      */\r
134     show : function(){\r
135         this.showAt(this.getTargetXY());\r
136     },\r
137 \r
138     // inherit docs\r
139     showAt : function(xy){\r
140         this.lastActive = new Date();\r
141         this.clearTimers();\r
142         Ext.ToolTip.superclass.showAt.call(this, xy);\r
143         if(this.dismissDelay && this.autoHide !== false){\r
144             this.dismissTimer = this.hide.defer(this.dismissDelay, this);\r
145         }\r
146     },\r
147 \r
148     // private\r
149     clearTimer : function(name){\r
150         name = name + 'Timer';\r
151         clearTimeout(this[name]);\r
152         delete this[name];\r
153     },\r
154 \r
155     // private\r
156     clearTimers : function(){\r
157         this.clearTimer('show');\r
158         this.clearTimer('dismiss');\r
159         this.clearTimer('hide');\r
160     },\r
161 \r
162     // private\r
163     onShow : function(){\r
164         Ext.ToolTip.superclass.onShow.call(this);\r
165         Ext.getDoc().on('mousedown', this.onDocMouseDown, this);\r
166     },\r
167 \r
168     // private\r
169     onHide : function(){\r
170         Ext.ToolTip.superclass.onHide.call(this);\r
171         Ext.getDoc().un('mousedown', this.onDocMouseDown, this);\r
172     },\r
173 \r
174     // private\r
175     onDocMouseDown : function(e){\r
176         if(this.autoHide !== false && !e.within(this.el.dom)){\r
177             this.disable();\r
178             this.enable.defer(100, this);\r
179         }\r
180     },\r
181 \r
182     // private\r
183     onDisable : function(){\r
184         this.clearTimers();\r
185         this.hide();\r
186     },\r
187 \r
188     // private\r
189     adjustPosition : function(x, y){\r
190         // keep the position from being under the mouse\r
191         var ay = this.targetXY[1], h = this.getSize().height;\r
192         if(this.constrainPosition && y <= ay && (y+h) >= ay){\r
193             y = ay-h-5;\r
194         }\r
195         return {x : x, y: y};\r
196     },\r
197 \r
198     // private\r
199     onDestroy : function(){\r
200         Ext.ToolTip.superclass.onDestroy.call(this);\r
201         if(this.target){\r
202             this.target.un('mouseover', this.onTargetOver, this);\r
203             this.target.un('mouseout', this.onTargetOut, this);\r
204             this.target.un('mousemove', this.onMouseMove, this);\r
205         }\r
206     }\r
207 });