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.dd.DragSource
17 * @extends Ext.dd.DDProxy
18 * A simple class that provides the basic implementation needed to make any element draggable.
20 Ext.define('Ext.dd.DragSource', {
21 extend: 'Ext.dd.DDProxy',
24 'Ext.dd.DragDropManager'
28 * @cfg {String} ddGroup
29 * A named drag drop group to which this object belongs. If a group is specified, then this object will only
30 * interact with other drag drop objects in the same group.
34 * @cfg {String} [dropAllowed="x-dd-drop-ok"]
35 * The CSS class returned to the drag source when drop is allowed.
37 dropAllowed : Ext.baseCSSPrefix + 'dd-drop-ok',
39 * @cfg {String} [dropNotAllowed="x-dd-drop-nodrop"]
40 * The CSS class returned to the drag source when drop is not allowed.
42 dropNotAllowed : Ext.baseCSSPrefix + 'dd-drop-nodrop',
45 * @cfg {Boolean} animRepair
46 * If true, animates the proxy element back to the position of the handle element used to trigger the drag.
51 * @cfg {String} repairHighlightColor
52 * The color to use when visually highlighting the drag source in the afterRepair
53 * method after a failed drop (defaults to light blue). The color must be a 6 digit hex value, without
56 repairHighlightColor: 'c3daf9',
59 * Creates new drag-source.
61 * @param {String/HTMLElement/Ext.Element} el The container element or ID of it.
62 * @param {Object} config (optional) Config object.
64 constructor: function(el, config) {
65 this.el = Ext.get(el);
70 Ext.apply(this, config);
73 this.proxy = Ext.create('Ext.dd.StatusProxy', {
74 animRepair: this.animRepair
77 this.callParent([this.el.dom, this.ddGroup || this.group,
78 {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true}]);
80 this.dragging = false;
84 * Returns the data object associated with this drag source
85 * @return {Object} data An object containing arbitrary data
87 getDragData : function(e){
92 onDragEnter : function(e, id){
93 var target = Ext.dd.DragDropManager.getDDById(id);
94 this.cachedTarget = target;
95 if (this.beforeDragEnter(target, e, id) !== false) {
96 if (target.isNotifyTarget) {
97 var status = target.notifyEnter(this, e, this.dragData);
98 this.proxy.setStatus(status);
100 this.proxy.setStatus(this.dropAllowed);
103 if (this.afterDragEnter) {
105 * An empty function by default, but provided so that you can perform a custom action
106 * when the dragged item enters the drop target by providing an implementation.
107 * @param {Ext.dd.DragDrop} target The drop target
108 * @param {Event} e The event object
109 * @param {String} id The id of the dragged element
110 * @method afterDragEnter
112 this.afterDragEnter(target, e, id);
118 * An empty function by default, but provided so that you can perform a custom action
119 * before the dragged item enters the drop target and optionally cancel the onDragEnter.
120 * @param {Ext.dd.DragDrop} target The drop target
121 * @param {Event} e The event object
122 * @param {String} id The id of the dragged element
123 * @return {Boolean} isValid True if the drag event is valid, else false to cancel
125 beforeDragEnter: function(target, e, id) {
130 alignElWithMouse: function() {
131 this.callParent(arguments);
136 onDragOver: function(e, id) {
137 var target = this.cachedTarget || Ext.dd.DragDropManager.getDDById(id);
138 if (this.beforeDragOver(target, e, id) !== false) {
139 if(target.isNotifyTarget){
140 var status = target.notifyOver(this, e, this.dragData);
141 this.proxy.setStatus(status);
144 if (this.afterDragOver) {
146 * An empty function by default, but provided so that you can perform a custom action
147 * while the dragged item is over the drop target by providing an implementation.
148 * @param {Ext.dd.DragDrop} target The drop target
149 * @param {Event} e The event object
150 * @param {String} id The id of the dragged element
151 * @method afterDragOver
153 this.afterDragOver(target, e, id);
159 * An empty function by default, but provided so that you can perform a custom action
160 * while the dragged item is over the drop target and optionally cancel the onDragOver.
161 * @param {Ext.dd.DragDrop} target The drop target
162 * @param {Event} e The event object
163 * @param {String} id The id of the dragged element
164 * @return {Boolean} isValid True if the drag event is valid, else false to cancel
166 beforeDragOver: function(target, e, id) {
171 onDragOut: function(e, id) {
172 var target = this.cachedTarget || Ext.dd.DragDropManager.getDDById(id);
173 if (this.beforeDragOut(target, e, id) !== false) {
174 if (target.isNotifyTarget) {
175 target.notifyOut(this, e, this.dragData);
178 if (this.afterDragOut) {
180 * An empty function by default, but provided so that you can perform a custom action
181 * after the dragged item is dragged out of the target without dropping.
182 * @param {Ext.dd.DragDrop} target The drop target
183 * @param {Event} e The event object
184 * @param {String} id The id of the dragged element
185 * @method afterDragOut
187 this.afterDragOut(target, e, id);
190 this.cachedTarget = null;
194 * An empty function by default, but provided so that you can perform a custom action before the dragged
195 * item is dragged out of the target without dropping, and optionally cancel the onDragOut.
196 * @param {Ext.dd.DragDrop} target The drop target
197 * @param {Event} e The event object
198 * @param {String} id The id of the dragged element
199 * @return {Boolean} isValid True if the drag event is valid, else false to cancel
201 beforeDragOut: function(target, e, id){
206 onDragDrop: function(e, id){
207 var target = this.cachedTarget || Ext.dd.DragDropManager.getDDById(id);
208 if (this.beforeDragDrop(target, e, id) !== false) {
209 if (target.isNotifyTarget) {
210 if (target.notifyDrop(this, e, this.dragData) !== false) { // valid drop?
211 this.onValidDrop(target, e, id);
213 this.onInvalidDrop(target, e, id);
216 this.onValidDrop(target, e, id);
219 if (this.afterDragDrop) {
221 * An empty function by default, but provided so that you can perform a custom action
222 * after a valid drag drop has occurred by providing an implementation.
223 * @param {Ext.dd.DragDrop} target The drop target
224 * @param {Event} e The event object
225 * @param {String} id The id of the dropped element
226 * @method afterDragDrop
228 this.afterDragDrop(target, e, id);
231 delete this.cachedTarget;
235 * An empty function by default, but provided so that you can perform a custom action before the dragged
236 * item is dropped onto the target and optionally cancel the onDragDrop.
237 * @param {Ext.dd.DragDrop} target The drop target
238 * @param {Event} e The event object
239 * @param {String} id The id of the dragged element
240 * @return {Boolean} isValid True if the drag drop event is valid, else false to cancel
242 beforeDragDrop: function(target, e, id){
247 onValidDrop: function(target, e, id){
249 if(this.afterValidDrop){
251 * An empty function by default, but provided so that you can perform a custom action
252 * after a valid drop has occurred by providing an implementation.
253 * @param {Object} target The target DD
254 * @param {Event} e The event object
255 * @param {String} id The id of the dropped element
256 * @method afterValidDrop
258 this.afterValidDrop(target, e, id);
263 getRepairXY: function(e, data){
264 return this.el.getXY();
268 onInvalidDrop: function(target, e, id) {
269 this.beforeInvalidDrop(target, e, id);
270 if (this.cachedTarget) {
271 if(this.cachedTarget.isNotifyTarget){
272 this.cachedTarget.notifyOut(this, e, this.dragData);
274 this.cacheTarget = null;
276 this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);
278 if (this.afterInvalidDrop) {
280 * An empty function by default, but provided so that you can perform a custom action
281 * after an invalid drop has occurred by providing an implementation.
282 * @param {Event} e The event object
283 * @param {String} id The id of the dropped element
284 * @method afterInvalidDrop
286 this.afterInvalidDrop(e, id);
291 afterRepair: function() {
294 me.el.highlight(me.repairHighlightColor);
300 * An empty function by default, but provided so that you can perform a custom action after an invalid
302 * @param {Ext.dd.DragDrop} target The drop target
303 * @param {Event} e The event object
304 * @param {String} id The id of the dragged element
305 * @return {Boolean} isValid True if the invalid drop should proceed, else false to cancel
307 beforeInvalidDrop: function(target, e, id) {
312 handleMouseDown: function(e) {
316 var data = this.getDragData(e);
317 if (data && this.onBeforeDrag(data, e) !== false) {
318 this.dragData = data;
320 this.callParent(arguments);
325 * An empty function by default, but provided so that you can perform a custom action before the initial
326 * drag event begins and optionally cancel it.
327 * @param {Object} data An object containing arbitrary data to be shared with drop targets
328 * @param {Event} e The event object
329 * @return {Boolean} isValid True if the drag event is valid, else false to cancel
331 onBeforeDrag: function(data, e){
336 * An empty function by default, but provided so that you can perform a custom action once the initial
337 * drag event has begun. The drag cannot be canceled from this function.
338 * @param {Number} x The x position of the click on the dragged object
339 * @param {Number} y The y position of the click on the dragged object
342 onStartDrag: Ext.emptyFn,
345 startDrag: function(x, y) {
347 this.dragging = true;
348 this.proxy.update("");
349 this.onInitDrag(x, y);
354 onInitDrag: function(x, y) {
355 var clone = this.el.dom.cloneNode(true);
356 clone.id = Ext.id(); // prevent duplicate ids
357 this.proxy.update(clone);
358 this.onStartDrag(x, y);
363 * Returns the drag source's underlying {@link Ext.dd.StatusProxy}
364 * @return {Ext.dd.StatusProxy} proxy The StatusProxy
366 getProxy: function() {
371 * Hides the drag source's {@link Ext.dd.StatusProxy}
373 hideProxy: function() {
375 this.proxy.reset(true);
376 this.dragging = false;
380 triggerCacheRefresh: function() {
381 Ext.dd.DDM.refreshCache(this.groups);
384 // private - override to prevent hiding
385 b4EndDrag: function(e) {
388 // private - override to prevent moving
389 endDrag : function(e){
390 this.onEndDrag(this.dragData, e);
394 onEndDrag : function(data, e){
397 // private - pin to cursor
398 autoOffset : function(x, y) {
399 this.setDelta(-12, -20);
404 Ext.destroy(this.proxy);