Border.html 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864
  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-layout-container-Border'>/**
  19. </span> * This is a multi-pane, application-oriented UI layout style that supports multiple nested panels, automatic bars
  20. * between regions and built-in {@link Ext.panel.Panel#collapsible expanding and collapsing} of regions.
  21. *
  22. * This class is intended to be extended or created via the `layout:'border'` {@link Ext.container.Container#layout}
  23. * config, and should generally not need to be created directly via the new keyword.
  24. *
  25. * @example
  26. * Ext.create('Ext.panel.Panel', {
  27. * width: 500,
  28. * height: 300,
  29. * title: 'Border Layout',
  30. * layout: 'border',
  31. * items: [{
  32. * title: 'South Region is resizable',
  33. * region: 'south', // position for region
  34. * xtype: 'panel',
  35. * height: 100,
  36. * split: true, // enable resizing
  37. * margins: '0 5 5 5'
  38. * },{
  39. * // xtype: 'panel' implied by default
  40. * title: 'West Region is collapsible',
  41. * region:'west',
  42. * xtype: 'panel',
  43. * margins: '5 0 0 5',
  44. * width: 200,
  45. * collapsible: true, // make collapsible
  46. * id: 'west-region-container',
  47. * layout: 'fit'
  48. * },{
  49. * title: 'Center Region',
  50. * region: 'center', // center region is required, no width/height specified
  51. * xtype: 'panel',
  52. * layout: 'fit',
  53. * margins: '5 5 0 0'
  54. * }],
  55. * renderTo: Ext.getBody()
  56. * });
  57. *
  58. * # Notes
  59. *
  60. * - When using the split option, the layout will automatically insert a {@link Ext.resizer.Splitter}
  61. * into the appropriate place. This will modify the underlying
  62. * {@link Ext.container.Container#property-items items} collection in the container.
  63. *
  64. * - Any Container using the Border layout **must** have a child item with `region:'center'`.
  65. * The child item in the center region will always be resized to fill the remaining space
  66. * not used by the other regions in the layout.
  67. *
  68. * - Any child items with a region of `west` or `east` may be configured with either an initial
  69. * `width`, or a {@link Ext.layout.container.Box#flex} value, or an initial percentage width
  70. * **string** (Which is simply divided by 100 and used as a flex value).
  71. * The 'center' region has a flex value of `1`.
  72. *
  73. * - Any child items with a region of `north` or `south` may be configured with either an initial
  74. * `height`, or a {@link Ext.layout.container.Box#flex} value, or an initial percentage height
  75. * **string** (Which is simply divided by 100 and used as a flex value).
  76. * The 'center' region has a flex value of `1`.
  77. *
  78. * - **There is no BorderLayout.Region class in ExtJS 4.0+**
  79. */
  80. Ext.define('Ext.layout.container.Border', {
  81. alias: 'layout.border',
  82. extend: 'Ext.layout.container.Container',
  83. requires: ['Ext.resizer.BorderSplitter', 'Ext.Component', 'Ext.fx.Anim'],
  84. alternateClassName: 'Ext.layout.BorderLayout',
  85. targetCls: Ext.baseCSSPrefix + 'border-layout-ct',
  86. itemCls: [Ext.baseCSSPrefix + 'border-item', Ext.baseCSSPrefix + 'box-item'],
  87. type: 'border',
  88. <span id='Ext-layout-container-Border-cfg-split'> /**
  89. </span> * @cfg {Boolean} split
  90. * This configuration option is to be applied to the **child `items`** managed by this layout.
  91. * Each region with `split:true` will get a {@link Ext.resizer.BorderSplitter Splitter} that
  92. * allows for manual resizing of the container. Except for the `center` region.
  93. */
  94. <span id='Ext-layout-container-Border-cfg-splitterResize'> /**
  95. </span> * @cfg {Boolean} [splitterResize=true]
  96. * This configuration option is to be applied to the **child `items`** managed by this layout and
  97. * is used in conjunction with {@link #split}. By default, when specifying {@link #split}, the region
  98. * can be dragged to be resized. Set this option to false to show the split bar but prevent resizing.
  99. */
  100. <span id='Ext-layout-container-Border-cfg-padding'> /**
  101. </span> * @cfg {Number/String/Object} padding
  102. * Sets the padding to be applied to all child items managed by this layout.
  103. *
  104. * This property can be specified as a string containing space-separated, numeric
  105. * padding values. The order of the sides associated with each value matches the way
  106. * CSS processes padding values:
  107. *
  108. * - If there is only one value, it applies to all sides.
  109. * - If there are two values, the top and bottom borders are set to the first value
  110. * and the right and left are set to the second.
  111. * - If there are three values, the top is set to the first value, the left and right
  112. * are set to the second, and the bottom is set to the third.
  113. * - If there are four values, they apply to the top, right, bottom, and left,
  114. * respectively.
  115. *
  116. */
  117. padding: undefined,
  118. percentageRe: /(\d+)%/,
  119. <span id='Ext-layout-container-Border-property-axisProps'> /**
  120. </span> * Reused meta-data objects that describe axis properties.
  121. * @private
  122. */
  123. axisProps: {
  124. horz: {
  125. borderBegin: 'west',
  126. borderEnd: 'east',
  127. horizontal: true,
  128. posProp: 'x',
  129. sizeProp: 'width',
  130. sizePropCap: 'Width'
  131. },
  132. vert: {
  133. borderBegin: 'north',
  134. borderEnd: 'south',
  135. horizontal: false,
  136. posProp: 'y',
  137. sizeProp: 'height',
  138. sizePropCap: 'Height'
  139. }
  140. },
  141. // @private
  142. centerRegion: null,
  143. <span id='Ext-layout-container-Border-property-collapseDirections'> /**
  144. </span> * Maps from region name to collapseDirection for panel.
  145. * @private
  146. */
  147. collapseDirections: {
  148. north: 'top',
  149. south: 'bottom',
  150. east: 'right',
  151. west: 'left'
  152. },
  153. manageMargins: true,
  154. panelCollapseAnimate: true,
  155. panelCollapseMode: 'placeholder',
  156. <span id='Ext-layout-container-Border-cfg-regionWeights'> /**
  157. </span> * @cfg {Object} regionWeights
  158. * The default weights to assign to regions in the border layout. These values are
  159. * used when a region does not contain a `weight` property. This object must have
  160. * properties for all regions (&quot;north&quot;, &quot;south&quot;, &quot;east&quot; and &quot;west&quot;).
  161. *
  162. * **IMPORTANT:** Since this is an object, changing its properties will impact ALL
  163. * instances of Border layout. If this is not desired, provide a replacement object as
  164. * a config option instead:
  165. *
  166. * layout: {
  167. * type: 'border',
  168. * regionWeights: {
  169. * west: 20,
  170. * north: 10,
  171. * south: -10,
  172. * east: -20
  173. * }
  174. * }
  175. *
  176. * The region with the highest weight is assigned space from the border before other
  177. * regions. Regions of equal weight are assigned space based on their position in the
  178. * owner's items list (first come, first served).
  179. */
  180. regionWeights: {
  181. north: 20,
  182. south: 10,
  183. center: 0,
  184. west: -10,
  185. east: -20
  186. },
  187. //----------------------------------
  188. // Layout processing
  189. <span id='Ext-layout-container-Border-method-beginAxis'> /**
  190. </span> * Creates the axis objects for the layout. These are only missing size information
  191. * which is added during {@link #calculate}.
  192. * @private
  193. */
  194. beginAxis: function (ownerContext, regions, name) {
  195. var me = this,
  196. props = me.axisProps[name],
  197. isVert = !props.horizontal,
  198. sizeProp = props.sizeProp,
  199. totalFlex = 0,
  200. childItems = ownerContext.childItems,
  201. length = childItems.length,
  202. center, i, childContext, centerFlex, comp, region, match, size, type, target, placeholder;
  203. for (i = 0; i &lt; length; ++i) {
  204. childContext = childItems[i];
  205. comp = childContext.target;
  206. childContext.layoutPos = {};
  207. if (comp.region) {
  208. childContext.region = region = comp.region;
  209. childContext.isCenter = comp.isCenter;
  210. childContext.isHorz = comp.isHorz;
  211. childContext.isVert = comp.isVert;
  212. childContext.weight = comp.weight || me.regionWeights[region] || 0;
  213. regions[comp.id] = childContext;
  214. if (comp.isCenter) {
  215. center = childContext;
  216. centerFlex = comp.flex;
  217. ownerContext.centerRegion = center;
  218. continue;
  219. }
  220. if (isVert !== childContext.isVert) {
  221. continue;
  222. }
  223. // process regions &quot;isVert ? north||south : east||center||west&quot;
  224. childContext.reverseWeighting = (region == props.borderEnd);
  225. size = comp[sizeProp];
  226. type = typeof size;
  227. if (!comp.collapsed) {
  228. if (type == 'string' &amp;&amp; (match = me.percentageRe.exec(size))) {
  229. childContext.percentage = parseInt(match[1], 10);
  230. } else if (comp.flex) {
  231. totalFlex += childContext.flex = comp.flex;
  232. }
  233. }
  234. }
  235. }
  236. // Special cases for a collapsed center region
  237. if (center) {
  238. target = center.target;
  239. if (placeholder = target.placeholderFor) {
  240. if (!centerFlex &amp;&amp; isVert === placeholder.collapsedVertical()) {
  241. // The center region is a placeholder, collapsed in this axis
  242. centerFlex = 0;
  243. center.collapseAxis = name;
  244. }
  245. } else if (target.collapsed &amp;&amp; (isVert === target.collapsedVertical())) {
  246. // The center region is a collapsed header, collapsed in this axis
  247. centerFlex = 0;
  248. center.collapseAxis = name;
  249. }
  250. }
  251. if (centerFlex == null) {
  252. // If we still don't have a center flex, default to 1
  253. centerFlex = 1;
  254. }
  255. totalFlex += centerFlex;
  256. return Ext.apply({
  257. before : isVert ? 'top' : 'left',
  258. totalFlex : totalFlex
  259. }, props);
  260. },
  261. beginLayout: function (ownerContext) {
  262. var me = this,
  263. items = me.getLayoutItems(),
  264. pad = me.padding,
  265. type = typeof pad,
  266. padOnContainer = false,
  267. childContext, item, length, i, regions, collapseTarget,
  268. doShow, hidden, region;
  269. // We sync the visibility state of splitters with their region:
  270. if (pad) {
  271. if (type == 'string' || type == 'number') {
  272. pad = Ext.util.Format.parseBox(pad);
  273. }
  274. } else {
  275. pad = ownerContext.getEl('getTargetEl').getPaddingInfo();
  276. padOnContainer = true;
  277. }
  278. ownerContext.outerPad = pad;
  279. ownerContext.padOnContainer = padOnContainer;
  280. for (i = 0, length = items.length; i &lt; length; ++i) {
  281. item = items[i];
  282. collapseTarget = me.getSplitterTarget(item);
  283. if (collapseTarget) {
  284. hidden = !!item.hidden;
  285. if (!collapseTarget.split) {
  286. if (collapseTarget.isCollapsingOrExpanding) {
  287. doShow = !!collapseTarget.collapsed;
  288. }
  289. } else if (hidden !== collapseTarget.hidden) {
  290. doShow = !collapseTarget.hidden;
  291. }
  292. if (doShow === true) {
  293. item.show();
  294. } else if (doShow === false) {
  295. item.hide();
  296. }
  297. }
  298. }
  299. // The above synchronized visibility of splitters with their regions, so we need
  300. // to make this call after that so that childItems and visibleItems are correct:
  301. //
  302. me.callParent(arguments);
  303. items = ownerContext.childItems;
  304. length = items.length;
  305. regions = {};
  306. ownerContext.borderAxisHorz = me.beginAxis(ownerContext, regions, 'horz');
  307. ownerContext.borderAxisVert = me.beginAxis(ownerContext, regions, 'vert');
  308. // Now that weights are assigned to the region's contextItems, we assign those
  309. // same weights to the contextItem for the splitters. We also cross link the
  310. // contextItems for the collapseTarget and its splitter.
  311. for (i = 0; i &lt; length; ++i) {
  312. childContext = items[i];
  313. collapseTarget = me.getSplitterTarget(childContext.target);
  314. if (collapseTarget) { // if (splitter)
  315. region = regions[collapseTarget.id]
  316. if (!region) {
  317. // if the region was hidden it will not be part of childItems, and
  318. // so beginAxis() won't add it to the regions object, so we have
  319. // to create the context item here.
  320. region = ownerContext.getEl(collapseTarget.el, me);
  321. region.region = collapseTarget.region;
  322. }
  323. childContext.collapseTarget = collapseTarget = region;
  324. childContext.weight = collapseTarget.weight;
  325. childContext.reverseWeighting = collapseTarget.reverseWeighting;
  326. collapseTarget.splitter = childContext;
  327. childContext.isHorz = collapseTarget.isHorz;
  328. childContext.isVert = collapseTarget.isVert;
  329. }
  330. }
  331. // Now we want to sort the childItems by their weight.
  332. me.sortWeightedItems(items, 'reverseWeighting');
  333. me.setupSplitterNeighbors(items);
  334. },
  335. calculate: function (ownerContext) {
  336. var me = this,
  337. containerSize = me.getContainerSize(ownerContext),
  338. childItems = ownerContext.childItems,
  339. length = childItems.length,
  340. horz = ownerContext.borderAxisHorz,
  341. vert = ownerContext.borderAxisVert,
  342. pad = ownerContext.outerPad,
  343. padOnContainer = ownerContext.padOnContainer,
  344. i, childContext, childMargins, size, horzPercentTotal, vertPercentTotal;
  345. horz.begin = pad.left;
  346. vert.begin = pad.top;
  347. // If the padding is already on the container we need to add it to the space
  348. // If not on the container, it's &quot;virtual&quot; padding.
  349. horzPercentTotal = horz.end = horz.flexSpace = containerSize.width + (padOnContainer ? pad.left : -pad.right);
  350. vertPercentTotal = vert.end = vert.flexSpace = containerSize.height + (padOnContainer ? pad.top : -pad.bottom);
  351. // Reduce flexSpace on each axis by the fixed/auto sized dimensions of items that
  352. // aren't flexed along that axis.
  353. for (i = 0; i &lt; length; ++i) {
  354. childContext = childItems[i];
  355. childMargins = childContext.getMarginInfo();
  356. // Margins are always fixed size and must be removed from the space used for percentages and flexes
  357. if (childContext.isHorz || childContext.isCenter) {
  358. horz.addUnflexed(childMargins.width);
  359. horzPercentTotal -= childMargins.width;
  360. }
  361. if (childContext.isVert || childContext.isCenter) {
  362. vert.addUnflexed(childMargins.height);
  363. vertPercentTotal -= childMargins.height;
  364. }
  365. // Fixed size components must have their sizes removed from the space used for flex
  366. if (!childContext.flex &amp;&amp; !childContext.percentage) {
  367. if (childContext.isHorz || (childContext.isCenter &amp;&amp; childContext.collapseAxis === 'horz')) {
  368. size = childContext.getProp('width');
  369. horz.addUnflexed(size);
  370. // splitters should not count towards percentages
  371. if (childContext.collapseTarget) {
  372. horzPercentTotal -= size;
  373. }
  374. } else if (childContext.isVert || (childContext.isCenter &amp;&amp; childContext.collapseAxis === 'vert')) {
  375. size = childContext.getProp('height');
  376. vert.addUnflexed(size);
  377. // splitters should not count towards percentages
  378. if (childContext.collapseTarget) {
  379. vertPercentTotal -= size;
  380. }
  381. }
  382. // else ignore center since it is fully flexed
  383. }
  384. }
  385. for (i = 0; i &lt; length; ++i) {
  386. childContext = childItems[i];
  387. childMargins = childContext.getMarginInfo();
  388. // Calculate the percentage sizes. After this calculation percentages are very similar to fixed sizes
  389. if (childContext.percentage) {
  390. if (childContext.isHorz) {
  391. size = Math.ceil(horzPercentTotal * childContext.percentage / 100);
  392. size = childContext.setWidth(size);
  393. horz.addUnflexed(size);
  394. } else if (childContext.isVert) {
  395. size = Math.ceil(vertPercentTotal * childContext.percentage / 100);
  396. size = childContext.setHeight(size);
  397. vert.addUnflexed(size);
  398. }
  399. // center shouldn't have a percentage but if it does it should be ignored
  400. }
  401. }
  402. // If we haven't gotten sizes for all unflexed dimensions on an axis, the flexSpace
  403. // will be NaN so we won't be calculating flexed dimensions until that is resolved.
  404. for (i = 0; i &lt; length; ++i) {
  405. childContext = childItems[i];
  406. if (!childContext.isCenter) {
  407. me.calculateChildAxis(childContext, horz);
  408. me.calculateChildAxis(childContext, vert);
  409. }
  410. }
  411. // Once all items are placed, the final size of the center can be determined. If we
  412. // can determine both width and height, we are done. We use '+' instead of '&amp;&amp;' to
  413. // avoid short-circuiting (we want to call both):
  414. if (me.finishAxis(ownerContext, vert) + me.finishAxis(ownerContext, horz) &lt; 2) {
  415. me.done = false;
  416. } else {
  417. // Size information is published as we place regions but position is hard to do
  418. // that way (while avoiding published multiple times) so we publish all the
  419. // positions at the end.
  420. me.finishPositions(childItems);
  421. }
  422. },
  423. <span id='Ext-layout-container-Border-method-calculateChildAxis'> /**
  424. </span> * Performs the calculations for a region on a specified axis.
  425. * @private
  426. */
  427. calculateChildAxis: function (childContext, axis) {
  428. var collapseTarget = childContext.collapseTarget,
  429. setSizeMethod = 'set' + axis.sizePropCap,
  430. sizeProp = axis.sizeProp,
  431. childMarginSize = childContext.getMarginInfo()[sizeProp],
  432. region, isBegin, flex, pos, size;
  433. if (collapseTarget) { // if (splitter)
  434. region = collapseTarget.region;
  435. } else {
  436. region = childContext.region;
  437. flex = childContext.flex;
  438. }
  439. isBegin = region == axis.borderBegin;
  440. if (!isBegin &amp;&amp; region != axis.borderEnd) {
  441. // a north/south region on the horizontal axis or an east/west region on the
  442. // vertical axis: stretch to fill remaining space:
  443. childContext[setSizeMethod](axis.end - axis.begin - childMarginSize);
  444. pos = axis.begin;
  445. } else {
  446. if (flex) {
  447. size = Math.ceil(axis.flexSpace * (flex / axis.totalFlex));
  448. size = childContext[setSizeMethod](size);
  449. } else if (childContext.percentage) {
  450. // Like getProp but without registering a dependency - we calculated the size, we don't depend on it
  451. size = childContext.peek(sizeProp);
  452. } else {
  453. size = childContext.getProp(sizeProp);
  454. }
  455. size += childMarginSize;
  456. if (isBegin) {
  457. pos = axis.begin;
  458. axis.begin += size;
  459. } else {
  460. axis.end = pos = axis.end - size;
  461. }
  462. }
  463. childContext.layoutPos[axis.posProp] = pos;
  464. },
  465. <span id='Ext-layout-container-Border-method-finishAxis'> /**
  466. </span> * Finishes the calculations on an axis. This basically just assigns the remaining
  467. * space to the center region.
  468. * @private
  469. */
  470. finishAxis: function (ownerContext, axis) {
  471. var size = axis.end - axis.begin,
  472. center = ownerContext.centerRegion;
  473. if (center) {
  474. center['set' + axis.sizePropCap](size - center.getMarginInfo()[axis.sizeProp]);
  475. center.layoutPos[axis.posProp] = axis.begin;
  476. }
  477. return Ext.isNumber(size) ? 1 : 0;
  478. },
  479. <span id='Ext-layout-container-Border-method-finishPositions'> /**
  480. </span> * Finishes by setting the positions on the child items.
  481. * @private
  482. */
  483. finishPositions: function (childItems) {
  484. var length = childItems.length,
  485. index, childContext;
  486. for (index = 0; index &lt; length; ++index) {
  487. childContext = childItems[index];
  488. childContext.setProp('x', childContext.layoutPos.x + childContext.marginInfo.left);
  489. childContext.setProp('y', childContext.layoutPos.y + childContext.marginInfo.top);
  490. }
  491. },
  492. getPlaceholder: function (comp) {
  493. return comp.getPlaceholder &amp;&amp; comp.getPlaceholder();
  494. },
  495. getSplitterTarget: function (splitter) {
  496. var collapseTarget = splitter.collapseTarget;
  497. if (collapseTarget &amp;&amp; collapseTarget.collapsed) {
  498. return collapseTarget.placeholder || collapseTarget;
  499. }
  500. return collapseTarget;
  501. },
  502. isItemBoxParent: function (itemContext) {
  503. return true;
  504. },
  505. isItemShrinkWrap: function (item) {
  506. return true;
  507. },
  508. //----------------------------------
  509. // Event handlers
  510. <span id='Ext-layout-container-Border-method-insertSplitter'> /**
  511. </span> * Inserts the splitter for a given region. A reference to the splitter is also stored
  512. * on the component as &quot;splitter&quot;.
  513. * @private
  514. */
  515. insertSplitter: function (item, index, hidden) {
  516. var region = item.region,
  517. splitter = {
  518. xtype: 'bordersplitter',
  519. collapseTarget: item,
  520. id: item.id + '-splitter',
  521. hidden: hidden,
  522. canResize: item.splitterResize !== false
  523. },
  524. at = index + ((region == 'south' || region == 'east') ? 0 : 1);
  525. // remove the default fixed width or height depending on orientation:
  526. if (item.isHorz) {
  527. splitter.height = null;
  528. } else {
  529. splitter.width = null;
  530. }
  531. if (item.collapseMode == 'mini') {
  532. splitter.collapsedCls = item.collapsedCls;
  533. }
  534. item.splitter = this.owner.add(at, splitter);
  535. },
  536. <span id='Ext-layout-container-Border-method-onAdd'> /**
  537. </span> * Called when a region (actually when any component) is added to the container. The
  538. * region is decorated with some helpful properties (isCenter, isHorz, isVert) and its
  539. * splitter is added if its &quot;split&quot; property is true.
  540. * @private
  541. */
  542. onAdd: function (item, index) {
  543. var me = this,
  544. placeholderFor = item.placeholderFor,
  545. region = item.region,
  546. split,
  547. hidden;
  548. me.callParent(arguments);
  549. if (region) {
  550. Ext.apply(item, me.regionFlags[region]);
  551. if (region == 'center') {
  552. //&lt;debug&gt;
  553. if (me.centerRegion) {
  554. Ext.Error.raise(&quot;Cannot have multiple center regions in a BorderLayout.&quot;);
  555. }
  556. //&lt;/debug&gt;
  557. me.centerRegion = item;
  558. } else {
  559. item.collapseDirection = this.collapseDirections[region];
  560. split = item.split;
  561. hidden = !!item.hidden;
  562. if ((item.isHorz || item.isVert) &amp;&amp; (split || item.collapseMode == 'mini')) {
  563. me.insertSplitter(item, index, hidden || !split);
  564. }
  565. }
  566. if (!item.hasOwnProperty('collapseMode')) {
  567. item.collapseMode = me.panelCollapseMode;
  568. }
  569. if (!item.hasOwnProperty('animCollapse')) {
  570. if (item.collapseMode != 'placeholder') {
  571. // other collapse modes do not animate nicely in a border layout, so
  572. // default them to off:
  573. item.animCollapse = false;
  574. } else {
  575. item.animCollapse = me.panelCollapseAnimate;
  576. }
  577. }
  578. } else if (placeholderFor) {
  579. Ext.apply(item, me.regionFlags[placeholderFor.region]);
  580. item.region = placeholderFor.region;
  581. item.weight = placeholderFor.weight;
  582. }
  583. },
  584. onDestroy: function() {
  585. this.centerRegion = null;
  586. this.callParent();
  587. },
  588. onRemove: function (item) {
  589. var me = this,
  590. region = item.region,
  591. splitter = item.splitter;
  592. if (region) {
  593. if (item.isCenter) {
  594. me.centerRegion = null;
  595. }
  596. delete item.isCenter;
  597. delete item.isHorz;
  598. delete item.isVert;
  599. if (splitter) {
  600. me.owner.doRemove(splitter, true); // avoid another layout
  601. delete item.splitter;
  602. }
  603. }
  604. me.callParent(arguments);
  605. },
  606. //----------------------------------
  607. // Misc
  608. regionFlags: {
  609. center: { isCenter: true, isHorz: false, isVert: false },
  610. north: { isCenter: false, isHorz: false, isVert: true },
  611. south: { isCenter: false, isHorz: false, isVert: true },
  612. west: { isCenter: false, isHorz: true, isVert: false },
  613. east: { isCenter: false, isHorz: true, isVert: false }
  614. },
  615. setupSplitterNeighbors: function (items) {
  616. var edgeRegions = {
  617. //north: null,
  618. //south: null,
  619. //east: null,
  620. //west: null
  621. },
  622. length = items.length,
  623. touchedRegions = this.touchedRegions,
  624. i, j, center, count, edge, comp, region, splitter, touched;
  625. for (i = 0; i &lt; length; ++i) {
  626. comp = items[i].target;
  627. region = comp.region;
  628. if (comp.isCenter) {
  629. center = comp;
  630. } else if (region) {
  631. touched = touchedRegions[region];
  632. for (j = 0, count = touched.length; j &lt; count; ++j) {
  633. edge = edgeRegions[touched[j]];
  634. if (edge) {
  635. edge.neighbors.push(comp);
  636. }
  637. }
  638. if (comp.placeholderFor) {
  639. // placeholder, so grab the splitter for the actual panel
  640. splitter = comp.placeholderFor.splitter;
  641. } else {
  642. splitter = comp.splitter;
  643. }
  644. if (splitter) {
  645. splitter.neighbors = [];
  646. }
  647. edgeRegions[region] = splitter;
  648. }
  649. }
  650. if (center) {
  651. touched = touchedRegions.center;
  652. for (j = 0, count = touched.length; j &lt; count; ++j) {
  653. edge = edgeRegions[touched[j]];
  654. if (edge) {
  655. edge.neighbors.push(center);
  656. }
  657. }
  658. }
  659. },
  660. <span id='Ext-layout-container-Border-property-touchedRegions'> /**
  661. </span> * Lists the regions that would consider an interior region a neighbor. For example,
  662. * a north region would consider an east or west region its neighbords (as well as
  663. * an inner north region).
  664. * @private
  665. */
  666. touchedRegions: {
  667. center: [ 'north', 'south', 'east', 'west' ],
  668. north: [ 'north', 'east', 'west' ],
  669. south: [ 'south', 'east', 'west' ],
  670. east: [ 'east', 'north', 'south' ],
  671. west: [ 'west', 'north', 'south' ]
  672. },
  673. sizePolicies: {
  674. vert: {
  675. setsWidth: 1,
  676. setsHeight: 0
  677. },
  678. horz: {
  679. setsWidth: 0,
  680. setsHeight: 1
  681. },
  682. flexAll: {
  683. setsWidth: 1,
  684. setsHeight: 1
  685. }
  686. },
  687. getItemSizePolicy: function (item) {
  688. var me = this,
  689. policies = this.sizePolicies,
  690. collapseTarget, size, policy, placeholderFor;
  691. if (item.isCenter) {
  692. placeholderFor = item.placeholderFor;
  693. if (placeholderFor) {
  694. if (placeholderFor.collapsedVertical()) {
  695. return policies.vert;
  696. }
  697. return policies.horz;
  698. }
  699. if (item.collapsed) {
  700. if (item.collapsedVertical()) {
  701. return policies.vert;
  702. }
  703. return policies.horz;
  704. }
  705. return policies.flexAll;
  706. }
  707. collapseTarget = item.collapseTarget;
  708. if (collapseTarget) {
  709. return collapseTarget.isVert ? policies.vert : policies.horz;
  710. }
  711. if (item.region) {
  712. if (item.isVert) {
  713. size = item.height;
  714. policy = policies.vert;
  715. } else {
  716. size = item.width;
  717. policy = policies.horz;
  718. }
  719. if (item.flex || (typeof size == 'string' &amp;&amp; me.percentageRe.test(size))) {
  720. return policies.flexAll;
  721. }
  722. return policy;
  723. }
  724. return me.autoSizePolicy;
  725. }
  726. }, function () {
  727. var methods = {
  728. addUnflexed: function (px) {
  729. this.flexSpace = Math.max(this.flexSpace - px, 0);
  730. }
  731. },
  732. props = this.prototype.axisProps;
  733. Ext.apply(props.horz, methods);
  734. Ext.apply(props.vert, methods);
  735. });
  736. </pre>
  737. </body>
  738. </html>