X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/src/dd/DDProxy.js diff --git a/src/dd/DDProxy.js b/src/dd/DDProxy.js new file mode 100644 index 00000000..016a8657 --- /dev/null +++ b/src/dd/DDProxy.js @@ -0,0 +1,208 @@ +/* + * This is a derivative of the similarly named class in the YUI Library. + * The original license: + * Copyright (c) 2006, Yahoo! Inc. All rights reserved. + * Code licensed under the BSD License: + * http://developer.yahoo.net/yui/license.txt + */ + +/** + * @class Ext.dd.DDProxy + * A DragDrop implementation that inserts an empty, bordered div into + * the document that follows the cursor during drag operations. At the time of + * the click, the frame div is resized to the dimensions of the linked html + * element, and moved to the exact location of the linked element. + * + * References to the "frame" element refer to the single proxy element that + * was created to be dragged in place of all DDProxy elements on the + * page. + * + * @extends Ext.dd.DD + * @constructor + * @param {String} id the id of the linked html element + * @param {String} sGroup the group of related DragDrop objects + * @param {object} config an object containing configurable attributes + * Valid properties for DDProxy in addition to those in DragDrop: + * resizeFrame, centerFrame, dragElId + */ +Ext.define('Ext.dd.DDProxy', { + extend: 'Ext.dd.DD', + + statics: { + /** + * The default drag frame div id + * @property Ext.dd.DDProxy.dragElId + * @type String + * @static + */ + dragElId: "ygddfdiv" + }, + + constructor: function(id, sGroup, config) { + if (id) { + this.init(id, sGroup, config); + this.initFrame(); + } + }, + + /** + * By default we resize the drag frame to be the same size as the element + * we want to drag (this is to get the frame effect). We can turn it off + * if we want a different behavior. + * @property resizeFrame + * @type boolean + */ + resizeFrame: true, + + /** + * By default the frame is positioned exactly where the drag element is, so + * we use the cursor offset provided by Ext.dd.DD. Another option that works only if + * you do not have constraints on the obj is to have the drag frame centered + * around the cursor. Set centerFrame to true for this effect. + * @property centerFrame + * @type boolean + */ + centerFrame: false, + + /** + * Creates the proxy element if it does not yet exist + * @method createFrame + */ + createFrame: function() { + var self = this; + var body = document.body; + + if (!body || !body.firstChild) { + setTimeout( function() { self.createFrame(); }, 50 ); + return; + } + + var div = this.getDragEl(); + + if (!div) { + div = document.createElement("div"); + div.id = this.dragElId; + var s = div.style; + + s.position = "absolute"; + s.visibility = "hidden"; + s.cursor = "move"; + s.border = "2px solid #aaa"; + s.zIndex = 999; + + // appendChild can blow up IE if invoked prior to the window load event + // while rendering a table. It is possible there are other scenarios + // that would cause this to happen as well. + body.insertBefore(div, body.firstChild); + } + }, + + /** + * Initialization for the drag frame element. Must be called in the + * constructor of all subclasses + * @method initFrame + */ + initFrame: function() { + this.createFrame(); + }, + + applyConfig: function() { + this.callParent(); + + this.resizeFrame = (this.config.resizeFrame !== false); + this.centerFrame = (this.config.centerFrame); + this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId); + }, + + /** + * Resizes the drag frame to the dimensions of the clicked object, positions + * it over the object, and finally displays it + * @method showFrame + * @param {int} iPageX X click position + * @param {int} iPageY Y click position + * @private + */ + showFrame: function(iPageX, iPageY) { + var el = this.getEl(); + var dragEl = this.getDragEl(); + var s = dragEl.style; + + this._resizeProxy(); + + if (this.centerFrame) { + this.setDelta( Math.round(parseInt(s.width, 10)/2), + Math.round(parseInt(s.height, 10)/2) ); + } + + this.setDragElPos(iPageX, iPageY); + + Ext.fly(dragEl).show(); + }, + + /** + * The proxy is automatically resized to the dimensions of the linked + * element when a drag is initiated, unless resizeFrame is set to false + * @method _resizeProxy + * @private + */ + _resizeProxy: function() { + if (this.resizeFrame) { + var el = this.getEl(); + Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight); + } + }, + + // overrides Ext.dd.DragDrop + b4MouseDown: function(e) { + var x = e.getPageX(); + var y = e.getPageY(); + this.autoOffset(x, y); + this.setDragElPos(x, y); + }, + + // overrides Ext.dd.DragDrop + b4StartDrag: function(x, y) { + // show the drag frame + this.showFrame(x, y); + }, + + // overrides Ext.dd.DragDrop + b4EndDrag: function(e) { + Ext.fly(this.getDragEl()).hide(); + }, + + // overrides Ext.dd.DragDrop + // By default we try to move the element to the last location of the frame. + // This is so that the default behavior mirrors that of Ext.dd.DD. + endDrag: function(e) { + + var lel = this.getEl(); + var del = this.getDragEl(); + + // Show the drag frame briefly so we can get its position + del.style.visibility = ""; + + this.beforeMove(); + // Hide the linked element before the move to get around a Safari + // rendering bug. + lel.style.visibility = "hidden"; + Ext.dd.DDM.moveToEl(lel, del); + del.style.visibility = "hidden"; + lel.style.visibility = ""; + + this.afterDrag(); + }, + + beforeMove : function(){ + + }, + + afterDrag : function(){ + + }, + + toString: function() { + return ("DDProxy " + this.id); + } + +});