SplitterTracker.html 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js"><span id='Ext-resizer-SplitterTracker'>/**
  19. </span> * Private utility class for Ext.Splitter.
  20. * @private
  21. */
  22. Ext.define('Ext.resizer.SplitterTracker', {
  23. extend: 'Ext.dd.DragTracker',
  24. requires: ['Ext.util.Region'],
  25. enabled: true,
  26. overlayCls: Ext.baseCSSPrefix + 'resizable-overlay',
  27. createDragOverlay: function () {
  28. var overlay;
  29. overlay = this.overlay = Ext.getBody().createChild({
  30. cls: this.overlayCls,
  31. html: '&amp;#160;'
  32. });
  33. overlay.unselectable();
  34. overlay.setSize(Ext.Element.getViewWidth(true), Ext.Element.getViewHeight(true));
  35. overlay.show();
  36. },
  37. getPrevCmp: function() {
  38. var splitter = this.getSplitter();
  39. return splitter.previousSibling();
  40. },
  41. getNextCmp: function() {
  42. var splitter = this.getSplitter();
  43. return splitter.nextSibling();
  44. },
  45. // ensure the tracker is enabled, store boxes of previous and next
  46. // components and calculate the constrain region
  47. onBeforeStart: function(e) {
  48. var me = this,
  49. prevCmp = me.getPrevCmp(),
  50. nextCmp = me.getNextCmp(),
  51. collapseEl = me.getSplitter().collapseEl,
  52. target = e.getTarget(),
  53. box;
  54. if (collapseEl &amp;&amp; target === me.getSplitter().collapseEl.dom) {
  55. return false;
  56. }
  57. // SplitterTracker is disabled if any of its adjacents are collapsed.
  58. if (nextCmp.collapsed || prevCmp.collapsed) {
  59. return false;
  60. }
  61. // store boxes of previous and next
  62. me.prevBox = prevCmp.getEl().getBox();
  63. me.nextBox = nextCmp.getEl().getBox();
  64. me.constrainTo = box = me.calculateConstrainRegion();
  65. if (!box) {
  66. return false;
  67. }
  68. me.createDragOverlay();
  69. return box;
  70. },
  71. // We move the splitter el. Add the proxy class.
  72. onStart: function(e) {
  73. var splitter = this.getSplitter();
  74. splitter.addCls(splitter.baseCls + '-active');
  75. },
  76. // calculate the constrain Region in which the splitter el may be moved.
  77. calculateConstrainRegion: function() {
  78. var me = this,
  79. splitter = me.getSplitter(),
  80. splitWidth = splitter.getWidth(),
  81. defaultMin = splitter.defaultSplitMin,
  82. orient = splitter.orientation,
  83. prevBox = me.prevBox,
  84. prevCmp = me.getPrevCmp(),
  85. nextBox = me.nextBox,
  86. nextCmp = me.getNextCmp(),
  87. // prev and nextConstrainRegions are the maximumBoxes minus the
  88. // minimumBoxes. The result is always the intersection
  89. // of these two boxes.
  90. prevConstrainRegion, nextConstrainRegion;
  91. // vertical splitters, so resizing left to right
  92. if (orient === 'vertical') {
  93. // Region constructor accepts (top, right, bottom, left)
  94. // anchored/calculated from the left
  95. prevConstrainRegion = new Ext.util.Region(
  96. prevBox.y,
  97. // Right boundary is x + maxWidth if there IS a maxWidth.
  98. // Otherwise it is calculated based upon the minWidth of the next Component
  99. (prevCmp.maxWidth ? prevBox.x + prevCmp.maxWidth : nextBox.right - (nextCmp.minWidth || defaultMin)) + splitWidth,
  100. prevBox.bottom,
  101. prevBox.x + (prevCmp.minWidth || defaultMin)
  102. );
  103. // anchored/calculated from the right
  104. nextConstrainRegion = new Ext.util.Region(
  105. nextBox.y,
  106. nextBox.right - (nextCmp.minWidth || defaultMin),
  107. nextBox.bottom,
  108. // Left boundary is right - maxWidth if there IS a maxWidth.
  109. // Otherwise it is calculated based upon the minWidth of the previous Component
  110. (nextCmp.maxWidth ? nextBox.right - nextCmp.maxWidth : prevBox.x + (prevBox.minWidth || defaultMin)) - splitWidth
  111. );
  112. } else {
  113. // anchored/calculated from the top
  114. prevConstrainRegion = new Ext.util.Region(
  115. prevBox.y + (prevCmp.minHeight || defaultMin),
  116. prevBox.right,
  117. // Bottom boundary is y + maxHeight if there IS a maxHeight.
  118. // Otherwise it is calculated based upon the minWidth of the next Component
  119. (prevCmp.maxHeight ? prevBox.y + prevCmp.maxHeight : nextBox.bottom - (nextCmp.minHeight || defaultMin)) + splitWidth,
  120. prevBox.x
  121. );
  122. // anchored/calculated from the bottom
  123. nextConstrainRegion = new Ext.util.Region(
  124. // Top boundary is bottom - maxHeight if there IS a maxHeight.
  125. // Otherwise it is calculated based upon the minHeight of the previous Component
  126. (nextCmp.maxHeight ? nextBox.bottom - nextCmp.maxHeight : prevBox.y + (prevCmp.minHeight || defaultMin)) - splitWidth,
  127. nextBox.right,
  128. nextBox.bottom - (nextCmp.minHeight || defaultMin),
  129. nextBox.x
  130. );
  131. }
  132. // intersection of the two regions to provide region draggable
  133. return prevConstrainRegion.intersect(nextConstrainRegion);
  134. },
  135. // Performs the actual resizing of the previous and next components
  136. performResize: function(e, offset) {
  137. var me = this,
  138. splitter = me.getSplitter(),
  139. orient = splitter.orientation,
  140. prevCmp = me.getPrevCmp(),
  141. nextCmp = me.getNextCmp(),
  142. owner = splitter.ownerCt,
  143. flexedSiblings = owner.query('&gt;[flex]'),
  144. len = flexedSiblings.length,
  145. i = 0,
  146. dimension,
  147. size,
  148. totalFlex = 0;
  149. // Convert flexes to pixel values proportional to the total pixel width of all flexes.
  150. for (; i &lt; len; i++) {
  151. size = flexedSiblings[i].getWidth();
  152. totalFlex += size;
  153. flexedSiblings[i].flex = size;
  154. }
  155. offset = offset || me.getOffset('dragTarget');
  156. if (orient === 'vertical') {
  157. offset = offset[0];
  158. dimension = 'width';
  159. } else {
  160. dimension = 'height';
  161. offset = offset[1];
  162. }
  163. if (prevCmp) {
  164. size = me.prevBox[dimension] + offset;
  165. if (prevCmp.flex) {
  166. prevCmp.flex = size;
  167. } else {
  168. prevCmp[dimension] = size;
  169. }
  170. }
  171. if (nextCmp) {
  172. size = me.nextBox[dimension] - offset;
  173. if (nextCmp.flex) {
  174. nextCmp.flex = size;
  175. } else {
  176. nextCmp[dimension] = size;
  177. }
  178. }
  179. owner.updateLayout();
  180. },
  181. // Cleans up the overlay (if we have one) and calls the base. This cannot be done in
  182. // onEnd, because onEnd is only called if a drag is detected but the overlay is created
  183. // regardless (by onBeforeStart).
  184. endDrag: function () {
  185. var me = this;
  186. if (me.overlay) {
  187. me.overlay.remove();
  188. delete me.overlay;
  189. }
  190. me.callParent(arguments); // this calls onEnd
  191. },
  192. // perform the resize and remove the proxy class from the splitter el
  193. onEnd: function(e) {
  194. var me = this,
  195. splitter = me.getSplitter();
  196. splitter.removeCls(splitter.baseCls + '-active');
  197. me.performResize(e, me.getOffset('dragTarget'));
  198. },
  199. // Track the proxy and set the proper XY coordinates
  200. // while constraining the drag
  201. onDrag: function(e) {
  202. var me = this,
  203. offset = me.getOffset('dragTarget'),
  204. splitter = me.getSplitter(),
  205. splitEl = splitter.getEl(),
  206. orient = splitter.orientation;
  207. if (orient === &quot;vertical&quot;) {
  208. splitEl.setX(me.startRegion.left + offset[0]);
  209. } else {
  210. splitEl.setY(me.startRegion.top + offset[1]);
  211. }
  212. },
  213. getSplitter: function() {
  214. return this.splitter;
  215. }
  216. });</pre>
  217. </body>
  218. </html>