/*!
- * 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
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]);
}
},
* @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 {
'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