]> git.proxmox.com Git - extjs.git/blob - extjs/packages/ux/classic/src/DataView/DragSelector.js
add extjs 6.0.1 sources
[extjs.git] / extjs / packages / ux / classic / src / DataView / DragSelector.js
1 /**
2 *
3 */
4 Ext.define('Ext.ux.DataView.DragSelector', {
5 requires: ['Ext.dd.DragTracker', 'Ext.util.Region'],
6
7 /**
8 * Initializes the plugin by setting up the drag tracker
9 */
10 init: function(dataview) {
11 /**
12 * @property dataview
13 * @type Ext.view.View
14 * The DataView bound to this instance
15 */
16 this.dataview = dataview;
17 dataview.mon(dataview, {
18 beforecontainerclick: this.cancelClick,
19 scope: this,
20 render: {
21 fn: this.onRender,
22 scope: this,
23 single: true
24 }
25 });
26 },
27
28 /**
29 * @private
30 * Called when the attached DataView is rendered. This sets up the DragTracker instance that will be used
31 * to created a dragged selection area
32 */
33 onRender: function() {
34 /**
35 * @property tracker
36 * @type Ext.dd.DragTracker
37 * The DragTracker attached to this instance. Note that the 4 on* functions are called in the scope of the
38 * DragTracker ('this' refers to the DragTracker inside those functions), so we pass a reference to the
39 * DragSelector so that we can call this class's functions.
40 */
41 this.tracker = Ext.create('Ext.dd.DragTracker', {
42 dataview: this.dataview,
43 el: this.dataview.el,
44 dragSelector: this,
45 onBeforeStart: this.onBeforeStart,
46 onStart: this.onStart,
47 onDrag : this.onDrag,
48 onEnd : this.onEnd
49 });
50
51 /**
52 * @property dragRegion
53 * @type Ext.util.Region
54 * Represents the region currently dragged out by the user. This is used to figure out which dataview nodes are
55 * in the selected area and to set the size of the Proxy element used to highlight the current drag area
56 */
57 this.dragRegion = Ext.create('Ext.util.Region');
58 },
59
60 /**
61 * @private
62 * Listener attached to the DragTracker's onBeforeStart event. Returns false if the drag didn't start within the
63 * DataView's el
64 */
65 onBeforeStart: function(e) {
66 return e.target == this.dataview.getEl().dom;
67 },
68
69 /**
70 * @private
71 * Listener attached to the DragTracker's onStart event. Cancel's the DataView's containerclick event from firing
72 * and sets the start co-ordinates of the Proxy element. Clears any existing DataView selection
73 * @param {Ext.event.Event} e The click event
74 */
75 onStart: function(e) {
76 var dragSelector = this.dragSelector,
77 dataview = this.dataview;
78
79 // Flag which controls whether the cancelClick method vetoes the processing of the DataView's containerclick event.
80 // On IE (where else), this needs to remain set for a millisecond after mouseup because even though the mouse has
81 // moved, the mouseup will still trigger a click event.
82 this.dragging = true;
83
84 //here we reset and show the selection proxy element and cache the regions each item in the dataview take up
85 dragSelector.fillRegions();
86 dragSelector.getProxy().show();
87 dataview.getSelectionModel().deselectAll();
88 },
89
90 /**
91 * @private
92 * Reusable handler that's used to cancel the container click event when dragging on the dataview. See onStart for
93 * details
94 */
95 cancelClick: function() {
96 return !this.tracker.dragging;
97 },
98
99 /**
100 * @private
101 * Listener attached to the DragTracker's onDrag event. Figures out how large the drag selection area should be and
102 * updates the proxy element's size to match. Then iterates over all of the rendered items and marks them selected
103 * if the drag region touches them
104 * @param {Ext.event.Event} e The drag event
105 */
106 onDrag: function(e) {
107 var dragSelector = this.dragSelector,
108 selModel = dragSelector.dataview.getSelectionModel(),
109 dragRegion = dragSelector.dragRegion,
110 bodyRegion = dragSelector.bodyRegion,
111 proxy = dragSelector.getProxy(),
112 regions = dragSelector.regions,
113 length = regions.length,
114
115 startXY = this.startXY,
116 currentXY = this.getXY(),
117 minX = Math.min(startXY[0], currentXY[0]),
118 minY = Math.min(startXY[1], currentXY[1]),
119 width = Math.abs(startXY[0] - currentXY[0]),
120 height = Math.abs(startXY[1] - currentXY[1]),
121 region, selected, i;
122
123 Ext.apply(dragRegion, {
124 top: minY,
125 left: minX,
126 right: minX + width,
127 bottom: minY + height
128 });
129
130 dragRegion.constrainTo(bodyRegion);
131 proxy.setBox(dragRegion);
132
133 for (i = 0; i < length; i++) {
134 region = regions[i];
135 selected = dragRegion.intersect(region);
136
137 if (selected) {
138 selModel.select(i, true);
139 } else {
140 selModel.deselect(i);
141 }
142 }
143 },
144
145 /**
146 * @method
147 * @private
148 * Listener attached to the DragTracker's onEnd event. This is a delayed function which executes 1
149 * millisecond after it has been called. This is because the dragging flag must remain active to cancel
150 * the containerclick event which the mouseup event will trigger.
151 * @param {Ext.event.Event} e The event object
152 */
153 onEnd: Ext.Function.createDelayed(function(e) {
154 var dataview = this.dataview,
155 selModel = dataview.getSelectionModel(),
156 dragSelector = this.dragSelector;
157
158 this.dragging = false;
159 dragSelector.getProxy().hide();
160 }, 1),
161
162 /**
163 * @private
164 * Creates a Proxy element that will be used to highlight the drag selection region
165 * @return {Ext.Element} The Proxy element
166 */
167 getProxy: function() {
168 if (!this.proxy) {
169 this.proxy = this.dataview.getEl().createChild({
170 tag: 'div',
171 cls: 'x-view-selector'
172 });
173 }
174 return this.proxy;
175 },
176
177 /**
178 * @private
179 * Gets the region taken up by each rendered node in the DataView. We use these regions to figure out which nodes
180 * to select based on the selector region the user has dragged out
181 */
182 fillRegions: function() {
183 var dataview = this.dataview,
184 regions = this.regions = [];
185
186 dataview.all.each(function(node) {
187 regions.push(node.getRegion());
188 });
189 this.bodyRegion = dataview.getEl().getRegion();
190 }
191 });