Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / src / view / DragZone.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
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.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /**
16  * @class Ext.view.DragZone
17  * @extends Ext.dd.DragZone
18  * @private
19  */
20 Ext.define('Ext.view.DragZone', {
21     extend: 'Ext.dd.DragZone',
22     containerScroll: false,
23
24     constructor: function(config) {
25         var me = this;
26
27         Ext.apply(me, config);
28
29         // Create a ddGroup unless one has been configured.
30         // User configuration of ddGroups allows users to specify which
31         // DD instances can interact with each other. Using one
32         // based on the id of the View would isolate it and mean it can only
33         // interact with a DropZone on the same View also using a generated ID.
34         if (!me.ddGroup) {
35             me.ddGroup = 'view-dd-zone-' + me.view.id;
36         }
37
38         // Ext.dd.DragDrop instances are keyed by the ID of their encapsulating element.
39         // So a View's DragZone cannot use the View's main element because the DropZone must use that
40         // because the DropZone may need to scroll on hover at a scrolling boundary, and it is the View's
41         // main element which handles scrolling.
42         // We use the View's parent element to drag from. Ideally, we would use the internal structure, but that
43         // is transient; DataView's recreate the internal structure dynamically as data changes.
44         // TODO: Ext 5.0 DragDrop must allow multiple DD objects to share the same element.
45         me.callParent([me.view.el.dom.parentNode]);
46
47         me.ddel = Ext.get(document.createElement('div'));
48         me.ddel.addCls(Ext.baseCSSPrefix + 'grid-dd-wrap');
49     },
50
51     init: function(id, sGroup, config) {
52         this.initTarget(id, sGroup, config);
53         this.view.mon(this.view, {
54             itemmousedown: this.onItemMouseDown,
55             scope: this
56         });
57     },
58
59     onItemMouseDown: function(view, record, item, index, e) {
60         if (!this.isPreventDrag(e, record, item, index)) {
61             this.handleMouseDown(e);
62
63             // If we want to allow dragging of multi-selections, then veto the following handlers (which, in the absence of ctrlKey, would deselect)
64             // if the mousedowned record is selected
65             if (view.getSelectionModel().selectionMode == 'MULTI' && !e.ctrlKey && view.getSelectionModel().isSelected(record)) {
66                 return false;
67             }
68         }
69     },
70
71     // private template method
72     isPreventDrag: function(e) {
73         return false;
74     },
75
76     getDragData: function(e) {
77         var view = this.view,
78             item = e.getTarget(view.getItemSelector()),
79             record, selectionModel, records;
80
81         if (item) {
82             record = view.getRecord(item);
83             selectionModel = view.getSelectionModel();
84             records = selectionModel.getSelection();
85             return {
86                 copy: this.view.copy || (this.view.allowCopy && e.ctrlKey),
87                 event: new Ext.EventObjectImpl(e),
88                 view: view,
89                 ddel: this.ddel,
90                 item: item,
91                 records: records,
92                 fromPosition: Ext.fly(item).getXY()
93             };
94         }
95     },
96
97     onInitDrag: function(x, y) {
98         var me = this,
99             data = me.dragData,
100             view = data.view,
101             selectionModel = view.getSelectionModel(),
102             record = view.getRecord(data.item),
103             e = data.event;
104
105         // Update the selection to match what would have been selected if the user had
106         // done a full click on the target node rather than starting a drag from it
107         if (!selectionModel.isSelected(record) || e.hasModifier()) {
108             selectionModel.selectWithEvent(record, e, true);
109         }
110         data.records = selectionModel.getSelection();
111
112         me.ddel.update(me.getDragText());
113         me.proxy.update(me.ddel.dom);
114         me.onStartDrag(x, y);
115         return true;
116     },
117
118     getDragText: function() {
119         var count = this.dragData.records.length;
120         return Ext.String.format(this.dragText, count, count == 1 ? '' : 's');
121     },
122
123     getRepairXY : function(e, data){
124         return data ? data.fromPosition : false;
125     }
126 });