Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / DragDrop.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js">/*
19  * This is a derivative of the similarly named class in the YUI Library.
20  * The original license:
21  * Copyright (c) 2006, Yahoo! Inc. All rights reserved.
22  * Code licensed under the BSD License:
23  * http://developer.yahoo.net/yui/license.txt
24  */
25
26
27 <span id='Ext-dd-DragDrop'>/**
28 </span> * Defines the interface and base operation of items that that can be
29  * dragged or can be drop targets.  It was designed to be extended, overriding
30  * the event handlers for startDrag, onDrag, onDragOver and onDragOut.
31  * Up to three html elements can be associated with a DragDrop instance:
32  *
33  * - linked element: the element that is passed into the constructor.
34  *   This is the element which defines the boundaries for interaction with
35  *   other DragDrop objects.
36  *
37  * - handle element(s): The drag operation only occurs if the element that
38  *   was clicked matches a handle element.  By default this is the linked
39  *   element, but there are times that you will want only a portion of the
40  *   linked element to initiate the drag operation, and the setHandleElId()
41  *   method provides a way to define this.
42  *
43  * - drag element: this represents the element that would be moved along
44  *   with the cursor during a drag operation.  By default, this is the linked
45  *   element itself as in {@link Ext.dd.DD}.  setDragElId() lets you define
46  *   a separate element that would be moved, as in {@link Ext.dd.DDProxy}.
47  *
48  * This class should not be instantiated until the onload event to ensure that
49  * the associated elements are available.
50  * The following would define a DragDrop obj that would interact with any
51  * other DragDrop obj in the &quot;group1&quot; group:
52  *
53  *     dd = new Ext.dd.DragDrop(&quot;div1&quot;, &quot;group1&quot;);
54  *
55  * Since none of the event handlers have been implemented, nothing would
56  * actually happen if you were to run the code above.  Normally you would
57  * override this class or one of the default implementations, but you can
58  * also override the methods you want on an instance of the class...
59  *
60  *     dd.onDragDrop = function(e, id) {
61  *         alert(&quot;dd was dropped on &quot; + id);
62  *     }
63  *
64  */
65 Ext.define('Ext.dd.DragDrop', {
66     requires: ['Ext.dd.DragDropManager'],
67     
68 <span id='Ext-dd-DragDrop-method-constructor'>    /**
69 </span>     * Creates new DragDrop.
70      * @param {String} id of the element that is linked to this instance
71      * @param {String} sGroup the group of related DragDrop objects
72      * @param {object} config an object containing configurable attributes.
73      * Valid properties for DragDrop:
74      * 
75      * - padding
76      * - isTarget
77      * - maintainOffset
78      * - primaryButtonOnly
79      */
80     constructor: function(id, sGroup, config) {
81         if(id) {
82             this.init(id, sGroup, config);
83         }
84     },
85     
86 <span id='Ext-dd-DragDrop-property-ignoreSelf'>    /**
87 </span>     * Set to false to enable a DragDrop object to fire drag events while dragging
88      * over its own Element. Defaults to true - DragDrop objects do not by default
89      * fire drag events to themselves.
90      * @property ignoreSelf
91      * @type Boolean
92      */
93
94 <span id='Ext-dd-DragDrop-property-id'>    /**
95 </span>     * The id of the element associated with this object.  This is what we
96      * refer to as the &quot;linked element&quot; because the size and position of
97      * this element is used to determine when the drag and drop objects have
98      * interacted.
99      * @property id
100      * @type String
101      */
102     id: null,
103
104 <span id='Ext-dd-DragDrop-property-config'>    /**
105 </span>     * Configuration attributes passed into the constructor
106      * @property config
107      * @type object
108      */
109     config: null,
110
111 <span id='Ext-dd-DragDrop-property-dragElId'>    /**
112 </span>     * The id of the element that will be dragged.  By default this is same
113      * as the linked element, but could be changed to another element. Ex:
114      * Ext.dd.DDProxy
115      * @property dragElId
116      * @type String
117      * @private
118      */
119     dragElId: null,
120
121 <span id='Ext-dd-DragDrop-property-handleElId'>    /**
122 </span>     * The ID of the element that initiates the drag operation.  By default
123      * this is the linked element, but could be changed to be a child of this
124      * element.  This lets us do things like only starting the drag when the
125      * header element within the linked html element is clicked.
126      * @property handleElId
127      * @type String
128      * @private
129      */
130     handleElId: null,
131
132 <span id='Ext-dd-DragDrop-property-invalidHandleTypes'>    /**
133 </span>     * An object who's property names identify HTML tags to be considered invalid as drag handles.
134      * A non-null property value identifies the tag as invalid. Defaults to the 
135      * following value which prevents drag operations from being initiated by &amp;lt;a&gt; elements:&lt;pre&gt;&lt;code&gt;
136 {
137     A: &quot;A&quot;
138 }&lt;/code&gt;&lt;/pre&gt;
139      * @property invalidHandleTypes
140      * @type Object
141      */
142     invalidHandleTypes: null,
143
144 <span id='Ext-dd-DragDrop-property-invalidHandleIds'>    /**
145 </span>     * An object who's property names identify the IDs of elements to be considered invalid as drag handles.
146      * A non-null property value identifies the ID as invalid. For example, to prevent
147      * dragging from being initiated on element ID &quot;foo&quot;, use:&lt;pre&gt;&lt;code&gt;
148 {
149     foo: true
150 }&lt;/code&gt;&lt;/pre&gt;
151      * @property invalidHandleIds
152      * @type Object
153      */
154     invalidHandleIds: null,
155
156 <span id='Ext-dd-DragDrop-property-invalidHandleClasses'>    /**
157 </span>     * An Array of CSS class names for elements to be considered in valid as drag handles.
158      * @property invalidHandleClasses
159      * @type Array
160      */
161     invalidHandleClasses: null,
162
163 <span id='Ext-dd-DragDrop-property-startPageX'>    /**
164 </span>     * The linked element's absolute X position at the time the drag was
165      * started
166      * @property startPageX
167      * @type int
168      * @private
169      */
170     startPageX: 0,
171
172 <span id='Ext-dd-DragDrop-property-startPageY'>    /**
173 </span>     * The linked element's absolute X position at the time the drag was
174      * started
175      * @property startPageY
176      * @type int
177      * @private
178      */
179     startPageY: 0,
180
181 <span id='Ext-dd-DragDrop-property-groups'>    /**
182 </span>     * The group defines a logical collection of DragDrop objects that are
183      * related.  Instances only get events when interacting with other
184      * DragDrop object in the same group.  This lets us define multiple
185      * groups using a single DragDrop subclass if we want.
186      * @property groups
187      * @type object An object in the format {'group1':true, 'group2':true}
188      */
189     groups: null,
190
191 <span id='Ext-dd-DragDrop-property-locked'>    /**
192 </span>     * Individual drag/drop instances can be locked.  This will prevent
193      * onmousedown start drag.
194      * @property locked
195      * @type boolean
196      * @private
197      */
198     locked: false,
199
200 <span id='Ext-dd-DragDrop-method-lock'>    /**
201 </span>     * Locks this instance
202      */
203     lock: function() {
204         this.locked = true;
205     },
206
207 <span id='Ext-dd-DragDrop-property-moveOnly'>    /**
208 </span>     * When set to true, other DD objects in cooperating DDGroups do not receive
209      * notification events when this DD object is dragged over them. Defaults to false.
210      * @property moveOnly
211      * @type boolean
212      */
213     moveOnly: false,
214
215 <span id='Ext-dd-DragDrop-method-unlock'>    /**
216 </span>     * Unlocks this instace
217      */
218     unlock: function() {
219         this.locked = false;
220     },
221
222 <span id='Ext-dd-DragDrop-property-isTarget'>    /**
223 </span>     * By default, all instances can be a drop target.  This can be disabled by
224      * setting isTarget to false.
225      * @property isTarget
226      * @type boolean
227      */
228     isTarget: true,
229
230 <span id='Ext-dd-DragDrop-property-padding'>    /**
231 </span>     * The padding configured for this drag and drop object for calculating
232      * the drop zone intersection with this object.
233      * An array containing the 4 padding values: [top, right, bottom, left]
234      * @property {[int]} padding
235      */
236     padding: null,
237
238 <span id='Ext-dd-DragDrop-property-_domRef'>    /**
239 </span>     * Cached reference to the linked element
240      * @property _domRef
241      * @private
242      */
243     _domRef: null,
244
245 <span id='Ext-dd-DragDrop-property-__ygDragDrop'>    /**
246 </span>     * Internal typeof flag
247      * @property __ygDragDrop
248      * @private
249      */
250     __ygDragDrop: true,
251
252 <span id='Ext-dd-DragDrop-property-constrainX'>    /**
253 </span>     * Set to true when horizontal contraints are applied
254      * @property constrainX
255      * @type boolean
256      * @private
257      */
258     constrainX: false,
259
260 <span id='Ext-dd-DragDrop-property-constrainY'>    /**
261 </span>     * Set to true when vertical contraints are applied
262      * @property constrainY
263      * @type boolean
264      * @private
265      */
266     constrainY: false,
267
268 <span id='Ext-dd-DragDrop-property-minX'>    /**
269 </span>     * The left constraint
270      * @property minX
271      * @type int
272      * @private
273      */
274     minX: 0,
275
276 <span id='Ext-dd-DragDrop-property-maxX'>    /**
277 </span>     * The right constraint
278      * @property maxX
279      * @type int
280      * @private
281      */
282     maxX: 0,
283
284 <span id='Ext-dd-DragDrop-property-minY'>    /**
285 </span>     * The up constraint
286      * @property minY
287      * @type int
288      * @private
289      */
290     minY: 0,
291
292 <span id='Ext-dd-DragDrop-property-maxY'>    /**
293 </span>     * The down constraint
294      * @property maxY
295      * @type int
296      * @private
297      */
298     maxY: 0,
299
300 <span id='Ext-dd-DragDrop-property-maintainOffset'>    /**
301 </span>     * Maintain offsets when we resetconstraints.  Set to true when you want
302      * the position of the element relative to its parent to stay the same
303      * when the page changes
304      *
305      * @property maintainOffset
306      * @type boolean
307      */
308     maintainOffset: false,
309
310 <span id='Ext-dd-DragDrop-property-xTicks'>    /**
311 </span>     * Array of pixel locations the element will snap to if we specified a
312      * horizontal graduation/interval.  This array is generated automatically
313      * when you define a tick interval.
314      * @property {[int]} xTicks
315      */
316     xTicks: null,
317
318 <span id='Ext-dd-DragDrop-property-yTicks'>    /**
319 </span>     * Array of pixel locations the element will snap to if we specified a
320      * vertical graduation/interval.  This array is generated automatically
321      * when you define a tick interval.
322      * @property {[int]} yTicks
323      */
324     yTicks: null,
325
326 <span id='Ext-dd-DragDrop-property-primaryButtonOnly'>    /**
327 </span>     * By default the drag and drop instance will only respond to the primary
328      * button click (left button for a right-handed mouse).  Set to true to
329      * allow drag and drop to start with any mouse click that is propogated
330      * by the browser
331      * @property primaryButtonOnly
332      * @type boolean
333      */
334     primaryButtonOnly: true,
335
336 <span id='Ext-dd-DragDrop-property-available'>    /**
337 </span>     * The available property is false until the linked dom element is accessible.
338      * @property available
339      * @type boolean
340      */
341     available: false,
342
343 <span id='Ext-dd-DragDrop-property-hasOuterHandles'>    /**
344 </span>     * By default, drags can only be initiated if the mousedown occurs in the
345      * region the linked element is.  This is done in part to work around a
346      * bug in some browsers that mis-report the mousedown if the previous
347      * mouseup happened outside of the window.  This property is set to true
348      * if outer handles are defined. Defaults to false.
349      *
350      * @property hasOuterHandles
351      * @type boolean
352      */
353     hasOuterHandles: false,
354
355 <span id='Ext-dd-DragDrop-method-b4StartDrag'>    /**
356 </span>     * Code that executes immediately before the startDrag event
357      * @private
358      */
359     b4StartDrag: function(x, y) { },
360
361 <span id='Ext-dd-DragDrop-method-startDrag'>    /**
362 </span>     * Abstract method called after a drag/drop object is clicked
363      * and the drag or mousedown time thresholds have beeen met.
364      * @param {int} X click location
365      * @param {int} Y click location
366      */
367     startDrag: function(x, y) { /* override this */ },
368
369 <span id='Ext-dd-DragDrop-method-b4Drag'>    /**
370 </span>     * Code that executes immediately before the onDrag event
371      * @private
372      */
373     b4Drag: function(e) { },
374
375 <span id='Ext-dd-DragDrop-method-onDrag'>    /**
376 </span>     * Abstract method called during the onMouseMove event while dragging an
377      * object.
378      * @param {Event} e the mousemove event
379      */
380     onDrag: function(e) { /* override this */ },
381
382 <span id='Ext-dd-DragDrop-method-onDragEnter'>    /**
383 </span>     * Abstract method called when this element fist begins hovering over
384      * another DragDrop obj
385      * @param {Event} e the mousemove event
386      * @param {String/[DragDrop]} id In POINT mode, the element
387      * id this is hovering over.  In INTERSECT mode, an array of one or more
388      * dragdrop items being hovered over.
389      */
390     onDragEnter: function(e, id) { /* override this */ },
391
392 <span id='Ext-dd-DragDrop-method-b4DragOver'>    /**
393 </span>     * Code that executes immediately before the onDragOver event
394      * @private
395      */
396     b4DragOver: function(e) { },
397
398 <span id='Ext-dd-DragDrop-method-onDragOver'>    /**
399 </span>     * Abstract method called when this element is hovering over another
400      * DragDrop obj
401      * @param {Event} e the mousemove event
402      * @param {String|DragDrop[]} id In POINT mode, the element
403      * id this is hovering over.  In INTERSECT mode, an array of dd items
404      * being hovered over.
405      */
406     onDragOver: function(e, id) { /* override this */ },
407
408 <span id='Ext-dd-DragDrop-method-b4DragOut'>    /**
409 </span>     * Code that executes immediately before the onDragOut event
410      * @private
411      */
412     b4DragOut: function(e) { },
413
414 <span id='Ext-dd-DragDrop-method-onDragOut'>    /**
415 </span>     * Abstract method called when we are no longer hovering over an element
416      * @param {Event} e the mousemove event
417      * @param {String/[DragDrop]} id In POINT mode, the element
418      * id this was hovering over.  In INTERSECT mode, an array of dd items
419      * that the mouse is no longer over.
420      */
421     onDragOut: function(e, id) { /* override this */ },
422
423 <span id='Ext-dd-DragDrop-method-b4DragDrop'>    /**
424 </span>     * Code that executes immediately before the onDragDrop event
425      * @private
426      */
427     b4DragDrop: function(e) { },
428
429 <span id='Ext-dd-DragDrop-method-onDragDrop'>    /**
430 </span>     * Abstract method called when this item is dropped on another DragDrop
431      * obj
432      * @param {Event} e the mouseup event
433      * @param {String/[DragDrop]} id In POINT mode, the element
434      * id this was dropped on.  In INTERSECT mode, an array of dd items this
435      * was dropped on.
436      */
437     onDragDrop: function(e, id) { /* override this */ },
438
439 <span id='Ext-dd-DragDrop-method-onInvalidDrop'>    /**
440 </span>     * Abstract method called when this item is dropped on an area with no
441      * drop target
442      * @param {Event} e the mouseup event
443      */
444     onInvalidDrop: function(e) { /* override this */ },
445
446 <span id='Ext-dd-DragDrop-method-b4EndDrag'>    /**
447 </span>     * Code that executes immediately before the endDrag event
448      * @private
449      */
450     b4EndDrag: function(e) { },
451
452 <span id='Ext-dd-DragDrop-method-endDrag'>    /**
453 </span>     * Called when we are done dragging the object
454      * @param {Event} e the mouseup event
455      */
456     endDrag: function(e) { /* override this */ },
457
458 <span id='Ext-dd-DragDrop-method-b4MouseDown'>    /**
459 </span>     * Code executed immediately before the onMouseDown event
460      * @param {Event} e the mousedown event
461      * @private
462      */
463     b4MouseDown: function(e) {  },
464
465 <span id='Ext-dd-DragDrop-method-onMouseDown'>    /**
466 </span>     * Called when a drag/drop obj gets a mousedown
467      * @param {Event} e the mousedown event
468      */
469     onMouseDown: function(e) { /* override this */ },
470
471 <span id='Ext-dd-DragDrop-method-onMouseUp'>    /**
472 </span>     * Called when a drag/drop obj gets a mouseup
473      * @param {Event} e the mouseup event
474      */
475     onMouseUp: function(e) { /* override this */ },
476
477 <span id='Ext-dd-DragDrop-method-onAvailable'>    /**
478 </span>     * Override the onAvailable method to do what is needed after the initial
479      * position was determined.
480      */
481     onAvailable: function () {
482     },
483
484 <span id='Ext-dd-DragDrop-property-defaultPadding'>    /**
485 </span>     * Provides default constraint padding to &quot;constrainTo&quot; elements (defaults to `{left:0, right:0, top:0, bottom:0}`).
486      * @type Object
487      */
488     defaultPadding: {
489         left: 0,
490         right: 0,
491         top: 0,
492         bottom: 0
493     },
494
495 <span id='Ext-dd-DragDrop-method-constrainTo'>    /**
496 </span>     * Initializes the drag drop object's constraints to restrict movement to a certain element.
497      *
498      * Usage:
499      *
500      *     var dd = new Ext.dd.DDProxy(&quot;dragDiv1&quot;, &quot;proxytest&quot;,
501      *                    { dragElId: &quot;existingProxyDiv&quot; });
502      *     dd.startDrag = function(){
503      *         this.constrainTo(&quot;parent-id&quot;);
504      *     };
505      *
506      * Or you can initalize it using the {@link Ext.core.Element} object:
507      *
508      *     Ext.get(&quot;dragDiv1&quot;).initDDProxy(&quot;proxytest&quot;, {dragElId: &quot;existingProxyDiv&quot;}, {
509      *         startDrag : function(){
510      *             this.constrainTo(&quot;parent-id&quot;);
511      *         }
512      *     });
513      *
514      * @param {Mixed} constrainTo The element to constrain to.
515      * @param {Object/Number} pad (optional) Pad provides a way to specify &quot;padding&quot; of the constraints,
516      * and can be either a number for symmetrical padding (4 would be equal to `{left:4, right:4, top:4, bottom:4}`) or
517      * an object containing the sides to pad. For example: `{right:10, bottom:10}`
518      * @param {Boolean} inContent (optional) Constrain the draggable in the content box of the element (inside padding and borders)
519      */
520     constrainTo : function(constrainTo, pad, inContent){
521         if(Ext.isNumber(pad)){
522             pad = {left: pad, right:pad, top:pad, bottom:pad};
523         }
524         pad = pad || this.defaultPadding;
525         var b = Ext.get(this.getEl()).getBox(),
526             ce = Ext.get(constrainTo),
527             s = ce.getScroll(),
528             c, 
529             cd = ce.dom;
530         if(cd == document.body){
531             c = { x: s.left, y: s.top, width: Ext.core.Element.getViewWidth(), height: Ext.core.Element.getViewHeight()};
532         }else{
533             var xy = ce.getXY();
534             c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight};
535         }
536
537
538         var topSpace = b.y - c.y,
539             leftSpace = b.x - c.x;
540
541         this.resetConstraints();
542         this.setXConstraint(leftSpace - (pad.left||0), // left
543                 c.width - leftSpace - b.width - (pad.right||0), //right
544                                 this.xTickSize
545         );
546         this.setYConstraint(topSpace - (pad.top||0), //top
547                 c.height - topSpace - b.height - (pad.bottom||0), //bottom
548                                 this.yTickSize
549         );
550     },
551
552 <span id='Ext-dd-DragDrop-method-getEl'>    /**
553 </span>     * Returns a reference to the linked element
554      * @return {HTMLElement} the html element
555      */
556     getEl: function() {
557         if (!this._domRef) {
558             this._domRef = Ext.getDom(this.id);
559         }
560
561         return this._domRef;
562     },
563
564 <span id='Ext-dd-DragDrop-method-getDragEl'>    /**
565 </span>     * Returns a reference to the actual element to drag.  By default this is
566      * the same as the html element, but it can be assigned to another
567      * element. An example of this can be found in Ext.dd.DDProxy
568      * @return {HTMLElement} the html element
569      */
570     getDragEl: function() {
571         return Ext.getDom(this.dragElId);
572     },
573
574 <span id='Ext-dd-DragDrop-method-init'>    /**
575 </span>     * Sets up the DragDrop object.  Must be called in the constructor of any
576      * Ext.dd.DragDrop subclass
577      * @param {String} id the id of the linked element
578      * @param {String} sGroup the group of related items
579      * @param {Object} config configuration attributes
580      */
581     init: function(id, sGroup, config) {
582         this.initTarget(id, sGroup, config);
583         Ext.EventManager.on(this.id, &quot;mousedown&quot;, this.handleMouseDown, this);
584         // Ext.EventManager.on(this.id, &quot;selectstart&quot;, Event.preventDefault);
585     },
586
587 <span id='Ext-dd-DragDrop-method-initTarget'>    /**
588 </span>     * Initializes Targeting functionality only... the object does not
589      * get a mousedown handler.
590      * @param {String} id the id of the linked element
591      * @param {String} sGroup the group of related items
592      * @param {Object} config configuration attributes
593      */
594     initTarget: function(id, sGroup, config) {
595         // configuration attributes
596         this.config = config || {};
597
598         // create a local reference to the drag and drop manager
599         this.DDMInstance = Ext.dd.DragDropManager;
600         // initialize the groups array
601         this.groups = {};
602
603         // assume that we have an element reference instead of an id if the
604         // parameter is not a string
605         if (typeof id !== &quot;string&quot;) {
606             id = Ext.id(id);
607         }
608
609         // set the id
610         this.id = id;
611
612         // add to an interaction group
613         this.addToGroup((sGroup) ? sGroup : &quot;default&quot;);
614
615         // We don't want to register this as the handle with the manager
616         // so we just set the id rather than calling the setter.
617         this.handleElId = id;
618
619         // the linked element is the element that gets dragged by default
620         this.setDragElId(id);
621
622         // by default, clicked anchors will not start drag operations.
623         this.invalidHandleTypes = { A: &quot;A&quot; };
624         this.invalidHandleIds = {};
625         this.invalidHandleClasses = [];
626
627         this.applyConfig();
628
629         this.handleOnAvailable();
630     },
631
632 <span id='Ext-dd-DragDrop-method-applyConfig'>    /**
633 </span>     * Applies the configuration parameters that were passed into the constructor.
634      * This is supposed to happen at each level through the inheritance chain.  So
635      * a DDProxy implentation will execute apply config on DDProxy, DD, and
636      * DragDrop in order to get all of the parameters that are available in
637      * each object.
638      */
639     applyConfig: function() {
640
641         // configurable properties:
642         //    padding, isTarget, maintainOffset, primaryButtonOnly
643         this.padding           = this.config.padding || [0, 0, 0, 0];
644         this.isTarget          = (this.config.isTarget !== false);
645         this.maintainOffset    = (this.config.maintainOffset);
646         this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
647
648     },
649
650 <span id='Ext-dd-DragDrop-method-handleOnAvailable'>    /**
651 </span>     * Executed when the linked element is available
652      * @private
653      */
654     handleOnAvailable: function() {
655         this.available = true;
656         this.resetConstraints();
657         this.onAvailable();
658     },
659
660 <span id='Ext-dd-DragDrop-method-setPadding'>    /**
661 </span>     * Configures the padding for the target zone in px.  Effectively expands
662      * (or reduces) the virtual object size for targeting calculations.
663      * Supports css-style shorthand; if only one parameter is passed, all sides
664      * will have that padding, and if only two are passed, the top and bottom
665      * will have the first param, the left and right the second.
666      * @param {int} iTop    Top pad
667      * @param {int} iRight  Right pad
668      * @param {int} iBot    Bot pad
669      * @param {int} iLeft   Left pad
670      */
671     setPadding: function(iTop, iRight, iBot, iLeft) {
672         // this.padding = [iLeft, iRight, iTop, iBot];
673         if (!iRight &amp;&amp; 0 !== iRight) {
674             this.padding = [iTop, iTop, iTop, iTop];
675         } else if (!iBot &amp;&amp; 0 !== iBot) {
676             this.padding = [iTop, iRight, iTop, iRight];
677         } else {
678             this.padding = [iTop, iRight, iBot, iLeft];
679         }
680     },
681
682 <span id='Ext-dd-DragDrop-method-setInitPosition'>    /**
683 </span>     * Stores the initial placement of the linked element.
684      * @param {int} diffX   the X offset, default 0
685      * @param {int} diffY   the Y offset, default 0
686      */
687     setInitPosition: function(diffX, diffY) {
688         var el = this.getEl();
689
690         if (!this.DDMInstance.verifyEl(el)) {
691             return;
692         }
693
694         var dx = diffX || 0;
695         var dy = diffY || 0;
696
697         var p = Ext.core.Element.getXY( el );
698
699         this.initPageX = p[0] - dx;
700         this.initPageY = p[1] - dy;
701
702         this.lastPageX = p[0];
703         this.lastPageY = p[1];
704
705         this.setStartPosition(p);
706     },
707
708 <span id='Ext-dd-DragDrop-method-setStartPosition'>    /**
709 </span>     * Sets the start position of the element.  This is set when the obj
710      * is initialized, the reset when a drag is started.
711      * @param pos current position (from previous lookup)
712      * @private
713      */
714     setStartPosition: function(pos) {
715         var p = pos || Ext.core.Element.getXY( this.getEl() );
716         this.deltaSetXY = null;
717
718         this.startPageX = p[0];
719         this.startPageY = p[1];
720     },
721
722 <span id='Ext-dd-DragDrop-method-addToGroup'>    /**
723 </span>     * Adds this instance to a group of related drag/drop objects.  All
724      * instances belong to at least one group, and can belong to as many
725      * groups as needed.
726      * @param {String} sGroup the name of the group
727      */
728     addToGroup: function(sGroup) {
729         this.groups[sGroup] = true;
730         this.DDMInstance.regDragDrop(this, sGroup);
731     },
732
733 <span id='Ext-dd-DragDrop-method-removeFromGroup'>    /**
734 </span>     * Removes this instance from the supplied interaction group
735      * @param {String} sGroup  The group to drop
736      */
737     removeFromGroup: function(sGroup) {
738         if (this.groups[sGroup]) {
739             delete this.groups[sGroup];
740         }
741
742         this.DDMInstance.removeDDFromGroup(this, sGroup);
743     },
744
745 <span id='Ext-dd-DragDrop-method-setDragElId'>    /**
746 </span>     * Allows you to specify that an element other than the linked element
747      * will be moved with the cursor during a drag
748      * @param {String} id the id of the element that will be used to initiate the drag
749      */
750     setDragElId: function(id) {
751         this.dragElId = id;
752     },
753
754 <span id='Ext-dd-DragDrop-method-setHandleElId'>    /**
755 </span>     * Allows you to specify a child of the linked element that should be
756      * used to initiate the drag operation.  An example of this would be if
757      * you have a content div with text and links.  Clicking anywhere in the
758      * content area would normally start the drag operation.  Use this method
759      * to specify that an element inside of the content div is the element
760      * that starts the drag operation.
761      * @param {String} id the id of the element that will be used to
762      * initiate the drag.
763      */
764     setHandleElId: function(id) {
765         if (typeof id !== &quot;string&quot;) {
766             id = Ext.id(id);
767         }
768         this.handleElId = id;
769         this.DDMInstance.regHandle(this.id, id);
770     },
771
772 <span id='Ext-dd-DragDrop-method-setOuterHandleElId'>    /**
773 </span>     * Allows you to set an element outside of the linked element as a drag
774      * handle
775      * @param {String} id the id of the element that will be used to initiate the drag
776      */
777     setOuterHandleElId: function(id) {
778         if (typeof id !== &quot;string&quot;) {
779             id = Ext.id(id);
780         }
781         Ext.EventManager.on(id, &quot;mousedown&quot;, this.handleMouseDown, this);
782         this.setHandleElId(id);
783
784         this.hasOuterHandles = true;
785     },
786
787 <span id='Ext-dd-DragDrop-method-unreg'>    /**
788 </span>     * Removes all drag and drop hooks for this element
789      */
790     unreg: function() {
791         Ext.EventManager.un(this.id, &quot;mousedown&quot;, this.handleMouseDown, this);
792         this._domRef = null;
793         this.DDMInstance._remove(this);
794     },
795
796     destroy : function(){
797         this.unreg();
798     },
799
800 <span id='Ext-dd-DragDrop-method-isLocked'>    /**
801 </span>     * Returns true if this instance is locked, or the drag drop mgr is locked
802      * (meaning that all drag/drop is disabled on the page.)
803      * @return {Boolean} true if this obj or all drag/drop is locked, else
804      * false
805      */
806     isLocked: function() {
807         return (this.DDMInstance.isLocked() || this.locked);
808     },
809
810 <span id='Ext-dd-DragDrop-method-handleMouseDown'>    /**
811 </span>     * Called when this object is clicked
812      * @param {Event} e
813      * @param {Ext.dd.DragDrop} oDD the clicked dd object (this dd obj)
814      * @private
815      */
816     handleMouseDown: function(e, oDD){
817         if (this.primaryButtonOnly &amp;&amp; e.button != 0) {
818             return;
819         }
820
821         if (this.isLocked()) {
822             return;
823         }
824
825         this.DDMInstance.refreshCache(this.groups);
826
827         var pt = e.getPoint();
828         if (!this.hasOuterHandles &amp;&amp; !this.DDMInstance.isOverTarget(pt, this) )  {
829         } else {
830             if (this.clickValidator(e)) {
831                 // set the initial element position
832                 this.setStartPosition();
833                 this.b4MouseDown(e);
834                 this.onMouseDown(e);
835
836                 this.DDMInstance.handleMouseDown(e, this);
837
838                 this.DDMInstance.stopEvent(e);
839             } else {
840
841
842             }
843         }
844     },
845
846     clickValidator: function(e) {
847         var target = e.getTarget();
848         return ( this.isValidHandleChild(target) &amp;&amp;
849                     (this.id == this.handleElId ||
850                         this.DDMInstance.handleWasClicked(target, this.id)) );
851     },
852
853 <span id='Ext-dd-DragDrop-method-addInvalidHandleType'>    /**
854 </span>     * Allows you to specify a tag name that should not start a drag operation
855      * when clicked.  This is designed to facilitate embedding links within a
856      * drag handle that do something other than start the drag.
857      * @method addInvalidHandleType
858      * @param {String} tagName the type of element to exclude
859      */
860     addInvalidHandleType: function(tagName) {
861         var type = tagName.toUpperCase();
862         this.invalidHandleTypes[type] = type;
863     },
864
865 <span id='Ext-dd-DragDrop-method-addInvalidHandleId'>    /**
866 </span>     * Lets you to specify an element id for a child of a drag handle
867      * that should not initiate a drag
868      * @method addInvalidHandleId
869      * @param {String} id the element id of the element you wish to ignore
870      */
871     addInvalidHandleId: function(id) {
872         if (typeof id !== &quot;string&quot;) {
873             id = Ext.id(id);
874         }
875         this.invalidHandleIds[id] = id;
876     },
877
878 <span id='Ext-dd-DragDrop-method-addInvalidHandleClass'>    /**
879 </span>     * Lets you specify a css class of elements that will not initiate a drag
880      * @param {String} cssClass the class of the elements you wish to ignore
881      */
882     addInvalidHandleClass: function(cssClass) {
883         this.invalidHandleClasses.push(cssClass);
884     },
885
886 <span id='Ext-dd-DragDrop-method-removeInvalidHandleType'>    /**
887 </span>     * Unsets an excluded tag name set by addInvalidHandleType
888      * @param {String} tagName the type of element to unexclude
889      */
890     removeInvalidHandleType: function(tagName) {
891         var type = tagName.toUpperCase();
892         // this.invalidHandleTypes[type] = null;
893         delete this.invalidHandleTypes[type];
894     },
895
896 <span id='Ext-dd-DragDrop-method-removeInvalidHandleId'>    /**
897 </span>     * Unsets an invalid handle id
898      * @param {String} id the id of the element to re-enable
899      */
900     removeInvalidHandleId: function(id) {
901         if (typeof id !== &quot;string&quot;) {
902             id = Ext.id(id);
903         }
904         delete this.invalidHandleIds[id];
905     },
906
907 <span id='Ext-dd-DragDrop-method-removeInvalidHandleClass'>    /**
908 </span>     * Unsets an invalid css class
909      * @param {String} cssClass the class of the element(s) you wish to
910      * re-enable
911      */
912     removeInvalidHandleClass: function(cssClass) {
913         for (var i=0, len=this.invalidHandleClasses.length; i&lt;len; ++i) {
914             if (this.invalidHandleClasses[i] == cssClass) {
915                 delete this.invalidHandleClasses[i];
916             }
917         }
918     },
919
920 <span id='Ext-dd-DragDrop-method-isValidHandleChild'>    /**
921 </span>     * Checks the tag exclusion list to see if this click should be ignored
922      * @param {HTMLElement} node the HTMLElement to evaluate
923      * @return {Boolean} true if this is a valid tag type, false if not
924      */
925     isValidHandleChild: function(node) {
926
927         var valid = true;
928         // var n = (node.nodeName == &quot;#text&quot;) ? node.parentNode : node;
929         var nodeName;
930         try {
931             nodeName = node.nodeName.toUpperCase();
932         } catch(e) {
933             nodeName = node.nodeName;
934         }
935         valid = valid &amp;&amp; !this.invalidHandleTypes[nodeName];
936         valid = valid &amp;&amp; !this.invalidHandleIds[node.id];
937
938         for (var i=0, len=this.invalidHandleClasses.length; valid &amp;&amp; i&lt;len; ++i) {
939             valid = !Ext.fly(node).hasCls(this.invalidHandleClasses[i]);
940         }
941
942
943         return valid;
944
945     },
946
947 <span id='Ext-dd-DragDrop-method-setXTicks'>    /**
948 </span>     * Creates the array of horizontal tick marks if an interval was specified
949      * in setXConstraint().
950      * @private
951      */
952     setXTicks: function(iStartX, iTickSize) {
953         this.xTicks = [];
954         this.xTickSize = iTickSize;
955
956         var tickMap = {};
957
958         for (var i = this.initPageX; i &gt;= this.minX; i = i - iTickSize) {
959             if (!tickMap[i]) {
960                 this.xTicks[this.xTicks.length] = i;
961                 tickMap[i] = true;
962             }
963         }
964
965         for (i = this.initPageX; i &lt;= this.maxX; i = i + iTickSize) {
966             if (!tickMap[i]) {
967                 this.xTicks[this.xTicks.length] = i;
968                 tickMap[i] = true;
969             }
970         }
971
972         Ext.Array.sort(this.xTicks, this.DDMInstance.numericSort);
973     },
974
975 <span id='Ext-dd-DragDrop-method-setYTicks'>    /**
976 </span>     * Creates the array of vertical tick marks if an interval was specified in
977      * setYConstraint().
978      * @private
979      */
980     setYTicks: function(iStartY, iTickSize) {
981         this.yTicks = [];
982         this.yTickSize = iTickSize;
983
984         var tickMap = {};
985
986         for (var i = this.initPageY; i &gt;= this.minY; i = i - iTickSize) {
987             if (!tickMap[i]) {
988                 this.yTicks[this.yTicks.length] = i;
989                 tickMap[i] = true;
990             }
991         }
992
993         for (i = this.initPageY; i &lt;= this.maxY; i = i + iTickSize) {
994             if (!tickMap[i]) {
995                 this.yTicks[this.yTicks.length] = i;
996                 tickMap[i] = true;
997             }
998         }
999
1000         Ext.Array.sort(this.yTicks, this.DDMInstance.numericSort);
1001     },
1002
1003 <span id='Ext-dd-DragDrop-method-setXConstraint'>    /**
1004 </span>     * By default, the element can be dragged any place on the screen.  Use
1005      * this method to limit the horizontal travel of the element.  Pass in
1006      * 0,0 for the parameters if you want to lock the drag to the y axis.
1007      * @param {int} iLeft the number of pixels the element can move to the left
1008      * @param {int} iRight the number of pixels the element can move to the
1009      * right
1010      * @param {int} iTickSize optional parameter for specifying that the
1011      * element should move iTickSize pixels at a time.
1012      */
1013     setXConstraint: function(iLeft, iRight, iTickSize) {
1014         this.leftConstraint = iLeft;
1015         this.rightConstraint = iRight;
1016
1017         this.minX = this.initPageX - iLeft;
1018         this.maxX = this.initPageX + iRight;
1019         if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
1020
1021         this.constrainX = true;
1022     },
1023
1024 <span id='Ext-dd-DragDrop-method-clearConstraints'>    /**
1025 </span>     * Clears any constraints applied to this instance.  Also clears ticks
1026      * since they can't exist independent of a constraint at this time.
1027      */
1028     clearConstraints: function() {
1029         this.constrainX = false;
1030         this.constrainY = false;
1031         this.clearTicks();
1032     },
1033
1034 <span id='Ext-dd-DragDrop-method-clearTicks'>    /**
1035 </span>     * Clears any tick interval defined for this instance
1036      */
1037     clearTicks: function() {
1038         this.xTicks = null;
1039         this.yTicks = null;
1040         this.xTickSize = 0;
1041         this.yTickSize = 0;
1042     },
1043
1044 <span id='Ext-dd-DragDrop-method-setYConstraint'>    /**
1045 </span>     * By default, the element can be dragged any place on the screen.  Set
1046      * this to limit the vertical travel of the element.  Pass in 0,0 for the
1047      * parameters if you want to lock the drag to the x axis.
1048      * @param {int} iUp the number of pixels the element can move up
1049      * @param {int} iDown the number of pixels the element can move down
1050      * @param {int} iTickSize optional parameter for specifying that the
1051      * element should move iTickSize pixels at a time.
1052      */
1053     setYConstraint: function(iUp, iDown, iTickSize) {
1054         this.topConstraint = iUp;
1055         this.bottomConstraint = iDown;
1056
1057         this.minY = this.initPageY - iUp;
1058         this.maxY = this.initPageY + iDown;
1059         if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
1060
1061         this.constrainY = true;
1062
1063     },
1064
1065 <span id='Ext-dd-DragDrop-method-resetConstraints'>    /**
1066 </span>     * Must be called if you manually reposition a dd element.
1067      * @param {boolean} maintainOffset
1068      */
1069     resetConstraints: function() {
1070         // Maintain offsets if necessary
1071         if (this.initPageX || this.initPageX === 0) {
1072             // figure out how much this thing has moved
1073             var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
1074             var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
1075
1076             this.setInitPosition(dx, dy);
1077
1078         // This is the first time we have detected the element's position
1079         } else {
1080             this.setInitPosition();
1081         }
1082
1083         if (this.constrainX) {
1084             this.setXConstraint( this.leftConstraint,
1085                                  this.rightConstraint,
1086                                  this.xTickSize        );
1087         }
1088
1089         if (this.constrainY) {
1090             this.setYConstraint( this.topConstraint,
1091                                  this.bottomConstraint,
1092                                  this.yTickSize         );
1093         }
1094     },
1095
1096 <span id='Ext-dd-DragDrop-method-getTick'>    /**
1097 </span>     * Normally the drag element is moved pixel by pixel, but we can specify
1098      * that it move a number of pixels at a time.  This method resolves the
1099      * location when we have it set up like this.
1100      * @param {int} val where we want to place the object
1101      * @param {int[]} tickArray sorted array of valid points
1102      * @return {int} the closest tick
1103      * @private
1104      */
1105     getTick: function(val, tickArray) {
1106         if (!tickArray) {
1107             // If tick interval is not defined, it is effectively 1 pixel,
1108             // so we return the value passed to us.
1109             return val;
1110         } else if (tickArray[0] &gt;= val) {
1111             // The value is lower than the first tick, so we return the first
1112             // tick.
1113             return tickArray[0];
1114         } else {
1115             for (var i=0, len=tickArray.length; i&lt;len; ++i) {
1116                 var next = i + 1;
1117                 if (tickArray[next] &amp;&amp; tickArray[next] &gt;= val) {
1118                     var diff1 = val - tickArray[i];
1119                     var diff2 = tickArray[next] - val;
1120                     return (diff2 &gt; diff1) ? tickArray[i] : tickArray[next];
1121                 }
1122             }
1123
1124             // The value is larger than the last tick, so we return the last
1125             // tick.
1126             return tickArray[tickArray.length - 1];
1127         }
1128     },
1129
1130 <span id='Ext-dd-DragDrop-method-toString'>    /**
1131 </span>     * toString method
1132      * @return {string} string representation of the dd obj
1133      */
1134     toString: function() {
1135         return (&quot;DragDrop &quot; + this.id);
1136     }
1137
1138 });
1139 </pre>
1140 </body>
1141 </html>