Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / docs / source / DropZone2.html
diff --git a/docs/source/DropZone2.html b/docs/source/DropZone2.html
new file mode 100644 (file)
index 0000000..d8e2a14
--- /dev/null
@@ -0,0 +1,271 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <title>The source code</title>
+  <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
+  <script type="text/javascript" src="../prettify/prettify.js"></script>
+  <style type="text/css">
+    .highlight { display: block; background-color: #ddd; }
+  </style>
+  <script type="text/javascript">
+    function highlight() {
+      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
+    }
+  </script>
+</head>
+<body onload="prettyPrint(); highlight();">
+  <pre class="prettyprint lang-js"><span id='Ext-grid-header-DropZone'>/**
+</span> * @class Ext.grid.header.DropZone
+ * @extends Ext.dd.DropZone
+ * @private
+ */
+Ext.define('Ext.grid.header.DropZone', {
+    extend: 'Ext.dd.DropZone',
+    colHeaderCls: Ext.baseCSSPrefix + 'column-header',
+    proxyOffsets: [-4, -9],
+
+    constructor: function(headerCt){
+        this.headerCt = headerCt;
+        this.ddGroup = this.getDDGroup();
+        this.callParent([headerCt.el]);
+    },
+
+    getDDGroup: function() {
+        return 'header-dd-zone-' + this.headerCt.up('[scrollerOwner]').id;
+    },
+
+    getTargetFromEvent : function(e){
+        return e.getTarget('.' + this.colHeaderCls);
+    },
+
+    getTopIndicator: function() {
+        if (!this.topIndicator) {
+            this.topIndicator = Ext.core.DomHelper.append(Ext.getBody(), {
+                cls: &quot;col-move-top&quot;,
+                html: &quot;&amp;#160;&quot;
+            }, true);
+        }
+        return this.topIndicator;
+    },
+
+    getBottomIndicator: function() {
+        if (!this.bottomIndicator) {
+            this.bottomIndicator = Ext.core.DomHelper.append(Ext.getBody(), {
+                cls: &quot;col-move-bottom&quot;,
+                html: &quot;&amp;#160;&quot;
+            }, true);
+        }
+        return this.bottomIndicator;
+    },
+
+    getLocation: function(e, t) {
+        var x      = e.getXY()[0],
+            region = Ext.fly(t).getRegion(),
+            pos, header;
+
+        if ((region.right - x) &lt;= (region.right - region.left) / 2) {
+            pos = &quot;after&quot;;
+        } else {
+            pos = &quot;before&quot;;
+        }
+        return {
+            pos: pos,
+            header: Ext.getCmp(t.id),
+            node: t
+        };
+    },
+
+    positionIndicator: function(draggedHeader, node, e){
+        var location = this.getLocation(e, node),
+            header = location.header,
+            pos    = location.pos,
+            nextHd = draggedHeader.nextSibling('gridcolumn:not([hidden])'),
+            prevHd = draggedHeader.previousSibling('gridcolumn:not([hidden])'),
+            region, topIndicator, bottomIndicator, topAnchor, bottomAnchor,
+            topXY, bottomXY, headerCtEl, minX, maxX;
+
+        // Cannot drag beyond non-draggable start column
+        if (!header.draggable &amp;&amp; header.getIndex() == 0) {
+            return false;
+        }
+
+        this.lastLocation = location;
+
+        if ((draggedHeader !== header) &amp;&amp;
+            ((pos === &quot;before&quot; &amp;&amp; nextHd !== header) ||
+            (pos === &quot;after&quot; &amp;&amp; prevHd !== header)) &amp;&amp;
+            !header.isDescendantOf(draggedHeader)) {
+
+            // As we move in between different DropZones that are in the same
+            // group (such as the case when in a locked grid), invalidateDrop
+            // on the other dropZones.
+            var allDropZones = Ext.dd.DragDropManager.getRelated(this),
+                ln = allDropZones.length,
+                i  = 0,
+                dropZone;
+
+            for (; i &lt; ln; i++) {
+                dropZone = allDropZones[i];
+                if (dropZone !== this &amp;&amp; dropZone.invalidateDrop) {
+                    dropZone.invalidateDrop();
+                }
+            }
+
+
+            this.valid = true;
+            topIndicator = this.getTopIndicator();
+            bottomIndicator = this.getBottomIndicator();
+            if (pos === 'before') {
+                topAnchor = 'tl';
+                bottomAnchor = 'bl';
+            } else {
+                topAnchor = 'tr';
+                bottomAnchor = 'br';
+            }
+            topXY = header.el.getAnchorXY(topAnchor);
+            bottomXY = header.el.getAnchorXY(bottomAnchor);
+
+            // constrain the indicators to the viewable section
+            headerCtEl = this.headerCt.el;
+            minX = headerCtEl.getLeft();
+            maxX = headerCtEl.getRight();
+
+            topXY[0] = Ext.Number.constrain(topXY[0], minX, maxX);
+            bottomXY[0] = Ext.Number.constrain(bottomXY[0], minX, maxX);
+
+            // adjust by offsets, this is to center the arrows so that they point
+            // at the split point
+            topXY[0] -= 4;
+            topXY[1] -= 9;
+            bottomXY[0] -= 4;
+
+            // position and show indicators
+            topIndicator.setXY(topXY);
+            bottomIndicator.setXY(bottomXY);
+            topIndicator.show();
+            bottomIndicator.show();
+        // invalidate drop operation and hide indicators
+        } else {
+            this.invalidateDrop();
+        }
+    },
+
+    invalidateDrop: function() {
+        this.valid = false;
+        this.hideIndicators();
+    },
+
+    onNodeOver: function(node, dragZone, e, data) {
+        if (data.header.el.dom !== node) {
+            this.positionIndicator(data.header, node, e);
+        }
+        return this.valid ? this.dropAllowed : this.dropNotAllowed;
+    },
+
+    hideIndicators: function() {
+        this.getTopIndicator().hide();
+        this.getBottomIndicator().hide();
+    },
+
+    onNodeOut: function() {
+        this.hideIndicators();
+    },
+
+    onNodeDrop: function(node, dragZone, e, data) {
+        if (this.valid) {
+            this.invalidateDrop();
+            var hd = data.header,
+                lastLocation = this.lastLocation,
+                fromCt  = hd.ownerCt,
+                fromIdx = fromCt.items.indexOf(hd), // Container.items is a MixedCollection
+                toCt    = lastLocation.header.ownerCt,
+                toIdx   = toCt.items.indexOf(lastLocation.header),
+                headerCt = this.headerCt,
+                groupCt,
+                scrollerOwner;
+
+            if (lastLocation.pos === 'after') {
+                toIdx++;
+            }
+
+            // If we are dragging in between two HeaderContainers that have had the lockable
+            // mixin injected we will lock/unlock headers in between sections. Note that lockable
+            // does NOT currently support grouped headers.
+            if (fromCt !== toCt &amp;&amp; fromCt.lockableInjected &amp;&amp; toCt.lockableInjected &amp;&amp; toCt.lockedCt) {
+                scrollerOwner = fromCt.up('[scrollerOwner]');
+                scrollerOwner.lock(hd, toIdx);
+            } else if (fromCt !== toCt &amp;&amp; fromCt.lockableInjected &amp;&amp; toCt.lockableInjected &amp;&amp; fromCt.lockedCt) {
+                scrollerOwner = fromCt.up('[scrollerOwner]');
+                scrollerOwner.unlock(hd, toIdx);
+            } else {
+                // If dragging rightwards, then after removal, the insertion index will be one less when moving
+                // in between the same container.
+                if ((fromCt === toCt) &amp;&amp; (toIdx &gt; fromCt.items.indexOf(hd))) {
+                    toIdx--;
+                }
+
+                // Remove dragged header from where it was without destroying it or relaying its Container
+                if (fromCt !== toCt) {
+                    fromCt.suspendLayout = true;
+                    fromCt.remove(hd, false);
+                    fromCt.suspendLayout = false;
+                }
+
+                // Dragged the last header out of the fromCt group... The fromCt group must die
+                if (fromCt.isGroupHeader) {
+                    if (!fromCt.items.getCount()) {
+                        groupCt = fromCt.ownerCt;
+                        groupCt.suspendLayout = true;
+                        groupCt.remove(fromCt, false);
+                        fromCt.el.dom.parentNode.removeChild(fromCt.el.dom);
+                        groupCt.suspendLayout = false;
+                    } else {
+                        fromCt.minWidth = fromCt.getWidth() - hd.getWidth();
+                        fromCt.setWidth(fromCt.minWidth);
+                    }
+                }
+
+                // Move dragged header into its drop position
+                toCt.suspendLayout = true;
+                if (fromCt === toCt) {
+                    toCt.move(fromIdx, toIdx);
+                } else {
+                    toCt.insert(toIdx, hd);
+                }
+                toCt.suspendLayout = false;
+
+                // Group headers acquire the aggregate width of their child headers
+                // Therefore a child header may not flex; it must contribute a fixed width.
+                // But we restore the flex value when moving back into the main header container
+                if (toCt.isGroupHeader) {
+                    hd.savedFlex = hd.flex;
+                    delete hd.flex;
+                    hd.width = hd.getWidth();
+                    // When there was previously a flex, we need to ensure we don't count for the
+                    // border twice.
+                    toCt.minWidth = toCt.getWidth() + hd.getWidth() - (hd.savedFlex ? 1 : 0);
+                    toCt.setWidth(toCt.minWidth);
+                } else {
+                    if (hd.savedFlex) {
+                        hd.flex = hd.savedFlex;
+                        delete hd.width;
+                    }
+                }
+
+
+                // Refresh columns cache in case we remove an emptied group column
+                headerCt.purgeCache();
+                headerCt.doLayout();
+                headerCt.onHeaderMoved(hd, fromIdx, toIdx);
+                // Emptied group header can only be destroyed after the header and grid have been refreshed
+                if (!fromCt.items.getCount()) {
+                    fromCt.destroy();
+                }
+            }
+        }
+    }
+});
+</pre>
+</body>
+</html>