d496a63ee149788aa4d88a20afc30262249fad2b.svn-base 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com
  3. *
  4. * http://extjs.com/license
  5. */
  6. Ext.ux.Portal = Ext.extend(Ext.Panel, {
  7. layout : 'column',
  8. autoScroll : true,
  9. cls : 'x-portal',
  10. defaultType : 'portalcolumn',
  11. initComponent : function() {
  12. Ext.ux.Portal.superclass.initComponent.call(this);
  13. this.addEvents({
  14. validatedrop : true,
  15. beforedragover : true,
  16. dragover : true,
  17. beforedrop : true,
  18. drop : true
  19. });
  20. },
  21. initEvents : function() {
  22. Ext.ux.Portal.superclass.initEvents.call(this);
  23. this.dd = new Ext.ux.Portal.DropZone(this, this.dropConfig);
  24. }
  25. });
  26. Ext.reg('portal', Ext.ux.Portal);
  27. Ext.ux.Portal.DropZone = function(portal, cfg) {
  28. this.portal = portal;
  29. Ext.dd.ScrollManager.register(portal.body);
  30. Ext.ux.Portal.DropZone.superclass.constructor.call(this, portal.bwrap.dom,
  31. cfg);
  32. portal.body.ddScrollConfig = this.ddScrollConfig;
  33. };
  34. Ext.extend(Ext.ux.Portal.DropZone, Ext.dd.DropTarget, {
  35. ddScrollConfig : {
  36. vthresh : 50,
  37. hthresh : -1,
  38. animate : true,
  39. increment : 200
  40. },
  41. createEvent : function(dd, e, data, col, c, pos) {
  42. return {
  43. portal : this.portal,
  44. panel : data.panel,
  45. columnIndex : col,
  46. column : c,
  47. position : pos,
  48. data : data,
  49. source : dd,
  50. rawEvent : e,
  51. status : this.dropAllowed
  52. };
  53. },
  54. notifyOver : function(dd, e, data) {
  55. var xy = e.getXY(), portal = this.portal, px = dd.proxy;
  56. // case column widths
  57. if (!this.grid) {
  58. this.grid = this.getGrid();
  59. }
  60. // handle case scroll where scrollbars appear during drag
  61. var cw = portal.body.dom.clientWidth;
  62. if (!this.lastCW) {
  63. this.lastCW = cw;
  64. } else if (this.lastCW != cw) {
  65. this.lastCW = cw;
  66. portal.doLayout();
  67. this.grid = this.getGrid();
  68. }
  69. // determine column
  70. var col = 0, xs = this.grid.columnX, cmatch = false;
  71. for (var len = xs.length; col < len; col++) {
  72. if (xy[0] < (xs[col].x + xs[col].w)) {
  73. cmatch = true;
  74. break;
  75. }
  76. }
  77. // no match, fix last index
  78. if (!cmatch) {
  79. col--;
  80. }
  81. // find insert position
  82. var p, match = false, pos = 0, c = portal.items.itemAt(col), items = c.items.items;
  83. for (var len = items.length; pos < len; pos++) {
  84. p = items[pos];
  85. var h = p.el.getHeight();
  86. if (h !== 0 && (p.el.getY() + (h / 2)) > xy[1]) {
  87. match = true;
  88. break;
  89. }
  90. }
  91. var overEvent = this.createEvent(dd, e, data, col, c, match && p
  92. ? pos
  93. : c.items.getCount());
  94. if (portal.fireEvent('validatedrop', overEvent) !== false
  95. && portal.fireEvent('beforedragover', overEvent) !== false) {
  96. // make sure proxy width is fluid
  97. px.getProxy().setWidth('auto');
  98. if (p) {
  99. px.moveProxy(p.el.dom.parentNode, match ? p.el.dom : null);
  100. } else {
  101. px.moveProxy(c.el.dom, null);
  102. }
  103. this.lastPos = {
  104. c : c,
  105. col : col,
  106. p : match && p ? pos : false
  107. };
  108. this.scrollPos = portal.body.getScroll();
  109. portal.fireEvent('dragover', overEvent);
  110. return overEvent.status;;
  111. } else {
  112. return overEvent.status;
  113. }
  114. },
  115. notifyOut : function() {
  116. delete this.grid;
  117. },
  118. notifyDrop : function(dd, e, data) {
  119. delete this.grid;
  120. if (!this.lastPos) {
  121. return;
  122. }
  123. var c = this.lastPos.c, col = this.lastPos.col, pos = this.lastPos.p;
  124. var dropEvent = this.createEvent(dd, e, data, col, c, pos !== false
  125. ? pos
  126. : c.items.getCount());
  127. if (this.portal.fireEvent('validatedrop', dropEvent) !== false
  128. && this.portal.fireEvent('beforedrop', dropEvent) !== false) {
  129. dd.proxy.getProxy().remove();
  130. dd.panel.el.dom.parentNode.removeChild(dd.panel.el.dom);
  131. if (pos !== false) {
  132. c.insert(pos, dd.panel);
  133. } else {
  134. c.add(dd.panel);
  135. }
  136. c.doLayout();
  137. this.portal.fireEvent('drop', dropEvent);
  138. // scroll position is lost on drop, fix it
  139. var st = this.scrollPos.top;
  140. if (st) {
  141. var d = this.portal.body.dom;
  142. setTimeout(function() {
  143. d.scrollTop = st;
  144. }, 10);
  145. }
  146. }
  147. delete this.lastPos;
  148. },
  149. // internal cache of body and column coords
  150. getGrid : function() {
  151. var box = this.portal.bwrap.getBox();
  152. box.columnX = [];
  153. this.portal.items.each(function(c) {
  154. box.columnX.push({
  155. x : c.el.getX(),
  156. w : c.el.getWidth()
  157. });
  158. });
  159. return box;
  160. }
  161. });