]> git.proxmox.com Git - sencha-touch.git/blame - src/src/util/Droppable.js
import Sencha Touch 2.4.2 source
[sencha-touch.git] / src / src / util / Droppable.js
CommitLineData
c4685c84
TL
1/**
2 *
3 */
4Ext.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});