X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/b37ceabb82336ee82757cd32efe353cfab8ec267..f5240829880f87e0cf581c6a296e436fdef0ef80:/examples/ux/Reorderer.js diff --git a/examples/ux/Reorderer.js b/examples/ux/Reorderer.js index a6b76d2d..e5878f80 100644 --- a/examples/ux/Reorderer.js +++ b/examples/ux/Reorderer.js @@ -1,5 +1,5 @@ /*! - * Ext JS Library 3.2.2 + * Ext JS Library 3.3.0 * Copyright(c) 2006-2010 Ext JS, Inc. * licensing@extjs.com * http://www.extjs.com/license @@ -66,8 +66,11 @@ Ext.ux.Reorderer = Ext.extend(Object, { this.initEvents(); - var items = this.getItems(); - for (var i=0; i < items.length; i++) { + var items = this.getItems(), + length = items.length, + i; + + for (i = 0; i < length; i++) { this.createIfReorderable(items[i]); } }, @@ -193,9 +196,11 @@ Ext.ux.Reorderer = Ext.extend(Object, { * @param {Mixed} item The item */ createIfReorderable: function(item) { - if (this.defaultReorderable && item.reorderable == undefined) item.reorderable = true; + if (this.defaultReorderable && item.reorderable == undefined) { + item.reorderable = true; + } - if (item.reorderable) { + if (item.reorderable && !item.dd) { if (item.rendered) { this.createItemDD(item); } else { @@ -237,4 +242,184 @@ Ext.ux.Reorderer = Ext.extend(Object, { 'reorder' ); } +}); + +/** + * @class Ext.ux.HBoxReorderer + * @extends Ext.ux.Reorderer + * Description + */ +Ext.ux.HBoxReorderer = Ext.extend(Ext.ux.Reorderer, { + /** + * Initializes the plugin, decorates the container with additional functionality + */ + init: function(container) { + /** + * This is used to store the correct x value of each button in the array. We need to use this + * instead of the button's reported x co-ordinate because the buttons are animated when they move - + * if another onDrag is fired while the button is still moving, the comparison x value will be incorrect + */ + this.buttonXCache = {}; + + container.on({ + scope: this, + add : function(container, item) { + this.createIfReorderable(item); + } + }); + + //super sets a reference to the toolbar in this.target + Ext.ux.HBoxReorderer.superclass.init.apply(this, arguments); + }, + + /** + * Sets up the given Toolbar item as a draggable + * @param {Mixed} button The item to make draggable (usually an Ext.Button instance) + */ + createItemDD: function(button) { + if (button.dd != undefined) { + return; + } + + var el = button.getEl(), + id = el.id, + me = this, + tbar = me.target; + + button.dd = new Ext.dd.DD(el, undefined, { + isTarget: false + }); + + el.applyStyles({ + position: 'absolute' + }); + + //if a button has a menu, it is disabled while dragging with this function + var menuDisabler = function() { + return false; + }; + + Ext.apply(button.dd, { + b4StartDrag: function() { + this.startPosition = el.getXY(); + + //bump up the z index of the button being dragged but keep a reference to the original + this.startZIndex = el.getStyle('zIndex'); + el.setStyle('zIndex', 10000); + + button.suspendEvents(); + if (button.menu) { + button.menu.on('beforeshow', menuDisabler, me); + } + }, + + startDrag: function() { + this.constrainTo(tbar.getEl()); + this.setYConstraint(0, 0, 0); + }, + + onDrag: function(e) { + //calculate the button's index within the toolbar and its current midpoint + var buttonX = el.getXY()[0], + deltaX = buttonX - this.startPosition[0], + items = tbar.items.items, + length = items.length, + oldIndex = items.indexOf(button), + newIndex, index, item; + + //find which item in the toolbar the midpoint is currently over + for (index = 0; index < length; index++) { + item = items[index]; + + if (item.reorderable && item.id != button.id) { + //find the midpoint of the button + var box = item.getEl().getBox(), + midpoint = (me.buttonXCache[item.id] || box.x) + (box.width / 2), + movedLeft = oldIndex > index && deltaX < 0 && buttonX < midpoint, + movedRight = oldIndex < index && deltaX > 0 && (buttonX + el.getWidth()) > midpoint; + + if (movedLeft || movedRight) { + me[movedLeft ? 'onMovedLeft' : 'onMovedRight'](button, index, oldIndex); + break; + } + } + } + }, + + /** + * After the drag has been completed, make sure the button being dragged makes it back to + * the correct location and resets its z index + */ + endDrag: function() { + //we need to update the cache here for cases where the button was dragged but its + //position in the toolbar did not change + me.updateButtonXCache(); + + el.moveTo(me.buttonXCache[button.id], el.getY(), { + duration: me.animationDuration, + scope : this, + callback: function() { + button.resumeEvents(); + if (button.menu) { + button.menu.un('beforeshow', menuDisabler, me); + } + + tbar.fireEvent('reordered', button, tbar); + } + }); + + el.setStyle('zIndex', this.startZIndex); + } + }); + }, + + onMovedLeft: function(item, newIndex, oldIndex) { + var tbar = this.target, + items = tbar.items.items, + length = items.length, + index; + + if (newIndex != undefined && newIndex != oldIndex) { + //move the button currently under drag to its new location + tbar.remove(item, false); + tbar.insert(newIndex, item); + + //set the correct x location of each item in the toolbar + this.updateButtonXCache(); + for (index = 0; index < length; index++) { + var obj = items[index], + newX = this.buttonXCache[obj.id]; + + if (item == obj) { + item.dd.startPosition[0] = newX; + } else { + var el = obj.getEl(); + + el.moveTo(newX, el.getY(), { + duration: this.animationDuration + }); + } + } + } + }, + + onMovedRight: function(item, newIndex, oldIndex) { + this.onMovedLeft.apply(this, arguments); + }, + + /** + * @private + * Updates the internal cache of button X locations. + */ + updateButtonXCache: function() { + var tbar = this.target, + items = tbar.items, + totalX = tbar.getEl().getBox(true).x; + + items.each(function(item) { + this.buttonXCache[item.id] = totalX; + + totalX += item.getEl().getWidth(); + }, this); + } }); \ No newline at end of file