Upgrade to ExtJS 3.2.1 - Released 04/27/2010
[extjs.git] / src / widgets / tree / TreeEventModel.js
1 /*!
2  * Ext JS Library 3.2.1
3  * Copyright(c) 2006-2010 Ext JS, Inc.
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 Ext.tree.TreeEventModel = function(tree){
8     this.tree = tree;
9     this.tree.on('render', this.initEvents, this);
10 };
11
12 Ext.tree.TreeEventModel.prototype = {
13     initEvents : function(){
14         var t = this.tree;
15
16         if(t.trackMouseOver !== false){
17             t.mon(t.innerCt, {
18                 scope: this,
19                 mouseover: this.delegateOver,
20                 mouseout: this.delegateOut
21             });
22         }
23         t.mon(t.getTreeEl(), {
24             scope: this,
25             click: this.delegateClick,
26             dblclick: this.delegateDblClick,
27             contextmenu: this.delegateContextMenu
28         });
29     },
30
31     getNode : function(e){
32         var t;
33         if(t = e.getTarget('.x-tree-node-el', 10)){
34             var id = Ext.fly(t, '_treeEvents').getAttribute('tree-node-id', 'ext');
35             if(id){
36                 return this.tree.getNodeById(id);
37             }
38         }
39         return null;
40     },
41
42     getNodeTarget : function(e){
43         var t = e.getTarget('.x-tree-node-icon', 1);
44         if(!t){
45             t = e.getTarget('.x-tree-node-el', 6);
46         }
47         return t;
48     },
49
50     delegateOut : function(e, t){
51         if(!this.beforeEvent(e)){
52             return;
53         }
54         if(e.getTarget('.x-tree-ec-icon', 1)){
55             var n = this.getNode(e);
56             this.onIconOut(e, n);
57             if(n == this.lastEcOver){
58                 delete this.lastEcOver;
59             }
60         }
61         if((t = this.getNodeTarget(e)) && !e.within(t, true)){
62             this.onNodeOut(e, this.getNode(e));
63         }
64     },
65
66     delegateOver : function(e, t){
67         if(!this.beforeEvent(e)){
68             return;
69         }
70         if(Ext.isGecko && !this.trackingDoc){ // prevent hanging in FF
71             Ext.getBody().on('mouseover', this.trackExit, this);
72             this.trackingDoc = true;
73         }
74         if(this.lastEcOver){ // prevent hung highlight
75             this.onIconOut(e, this.lastEcOver);
76             delete this.lastEcOver;
77         }
78         if(e.getTarget('.x-tree-ec-icon', 1)){
79             this.lastEcOver = this.getNode(e);
80             this.onIconOver(e, this.lastEcOver);
81         }
82         if(t = this.getNodeTarget(e)){
83             this.onNodeOver(e, this.getNode(e));
84         }
85     },
86
87     trackExit : function(e){
88         if(this.lastOverNode){
89             if(this.lastOverNode.ui && !e.within(this.lastOverNode.ui.getEl())){
90                 this.onNodeOut(e, this.lastOverNode);
91             }
92             delete this.lastOverNode;
93             Ext.getBody().un('mouseover', this.trackExit, this);
94             this.trackingDoc = false;
95         }
96
97     },
98
99     delegateClick : function(e, t){
100         if(this.beforeEvent(e)){
101             if(e.getTarget('input[type=checkbox]', 1)){
102                 this.onCheckboxClick(e, this.getNode(e));
103             }else if(e.getTarget('.x-tree-ec-icon', 1)){
104                 this.onIconClick(e, this.getNode(e));
105             }else if(this.getNodeTarget(e)){
106                 this.onNodeClick(e, this.getNode(e));
107             }
108         }else{
109             this.checkContainerEvent(e, 'click');
110         }
111     },
112
113     delegateDblClick : function(e, t){
114         if(this.beforeEvent(e)){
115             if(this.getNodeTarget(e)){
116                 this.onNodeDblClick(e, this.getNode(e));
117             }
118         }else{
119             this.checkContainerEvent(e, 'dblclick');
120         }
121     },
122
123     delegateContextMenu : function(e, t){
124         if(this.beforeEvent(e)){
125             if(this.getNodeTarget(e)){
126                 this.onNodeContextMenu(e, this.getNode(e));
127             }
128         }else{
129             this.checkContainerEvent(e, 'contextmenu');
130         }
131     },
132     
133     checkContainerEvent: function(e, type){
134         if(this.disabled){
135             e.stopEvent();
136             return false;
137         }
138         this.onContainerEvent(e, type);    
139     },
140
141     onContainerEvent: function(e, type){
142         this.tree.fireEvent('container' + type, this.tree, e);
143     },
144
145     onNodeClick : function(e, node){
146         node.ui.onClick(e);
147     },
148
149     onNodeOver : function(e, node){
150         this.lastOverNode = node;
151         node.ui.onOver(e);
152     },
153
154     onNodeOut : function(e, node){
155         node.ui.onOut(e);
156     },
157
158     onIconOver : function(e, node){
159         node.ui.addClass('x-tree-ec-over');
160     },
161
162     onIconOut : function(e, node){
163         node.ui.removeClass('x-tree-ec-over');
164     },
165
166     onIconClick : function(e, node){
167         node.ui.ecClick(e);
168     },
169
170     onCheckboxClick : function(e, node){
171         node.ui.onCheckChange(e);
172     },
173
174     onNodeDblClick : function(e, node){
175         node.ui.onDblClick(e);
176     },
177
178     onNodeContextMenu : function(e, node){
179         node.ui.onContextMenu(e);
180     },
181
182     beforeEvent : function(e){
183         var node = this.getNode(e);
184         if(this.disabled || !node || !node.ui){
185             e.stopEvent();
186             return false;
187         }
188         return true;
189     },
190
191     disable: function(){
192         this.disabled = true;
193     },
194
195     enable: function(){
196         this.disabled = false;
197     }
198 };