]>
Commit | Line | Data |
---|---|---|
c4685c84 TL |
1 | /** |
2 | * | |
3 | */ | |
4 | Ext.define('Ext.util.Droppable', { | |
5 | mixins: { | |
6 | observable: 'Ext.mixin.Observable' | |
7 | }, | |
8 | ||
9 | config: { | |
10 | /** | |
11 | * The base CSS class to apply to this component's element. | |
12 | * This will also be prepended to other elements within this component. | |
13 | */ | |
14 | baseCls: Ext.baseCSSPrefix + 'droppable' | |
15 | }, | |
16 | ||
17 | /** | |
18 | * @cfg {String} activeCls | |
19 | * The CSS added to a Droppable when a Draggable in the same group is being | |
20 | * dragged. | |
21 | */ | |
22 | activeCls: Ext.baseCSSPrefix + 'drop-active', | |
23 | ||
24 | /** | |
25 | * @cfg {String} invalidCls | |
26 | * The CSS class to add to the droppable when dragging a draggable that is | |
27 | * not in the same group. | |
28 | */ | |
29 | invalidCls: Ext.baseCSSPrefix + 'drop-invalid', | |
30 | ||
31 | /** | |
32 | * @cfg {String} hoverCls | |
33 | * The CSS class to add to the droppable when hovering over a valid drop. | |
34 | */ | |
35 | hoverCls: Ext.baseCSSPrefix + 'drop-hover', | |
36 | ||
37 | /** | |
38 | * @cfg {String} validDropMode | |
39 | * Determines when a drop is considered 'valid' whether it simply need to | |
40 | * intersect the region or if it needs to be contained within the region. | |
41 | * Valid values are: 'intersects' or 'contains' | |
42 | */ | |
43 | validDropMode: 'intersect', | |
44 | ||
45 | /** | |
46 | * @cfg {Boolean} disabled | |
47 | */ | |
48 | disabled: false, | |
49 | ||
50 | /** | |
51 | * @cfg {String} group | |
52 | * Draggable and Droppable objects can participate in a group which are | |
53 | * capable of interacting. | |
54 | */ | |
55 | group: 'base', | |
56 | ||
57 | // not yet implemented | |
58 | tolerance: null, | |
59 | ||
60 | // @private | |
61 | monitoring: false, | |
62 | ||
63 | /** | |
64 | * Creates new Droppable. | |
65 | * @param {Mixed} el String, HtmlElement or Ext.Element representing an | |
66 | * element on the page. | |
67 | * @param {Object} config Configuration options for this class. | |
68 | */ | |
69 | constructor: function(el, config) { | |
70 | var me = this; | |
71 | ||
72 | config = config || {}; | |
73 | Ext.apply(me, config); | |
74 | ||
75 | /** | |
76 | * @event dropactivate | |
77 | * @param {Ext.util.Droppable} this | |
78 | * @param {Ext.util.Draggable} draggable | |
79 | * @param {Ext.event.Event} e | |
80 | */ | |
81 | ||
82 | /** | |
83 | * @event dropdeactivate | |
84 | * @param {Ext.util.Droppable} this | |
85 | * @param {Ext.util.Draggable} draggable | |
86 | * @param {Ext.event.Event} e | |
87 | */ | |
88 | ||
89 | /** | |
90 | * @event dropenter | |
91 | * @param {Ext.util.Droppable} this | |
92 | * @param {Ext.util.Draggable} draggable | |
93 | * @param {Ext.event.Event} e | |
94 | */ | |
95 | ||
96 | /** | |
97 | * @event dropleave | |
98 | * @param {Ext.util.Droppable} this | |
99 | * @param {Ext.util.Draggable} draggable | |
100 | * @param {Ext.event.Event} e | |
101 | */ | |
102 | ||
103 | /** | |
104 | * @event drop | |
105 | * @param {Ext.util.Droppable} this | |
106 | * @param {Ext.util.Draggable} draggable | |
107 | * @param {Ext.event.Event} e | |
108 | */ | |
109 | ||
110 | me.el = Ext.get(el); | |
111 | me.callParent(); | |
112 | ||
113 | me.mixins.observable.constructor.call(me); | |
114 | ||
115 | if (!me.disabled) { | |
116 | me.enable(); | |
117 | } | |
118 | ||
119 | me.el.addCls(me.baseCls); | |
120 | }, | |
121 | ||
122 | // @private | |
123 | onDragStart: function(draggable, e) { | |
124 | if (draggable.group === this.group) { | |
125 | this.monitoring = true; | |
126 | this.el.addCls(this.activeCls); | |
127 | this.region = this.el.getPageBox(true); | |
128 | ||
129 | draggable.on({ | |
130 | drag: this.onDrag, | |
131 | beforedragend: this.onBeforeDragEnd, | |
132 | dragend: this.onDragEnd, | |
133 | scope: this | |
134 | }); | |
135 | ||
136 | if (this.isDragOver(draggable)) { | |
137 | this.setCanDrop(true, draggable, e); | |
138 | } | |
139 | ||
140 | this.fireEvent('dropactivate', this, draggable, e); | |
141 | } | |
142 | else { | |
143 | draggable.on({ | |
144 | dragend: function() { | |
145 | this.el.removeCls(this.invalidCls); | |
146 | }, | |
147 | scope: this, | |
148 | single: true | |
149 | }); | |
150 | this.el.addCls(this.invalidCls); | |
151 | } | |
152 | }, | |
153 | ||
154 | // @private | |
155 | isDragOver: function(draggable, region) { | |
156 | return this.region[this.validDropMode](draggable.region); | |
157 | }, | |
158 | ||
159 | // @private | |
160 | onDrag: function(draggable, e) { | |
161 | this.setCanDrop(this.isDragOver(draggable), draggable, e); | |
162 | }, | |
163 | ||
164 | // @private | |
165 | setCanDrop: function(canDrop, draggable, e) { | |
166 | if (canDrop && !this.canDrop) { | |
167 | this.canDrop = true; | |
168 | this.el.addCls(this.hoverCls); | |
169 | this.fireEvent('dropenter', this, draggable, e); | |
170 | } | |
171 | else if (!canDrop && this.canDrop) { | |
172 | this.canDrop = false; | |
173 | this.el.removeCls(this.hoverCls); | |
174 | this.fireEvent('dropleave', this, draggable, e); | |
175 | } | |
176 | }, | |
177 | ||
178 | // @private | |
179 | onBeforeDragEnd: function(draggable, e) { | |
180 | draggable.cancelRevert = this.canDrop; | |
181 | }, | |
182 | ||
183 | // @private | |
184 | onDragEnd: function(draggable, e) { | |
185 | this.monitoring = false; | |
186 | this.el.removeCls(this.activeCls); | |
187 | ||
188 | draggable.un({ | |
189 | drag: this.onDrag, | |
190 | beforedragend: this.onBeforeDragEnd, | |
191 | dragend: this.onDragEnd, | |
192 | scope: this | |
193 | }); | |
194 | ||
195 | ||
196 | if (this.canDrop) { | |
197 | this.canDrop = false; | |
198 | this.el.removeCls(this.hoverCls); | |
199 | this.fireEvent('drop', this, draggable, e); | |
200 | } | |
201 | ||
202 | this.fireEvent('dropdeactivate', this, draggable, e); | |
203 | }, | |
204 | ||
205 | /** | |
206 | * Enable the Droppable target. | |
207 | * This is invoked immediately after constructing a Droppable if the | |
208 | * disabled parameter is NOT set to true. | |
209 | */ | |
210 | enable: function() { | |
211 | if (!this.mgr) { | |
212 | this.mgr = Ext.util.Observable.observe(Ext.util.Draggable); | |
213 | } | |
214 | this.mgr.on({ | |
215 | dragstart: this.onDragStart, | |
216 | scope: this | |
217 | }); | |
218 | this.disabled = false; | |
219 | }, | |
220 | ||
221 | /** | |
222 | * Disable the Droppable target. | |
223 | */ | |
224 | disable: function() { | |
225 | this.mgr.un({ | |
226 | dragstart: this.onDragStart, | |
227 | scope: this | |
228 | }); | |
229 | this.disabled = true; | |
230 | }, | |
231 | ||
232 | /** | |
233 | * Method to determine whether this Component is currently disabled. | |
234 | * @return {Boolean} the disabled state of this Component. | |
235 | */ | |
236 | isDisabled: function() { | |
237 | return this.disabled; | |
238 | }, | |
239 | ||
240 | /** | |
241 | * Method to determine whether this Droppable is currently monitoring drag operations of Draggables. | |
242 | * @return {Boolean} the monitoring state of this Droppable | |
243 | */ | |
244 | isMonitoring: function() { | |
245 | return this.monitoring; | |
246 | } | |
247 | }); |