123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- /**
- * @class Ext.ux.DataView.DragSelector
- * @extends Object
- * @author Ed Spencer
- *
- */
- Ext.define('Ext.ux.DataView.DragSelector', {
- requires: ['Ext.dd.DragTracker', 'Ext.util.Region'],
- /**
- * Initializes the plugin by setting up the drag tracker
- */
- init: function(dataview) {
- /**
- * @property dataview
- * @type Ext.view.View
- * The DataView bound to this instance
- */
- this.dataview = dataview;
- dataview.mon(dataview, {
- beforecontainerclick: this.cancelClick,
- scope: this,
- render: {
- fn: this.onRender,
- scope: this,
- single: true
- }
- });
- },
- /**
- * @private
- * Called when the attached DataView is rendered. This sets up the DragTracker instance that will be used
- * to created a dragged selection area
- */
- onRender: function() {
- /**
- * @property tracker
- * @type Ext.dd.DragTracker
- * The DragTracker attached to this instance. Note that the 4 on* functions are called in the scope of the
- * DragTracker ('this' refers to the DragTracker inside those functions), so we pass a reference to the
- * DragSelector so that we can call this class's functions.
- */
- this.tracker = Ext.create('Ext.dd.DragTracker', {
- dataview: this.dataview,
- el: this.dataview.el,
- dragSelector: this,
- onBeforeStart: this.onBeforeStart,
- onStart: this.onStart,
- onDrag : this.onDrag,
- onEnd : this.onEnd
- });
- /**
- * @property dragRegion
- * @type Ext.util.Region
- * Represents the region currently dragged out by the user. This is used to figure out which dataview nodes are
- * in the selected area and to set the size of the Proxy element used to highlight the current drag area
- */
- this.dragRegion = Ext.create('Ext.util.Region');
- },
- /**
- * @private
- * Listener attached to the DragTracker's onBeforeStart event. Returns false if the drag didn't start within the
- * DataView's el
- */
- onBeforeStart: function(e) {
- return e.target == this.dataview.getEl().dom;
- },
- /**
- * @private
- * Listener attached to the DragTracker's onStart event. Cancel's the DataView's containerclick event from firing
- * and sets the start co-ordinates of the Proxy element. Clears any existing DataView selection
- * @param {Ext.EventObject} e The click event
- */
- onStart: function(e) {
- var dragSelector = this.dragSelector,
- dataview = this.dataview;
- // Flag which controls whether the cancelClick method vetoes the processing of the DataView's containerclick event.
- // On IE (where else), this needs to remain set for a millisecond after mouseup because even though the mouse has
- // moved, the mouseup will still trigger a click event.
- this.dragging = true;
- //here we reset and show the selection proxy element and cache the regions each item in the dataview take up
- dragSelector.fillRegions();
- dragSelector.getProxy().show();
- dataview.getSelectionModel().deselectAll();
- },
- /**
- * @private
- * Reusable handler that's used to cancel the container click event when dragging on the dataview. See onStart for
- * details
- */
- cancelClick: function() {
- return !this.tracker.dragging;
- },
- /**
- * @private
- * Listener attached to the DragTracker's onDrag event. Figures out how large the drag selection area should be and
- * updates the proxy element's size to match. Then iterates over all of the rendered items and marks them selected
- * if the drag region touches them
- * @param {Ext.EventObject} e The drag event
- */
- onDrag: function(e) {
- var dragSelector = this.dragSelector,
- selModel = dragSelector.dataview.getSelectionModel(),
- dragRegion = dragSelector.dragRegion,
- bodyRegion = dragSelector.bodyRegion,
- proxy = dragSelector.getProxy(),
- regions = dragSelector.regions,
- length = regions.length,
- startXY = this.startXY,
- currentXY = this.getXY(),
- minX = Math.min(startXY[0], currentXY[0]),
- minY = Math.min(startXY[1], currentXY[1]),
- width = Math.abs(startXY[0] - currentXY[0]),
- height = Math.abs(startXY[1] - currentXY[1]),
- region, selected, i;
- Ext.apply(dragRegion, {
- top: minY,
- left: minX,
- right: minX + width,
- bottom: minY + height
- });
- dragRegion.constrainTo(bodyRegion);
- proxy.setRegion(dragRegion);
- for (i = 0; i < length; i++) {
- region = regions[i];
- selected = dragRegion.intersect(region);
- if (selected) {
- selModel.select(i, true);
- } else {
- selModel.deselect(i);
- }
- }
- },
- /**
- * @private
- * Listener attached to the DragTracker's onEnd event. This is a delayed function which executes 1
- * millisecond after it has been called. This is because the dragging flag must remain active to cancel
- * the containerclick event which the mouseup event will trigger.
- * @param {Ext.EventObject} e The event object
- */
- onEnd: Ext.Function.createDelayed(function(e) {
- var dataview = this.dataview,
- selModel = dataview.getSelectionModel(),
- dragSelector = this.dragSelector;
- this.dragging = false;
- dragSelector.getProxy().hide();
- }, 1),
- /**
- * @private
- * Creates a Proxy element that will be used to highlight the drag selection region
- * @return {Ext.Element} The Proxy element
- */
- getProxy: function() {
- if (!this.proxy) {
- this.proxy = this.dataview.getEl().createChild({
- tag: 'div',
- cls: 'x-view-selector'
- });
- }
- return this.proxy;
- },
- /**
- * @private
- * Gets the region taken up by each rendered node in the DataView. We use these regions to figure out which nodes
- * to select based on the selector region the user has dragged out
- */
- fillRegions: function() {
- var dataview = this.dataview,
- regions = this.regions = [];
- dataview.all.each(function(node) {
- regions.push(node.getRegion());
- });
- this.bodyRegion = dataview.getEl().getRegion();
- }
- });
|