| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 | <!DOCTYPE html><html><head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <title>The source code</title>  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />  <script type="text/javascript" src="../resources/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-view-DropZone'>/**</span> * @private */Ext.define('Ext.view.DropZone', {    extend: 'Ext.dd.DropZone',    indicatorHtml: '<div class="' + Ext.baseCSSPrefix + 'grid-drop-indicator-left"></div><div class="' + Ext.baseCSSPrefix + 'grid-drop-indicator-right"></div>',    indicatorCls: Ext.baseCSSPrefix + 'grid-drop-indicator',    constructor: function(config) {        var me = this;        Ext.apply(me, config);        // Create a ddGroup unless one has been configured.        // User configuration of ddGroups allows users to specify which        // DD instances can interact with each other. Using one        // based on the id of the View would isolate it and mean it can only        // interact with a DragZone on the same View also using a generated ID.        if (!me.ddGroup) {            me.ddGroup = 'view-dd-zone-' + me.view.id;        }        // The DropZone's encapsulating element is the View's main element. It must be this because drop gestures        // may require scrolling on hover near a scrolling boundary. In Ext 4.x two DD instances may not use the        // same element, so a DragZone on this same View must use the View's parent element as its element.        me.callParent([me.view.el]);    },//  Fire an event through the client DataView. Lock this DropZone during the event processing so that//  its data does not become corrupted by processing mouse events.    fireViewEvent: function() {        var me = this,            result;        me.lock();        result = me.view.fireEvent.apply(me.view, arguments);        me.unlock();        return result;    },    getTargetFromEvent : function(e) {        var node = e.getTarget(this.view.getItemSelector()),            mouseY, nodeList, testNode, i, len, box;//      Not over a row node: The content may be narrower than the View's encapsulating element, so return the closest.//      If we fall through because the mouse is below the nodes (or there are no nodes), we'll get an onContainerOver call.        if (!node) {            mouseY = e.getPageY();            for (i = 0, nodeList = this.view.getNodes(), len = nodeList.length; i < len; i++) {                testNode = nodeList[i];                box = Ext.fly(testNode).getBox();                if (mouseY <= box.bottom) {                    return testNode;                }            }        }        return node;    },    getIndicator: function() {        var me = this;        if (!me.indicator) {            me.indicator = new Ext.Component({                html: me.indicatorHtml,                cls: me.indicatorCls,                ownerCt: me.view,                floating: true,                shadow: false            });        }        return me.indicator;    },    getPosition: function(e, node) {        var y      = e.getXY()[1],            region = Ext.fly(node).getRegion(),            pos;        if ((region.bottom - y) >= (region.bottom - region.top) / 2) {            pos = "before";        } else {            pos = "after";        }        return pos;    },<span id='Ext-view-DropZone-method-containsRecordAtOffset'>    /**</span>     * @private Determines whether the record at the specified offset from the passed record     * is in the drag payload.     * @param records     * @param record     * @param offset     * @returns {Boolean} True if the targeted record is in the drag payload     */    containsRecordAtOffset: function(records, record, offset) {        if (!record) {            return false;        }        var view = this.view,            recordIndex = view.indexOf(record),            nodeBefore = view.getNode(recordIndex + offset),            recordBefore = nodeBefore ? view.getRecord(nodeBefore) : null;        return recordBefore && Ext.Array.contains(records, recordBefore);    },    positionIndicator: function(node, data, e) {        var me = this,            view = me.view,            pos = me.getPosition(e, node),            overRecord = view.getRecord(node),            draggingRecords = data.records,            indicatorY;        if (!Ext.Array.contains(draggingRecords, overRecord) && (            pos == 'before' && !me.containsRecordAtOffset(draggingRecords, overRecord, -1) ||            pos == 'after' && !me.containsRecordAtOffset(draggingRecords, overRecord, 1)        )) {            me.valid = true;            if (me.overRecord != overRecord || me.currentPosition != pos) {                indicatorY = Ext.fly(node).getY() - view.el.getY() - 1;                if (pos == 'after') {                    indicatorY += Ext.fly(node).getHeight();                }                me.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, indicatorY);                // Cache the overRecord and the 'before' or 'after' indicator.                me.overRecord = overRecord;                me.currentPosition = pos;            }        } else {            me.invalidateDrop();        }    },    invalidateDrop: function() {        if (this.valid) {            this.valid = false;            this.getIndicator().hide();        }    },    // The mouse is over a View node    onNodeOver: function(node, dragZone, e, data) {        var me = this;        if (!Ext.Array.contains(data.records, me.view.getRecord(node))) {            me.positionIndicator(node, data, e);        }        return me.valid ? me.dropAllowed : me.dropNotAllowed;    },    // Moved out of the DropZone without dropping.    // Remove drop position indicator    notifyOut: function(node, dragZone, e, data) {        var me = this;        me.callParent(arguments);        delete me.overRecord;        delete me.currentPosition;        if (me.indicator) {            me.indicator.hide();        }    },    // The mouse is past the end of all nodes (or there are no nodes)    onContainerOver : function(dd, e, data) {        var me = this,            view = me.view,            count = view.store.getCount();        // There are records, so position after the last one        if (count) {            me.positionIndicator(view.getNode(count - 1), data, e);        }        // No records, position the indicator at the top        else {            delete me.overRecord;            delete me.currentPosition;            me.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, 0);            me.valid = true;        }        return me.dropAllowed;    },    onContainerDrop : function(dd, e, data) {        return this.onNodeDrop(dd, null, e, data);    },    onNodeDrop: function(node, dragZone, e, data) {        var me = this,            dropHandled = false,             // Create a closure to perform the operation which the event handler may use.            // Users may now set the wait parameter in the beforedrop handler, and perform any kind            // of asynchronous processing such as an Ext.Msg.confirm, or an Ajax request,            // and complete the drop gesture at some point in the future by calling either the            // processDrop or cancelDrop methods.            dropHandlers = {                wait: false,                processDrop: function () {                    me.invalidateDrop();                    me.handleNodeDrop(data, me.overRecord, me.currentPosition);                    dropHandled = true;                    me.fireViewEvent('drop', node, data, me.overRecord, me.currentPosition);                },                 cancelDrop: function() {                    me.invalidateDrop();                    dropHandled = true;                }            },            performOperation = false;         if (me.valid) {            performOperation = me.fireViewEvent('beforedrop', node, data, me.overRecord, me.currentPosition, dropHandlers);            if (dropHandlers.wait) {                return;            }             if (performOperation !== false) {                // If either of the drop handlers were called in the event handler, do not do it again.                if (!dropHandled) {                    dropHandlers.processDrop();                }            }        }        return performOperation;    },        destroy: function(){        Ext.destroy(this.indicator);        delete this.indicator;        this.callParent();    }});</pre></body></html>
 |