Splitter.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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-Splitter'>/**
  19. </span> * This class functions **between siblings of a {@link Ext.layout.container.VBox VBox} or {@link Ext.layout.container.HBox HBox}
  20. * layout** to resize both immediate siblings.
  21. *
  22. * A Splitter will preserve the flex ratio of any flexed siblings it is required to resize. It does this by setting the `flex` property of *all* flexed siblings
  23. * to equal their pixel size. The actual numerical `flex` property in the Components will change, but the **ratio** to the total flex value will be preserved.
  24. *
  25. * A Splitter may be configured to show a centered mini-collapse tool orientated to collapse the {@link #collapseTarget}.
  26. * The Splitter will then call that sibling Panel's {@link Ext.panel.Panel#method-collapse collapse} or {@link Ext.panel.Panel#method-expand expand} method
  27. * to perform the appropriate operation (depending on the sibling collapse state). To create the mini-collapse tool but take care
  28. * of collapsing yourself, configure the splitter with `{@link #performCollapse}: false`.
  29. */
  30. Ext.define('Ext.resizer.Splitter', {
  31. extend: 'Ext.Component',
  32. requires: ['Ext.XTemplate'],
  33. uses: ['Ext.resizer.SplitterTracker'],
  34. alias: 'widget.splitter',
  35. childEls: [
  36. 'collapseEl'
  37. ],
  38. renderTpl: [
  39. '&lt;tpl if=&quot;collapsible===true&quot;&gt;',
  40. '&lt;div id=&quot;{id}-collapseEl&quot; class=&quot;', Ext.baseCSSPrefix, 'collapse-el ',
  41. Ext.baseCSSPrefix, 'layout-split-{collapseDir}&quot;&gt;&amp;#160;&lt;/div&gt;',
  42. '&lt;/tpl&gt;'
  43. ],
  44. baseCls: Ext.baseCSSPrefix + 'splitter',
  45. collapsedClsInternal: Ext.baseCSSPrefix + 'splitter-collapsed',
  46. // Default to tree, allow internal classes to disable resizing
  47. canResize: true,
  48. <span id='Ext-resizer-Splitter-cfg-collapsible'> /**
  49. </span> * @cfg {Boolean} collapsible
  50. * True to show a mini-collapse tool in the Splitter to toggle expand and collapse on the {@link #collapseTarget} Panel.
  51. * Defaults to the {@link Ext.panel.Panel#collapsible collapsible} setting of the Panel.
  52. */
  53. collapsible: false,
  54. <span id='Ext-resizer-Splitter-cfg-performCollapse'> /**
  55. </span> * @cfg {Boolean} performCollapse
  56. * Set to false to prevent this Splitter's mini-collapse tool from managing the collapse
  57. * state of the {@link #collapseTarget}.
  58. */
  59. <span id='Ext-resizer-Splitter-cfg-collapseOnDblClick'> /**
  60. </span> * @cfg {Boolean} collapseOnDblClick
  61. * True to enable dblclick to toggle expand and collapse on the {@link #collapseTarget} Panel.
  62. */
  63. collapseOnDblClick: true,
  64. <span id='Ext-resizer-Splitter-cfg-defaultSplitMin'> /**
  65. </span> * @cfg {Number} defaultSplitMin
  66. * Provides a default minimum width or height for the two components
  67. * that the splitter is between.
  68. */
  69. defaultSplitMin: 40,
  70. <span id='Ext-resizer-Splitter-cfg-defaultSplitMax'> /**
  71. </span> * @cfg {Number} defaultSplitMax
  72. * Provides a default maximum width or height for the two components
  73. * that the splitter is between.
  74. */
  75. defaultSplitMax: 1000,
  76. <span id='Ext-resizer-Splitter-cfg-collapsedCls'> /**
  77. </span> * @cfg {String} collapsedCls
  78. * A class to add to the splitter when it is collapsed. See {@link #collapsible}.
  79. */
  80. <span id='Ext-resizer-Splitter-cfg-collapseTarget'> /**
  81. </span> * @cfg {String/Ext.panel.Panel} collapseTarget
  82. * A string describing the relative position of the immediate sibling Panel to collapse. May be 'prev' or 'next'.
  83. *
  84. * Or the immediate sibling Panel to collapse.
  85. *
  86. * The orientation of the mini-collapse tool will be inferred from this setting.
  87. *
  88. * **Note that only Panels may be collapsed.**
  89. */
  90. collapseTarget: 'next',
  91. <span id='Ext-resizer-Splitter-property-orientation'> /**
  92. </span> * @property {String} orientation
  93. * Orientation of this Splitter. `'vertical'` when used in an hbox layout, `'horizontal'`
  94. * when used in a vbox layout.
  95. */
  96. horizontal: false,
  97. vertical: false,
  98. <span id='Ext-resizer-Splitter-method-getTrackerConfig'> /**
  99. </span> * Returns the config object (with an `xclass` property) for the splitter tracker. This
  100. * is overridden by {@link Ext.resizer.BorderSplitter BorderSplitter} to create a
  101. * {@link Ext.resizer.BorderSplitterTracker BorderSplitterTracker}.
  102. * @protected
  103. */
  104. getTrackerConfig: function () {
  105. return {
  106. xclass: 'Ext.resizer.SplitterTracker',
  107. el: this.el,
  108. splitter: this
  109. };
  110. },
  111. beforeRender: function() {
  112. var me = this,
  113. target = me.getCollapseTarget(),
  114. collapseDir = me.getCollapseDirection(),
  115. vertical = me.vertical,
  116. fixedSizeProp = vertical ? 'width' : 'height',
  117. stretchSizeProp = vertical ? 'height' : 'width',
  118. cls;
  119. me.callParent();
  120. if (!me.hasOwnProperty(stretchSizeProp)) {
  121. me[stretchSizeProp] = '100%';
  122. }
  123. if (!me.hasOwnProperty(fixedSizeProp)) {
  124. me[fixedSizeProp] = 5;
  125. }
  126. if (target.collapsed) {
  127. me.addCls(me.collapsedClsInternal);
  128. }
  129. cls = me.baseCls + '-' + me.orientation;
  130. me.addCls(cls);
  131. if (!me.canResize) {
  132. me.addCls(cls + '-noresize');
  133. }
  134. Ext.applyIf(me.renderData, {
  135. collapseDir: collapseDir,
  136. collapsible: me.collapsible || target.collapsible
  137. });
  138. },
  139. onRender: function() {
  140. var me = this;
  141. me.callParent(arguments);
  142. // Add listeners on the mini-collapse tool unless performCollapse is set to false
  143. if (me.performCollapse !== false) {
  144. if (me.renderData.collapsible) {
  145. me.mon(me.collapseEl, 'click', me.toggleTargetCmp, me);
  146. }
  147. if (me.collapseOnDblClick) {
  148. me.mon(me.el, 'dblclick', me.toggleTargetCmp, me);
  149. }
  150. }
  151. // Ensure the mini collapse icon is set to the correct direction when the target is collapsed/expanded by any means
  152. me.mon(me.getCollapseTarget(), {
  153. collapse: me.onTargetCollapse,
  154. expand: me.onTargetExpand,
  155. scope: me
  156. });
  157. me.el.unselectable();
  158. if (me.canResize) {
  159. me.tracker = Ext.create(me.getTrackerConfig());
  160. // Relay the most important events to our owner (could open wider later):
  161. me.relayEvents(me.tracker, [ 'beforedragstart', 'dragstart', 'dragend' ]);
  162. }
  163. },
  164. getCollapseDirection: function() {
  165. var me = this,
  166. dir = me.collapseDirection,
  167. collapseTarget, idx, items, type;
  168. if (!dir) {
  169. collapseTarget = me.collapseTarget;
  170. if (collapseTarget.isComponent) {
  171. dir = collapseTarget.collapseDirection;
  172. }
  173. if (!dir) {
  174. // Avoid duplication of string tests.
  175. // Create a two bit truth table of the configuration of the Splitter:
  176. // Collapse Target | orientation
  177. // 0 0 = next, horizontal
  178. // 0 1 = next, vertical
  179. // 1 0 = prev, horizontal
  180. // 1 1 = prev, vertical
  181. type = me.ownerCt.layout.type;
  182. if (collapseTarget.isComponent) {
  183. items = me.ownerCt.items;
  184. idx = Number(items.indexOf(collapseTarget) == items.indexOf(me) - 1) &lt;&lt; 1 | Number(type == 'hbox');
  185. } else {
  186. idx = Number(me.collapseTarget == 'prev') &lt;&lt; 1 | Number(type == 'hbox');
  187. }
  188. // Read the data out the truth table
  189. dir = ['bottom', 'right', 'top', 'left'][idx];
  190. }
  191. me.collapseDirection = dir;
  192. }
  193. me.orientation = (dir == 'top' || dir == 'bottom') ? 'horizontal' : 'vertical';
  194. me[me.orientation] = true;
  195. return dir;
  196. },
  197. getCollapseTarget: function() {
  198. var me = this;
  199. return me.collapseTarget.isComponent ? me.collapseTarget : me.collapseTarget == 'prev' ? me.previousSibling() : me.nextSibling();
  200. },
  201. onTargetCollapse: function(target) {
  202. this.el.addCls([this.collapsedClsInternal, this.collapsedCls]);
  203. },
  204. onTargetExpand: function(target) {
  205. this.el.removeCls([this.collapsedClsInternal, this.collapsedCls]);
  206. },
  207. toggleTargetCmp: function(e, t) {
  208. var cmp = this.getCollapseTarget(),
  209. placeholder = cmp.placeholder,
  210. toggle;
  211. if (placeholder &amp;&amp; !placeholder.hidden) {
  212. toggle = true;
  213. } else {
  214. toggle = !cmp.hidden;
  215. }
  216. if (toggle) {
  217. if (cmp.collapsed) {
  218. cmp.expand();
  219. } else if (cmp.collapseDirection) {
  220. cmp.collapse();
  221. } else {
  222. cmp.collapse(this.renderData.collapseDir);
  223. }
  224. }
  225. },
  226. /*
  227. * Work around IE bug. %age margins do not get recalculated on element resize unless repaint called.
  228. */
  229. setSize: function() {
  230. var me = this;
  231. me.callParent(arguments);
  232. if (Ext.isIE &amp;&amp; me.el) {
  233. me.el.repaint();
  234. }
  235. },
  236. beforeDestroy: function(){
  237. Ext.destroy(this.tracker);
  238. this.callParent();
  239. }
  240. });
  241. </pre>
  242. </body>
  243. </html>