Header.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  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-panel-Header'>/**
  19. </span> * Simple header class which is used for on {@link Ext.panel.Panel} and {@link Ext.window.Window}.
  20. */
  21. Ext.define('Ext.panel.Header', {
  22. extend: 'Ext.container.Container',
  23. uses: ['Ext.panel.Tool', 'Ext.draw.Component', 'Ext.util.CSS', 'Ext.layout.component.Body', 'Ext.Img'],
  24. alias: 'widget.header',
  25. <span id='Ext-panel-Header-property-isHeader'> /**
  26. </span> * @property {Boolean} isHeader
  27. * `true` in this class to identify an objact as an instantiated Header, or subclass thereof.
  28. */
  29. isHeader : true,
  30. defaultType : 'tool',
  31. indicateDrag : false,
  32. weight : -1,
  33. componentLayout: 'body',
  34. <span id='Ext-panel-Header-cfg-titleAlign'> /**
  35. </span> * @cfg {String} [titleAlign='left']
  36. * May be `&quot;left&quot;`, `&quot;right&quot;` or `&quot;center&quot;`.
  37. *
  38. * The alignment of the title text within the available space between the icon and the tools.
  39. */
  40. titleAlign: 'left',
  41. childEls: [
  42. 'body'
  43. ],
  44. renderTpl: [
  45. '&lt;div id=&quot;{id}-body&quot; class=&quot;{baseCls}-body {bodyCls}',
  46. '&lt;tpl for=&quot;uiCls&quot;&gt; {parent.baseCls}-body-{parent.ui}-{.}&lt;/tpl&gt;&quot;',
  47. '&lt;tpl if=&quot;bodyStyle&quot;&gt; style=&quot;{bodyStyle}&quot;&lt;/tpl&gt;&gt;',
  48. '{%this.renderContainer(out,values)%}',
  49. '&lt;/div&gt;'
  50. ],
  51. headingTpl: '&lt;span id=&quot;{id}-textEl&quot; class=&quot;{cls}-text {cls}-text-{ui}&quot;&gt;{title}&lt;/span&gt;',
  52. shrinkWrap: 3,
  53. <span id='Ext-panel-Header-cfg-title'> /**
  54. </span> * @cfg {String} title
  55. * The title text to display.
  56. */
  57. <span id='Ext-panel-Header-cfg-iconCls'> /**
  58. </span> * @cfg {String} iconCls
  59. * CSS class for an icon in the header. Used for displaying an icon to the left of a title.
  60. */
  61. <span id='Ext-panel-Header-cfg-icon'> /**
  62. </span> * @cfg {String} icon
  63. * Path to image for an icon in the header. Used for displaying an icon to the left of a title.
  64. */
  65. initComponent: function() {
  66. var me = this,
  67. ruleStyle,
  68. rule,
  69. style,
  70. ui,
  71. tempEl;
  72. me.addEvents(
  73. <span id='Ext-panel-Header-event-click'> /**
  74. </span> * @event click
  75. * Fires when the header is clicked. This event will not be fired
  76. * if the click was on a {@link Ext.panel.Tool}
  77. * @param {Ext.panel.Header} this
  78. * @param {Ext.EventObject} e
  79. */
  80. 'click',
  81. <span id='Ext-panel-Header-event-dblclick'> /**
  82. </span> * @event dblclick
  83. * Fires when the header is double clicked. This event will not
  84. * be fired if the click was on a {@link Ext.panel.Tool}
  85. * @param {Ext.panel.Header} this
  86. * @param {Ext.EventObject} e
  87. */
  88. 'dblclick'
  89. );
  90. me.indicateDragCls = me.baseCls + '-draggable';
  91. me.title = me.title || '&amp;#160;';
  92. me.tools = me.tools || [];
  93. me.items = me.items || [];
  94. me.orientation = me.orientation || 'horizontal';
  95. me.dock = (me.dock) ? me.dock : (me.orientation == 'horizontal') ? 'top' : 'left';
  96. //add the dock as a ui
  97. //this is so we support top/right/left/bottom headers
  98. me.addClsWithUI([me.orientation, me.dock]);
  99. if (me.indicateDrag) {
  100. me.addCls(me.indicateDragCls);
  101. }
  102. // Add Icon
  103. if (!Ext.isEmpty(me.iconCls) || !Ext.isEmpty(me.icon)) {
  104. me.initIconCmp();
  105. me.items.push(me.iconCmp);
  106. }
  107. // Add Title
  108. if (me.orientation == 'vertical') {
  109. me.layout = {
  110. type : 'vbox',
  111. align: 'center'
  112. };
  113. me.textConfig = {
  114. width: 16,
  115. cls: me.baseCls + '-text',
  116. type: 'text',
  117. text: me.title,
  118. rotate: {
  119. degrees: 90
  120. }
  121. };
  122. ui = me.ui;
  123. if (Ext.isArray(ui)) {
  124. ui = ui[0];
  125. }
  126. ruleStyle = '.' + me.baseCls + '-text-' + ui;
  127. if (Ext.scopeResetCSS) {
  128. ruleStyle = '.' + Ext.baseCSSPrefix + 'reset ' + ruleStyle;
  129. }
  130. rule = Ext.util.CSS.getRule(ruleStyle);
  131. // We might have been disallowed access to the stylesheet: https://sencha.jira.com/browse/EXTJSIV-5084
  132. if (rule) {
  133. style = rule.style;
  134. } else {
  135. style = (tempEl = Ext.resetElement.createChild({style: 'position:absolute', cls: me.baseCls + '-text-' + ui})).getStyles('fontFamily', 'fontWeight', 'fontSize', 'color');
  136. tempEl.remove();
  137. }
  138. if (style) {
  139. Ext.apply(me.textConfig, {
  140. 'font-family': style.fontFamily,
  141. 'font-weight': style.fontWeight,
  142. 'font-size': style.fontSize,
  143. fill: style.color
  144. });
  145. }
  146. me.titleCmp = new Ext.draw.Component({
  147. width : 16,
  148. ariaRole : 'heading',
  149. focusable : false,
  150. viewBox : false,
  151. flex : 1,
  152. id : me.id + '_hd',
  153. autoSize : true,
  154. items : me.textConfig,
  155. xhooks: {
  156. setSize: function (width) {
  157. // don't pass 2nd arg (height) on to setSize or we break 'flex:1'
  158. this.callParent([width]);
  159. }
  160. },
  161. // this is a bit of a cheat: we are not selecting an element of titleCmp
  162. // but rather of titleCmp.items[0]
  163. childEls : [
  164. { name: 'textEl', select: '.' + me.baseCls + '-text' }
  165. ]
  166. });
  167. } else {
  168. me.layout = {
  169. type : 'hbox',
  170. align: 'middle'
  171. };
  172. me.titleCmp = new Ext.Component({
  173. ariaRole : 'heading',
  174. focusable : false,
  175. noWrap : true,
  176. flex : 1,
  177. id : me.id + '_hd',
  178. style : 'text-align:' + me.titleAlign,
  179. cls : me.baseCls + '-text-container',
  180. renderTpl : me.getTpl('headingTpl'),
  181. renderData: {
  182. title: me.title,
  183. cls : me.baseCls,
  184. ui : me.ui
  185. },
  186. childEls : ['textEl']
  187. });
  188. }
  189. me.items.push(me.titleCmp);
  190. // Add Tools
  191. me.items = me.items.concat(me.tools);
  192. me.callParent();
  193. me.on({
  194. dblclick: me.onDblClick,
  195. click: me.onClick,
  196. element: 'el',
  197. scope: me
  198. });
  199. },
  200. initIconCmp: function() {
  201. var me = this,
  202. cfg = {
  203. focusable: false,
  204. src: Ext.BLANK_IMAGE_URL,
  205. cls: [me.baseCls + '-icon', me.iconCls],
  206. id: me.id + '-iconEl',
  207. iconCls: me.iconCls
  208. };
  209. if (!Ext.isEmpty(me.icon)) {
  210. delete cfg.iconCls;
  211. cfg.src = me.icon;
  212. }
  213. me.iconCmp = new Ext.Img(cfg);
  214. },
  215. afterRender: function() {
  216. this.el.unselectable();
  217. this.callParent();
  218. },
  219. // inherit docs
  220. addUIClsToElement: function(cls) {
  221. var me = this,
  222. result = me.callParent(arguments),
  223. classes = [me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls],
  224. array, i;
  225. if (me.bodyCls) {
  226. array = me.bodyCls.split(' ');
  227. for (i = 0; i &lt; classes.length; i++) {
  228. if (!Ext.Array.contains(array, classes[i])) {
  229. array.push(classes[i]);
  230. }
  231. }
  232. me.bodyCls = array.join(' ');
  233. } else {
  234. me.bodyCls = classes.join(' ');
  235. }
  236. return result;
  237. },
  238. // inherit docs
  239. removeUIClsFromElement: function(cls) {
  240. var me = this,
  241. result = me.callParent(arguments),
  242. classes = [me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls],
  243. array, i;
  244. if (me.bodyCls) {
  245. array = me.bodyCls.split(' ');
  246. for (i = 0; i &lt; classes.length; i++) {
  247. Ext.Array.remove(array, classes[i]);
  248. }
  249. me.bodyCls = array.join(' ');
  250. }
  251. return result;
  252. },
  253. // inherit docs
  254. addUIToElement: function() {
  255. var me = this,
  256. array, cls;
  257. me.callParent(arguments);
  258. cls = me.baseCls + '-body-' + me.ui;
  259. if (me.rendered) {
  260. if (me.bodyCls) {
  261. me.body.addCls(me.bodyCls);
  262. } else {
  263. me.body.addCls(cls);
  264. }
  265. } else {
  266. if (me.bodyCls) {
  267. array = me.bodyCls.split(' ');
  268. if (!Ext.Array.contains(array, cls)) {
  269. array.push(cls);
  270. }
  271. me.bodyCls = array.join(' ');
  272. } else {
  273. me.bodyCls = cls;
  274. }
  275. }
  276. if (me.titleCmp &amp;&amp; me.titleCmp.rendered &amp;&amp; me.titleCmp.textEl) {
  277. me.titleCmp.textEl.addCls(me.baseCls + '-text-' + me.ui);
  278. }
  279. },
  280. // inherit docs
  281. removeUIFromElement: function() {
  282. var me = this,
  283. array, cls;
  284. me.callParent(arguments);
  285. cls = me.baseCls + '-body-' + me.ui;
  286. if (me.rendered) {
  287. if (me.bodyCls) {
  288. me.body.removeCls(me.bodyCls);
  289. } else {
  290. me.body.removeCls(cls);
  291. }
  292. } else {
  293. if (me.bodyCls) {
  294. array = me.bodyCls.split(' ');
  295. Ext.Array.remove(array, cls);
  296. me.bodyCls = array.join(' ');
  297. } else {
  298. me.bodyCls = cls;
  299. }
  300. }
  301. if (me.titleCmp &amp;&amp; me.titleCmp.rendered &amp;&amp; me.titleCmp.textEl) {
  302. me.titleCmp.textEl.removeCls(me.baseCls + '-text-' + me.ui);
  303. }
  304. },
  305. onClick: function(e) {
  306. this.fireClickEvent('click', e);
  307. },
  308. onDblClick: function(e){
  309. this.fireClickEvent('dblclick', e);
  310. },
  311. fireClickEvent: function(type, e){
  312. var toolCls = '.' + Ext.panel.Tool.prototype.baseCls;
  313. if (!e.getTarget(toolCls)) {
  314. this.fireEvent(type, this, e);
  315. }
  316. },
  317. getFocusEl: function() {
  318. return this.el;
  319. },
  320. getTargetEl: function() {
  321. return this.body || this.frameBody || this.el;
  322. },
  323. <span id='Ext-panel-Header-method-setTitle'> /**
  324. </span> * Sets the title of the header.
  325. * @param {String} title The title to be set
  326. */
  327. setTitle: function(title) {
  328. var me = this,
  329. sprite,
  330. surface;
  331. if (me.rendered) {
  332. if (me.titleCmp.rendered) {
  333. if (me.titleCmp.surface) {
  334. me.title = title || '';
  335. sprite = me.titleCmp.surface.items.items[0];
  336. surface = me.titleCmp.surface;
  337. surface.remove(sprite);
  338. me.textConfig.type = 'text';
  339. me.textConfig.text = title;
  340. sprite = surface.add(me.textConfig);
  341. sprite.setAttributes({
  342. rotate: {
  343. degrees: 90
  344. }
  345. }, true);
  346. me.titleCmp.autoSizeSurface();
  347. } else {
  348. me.title = title;
  349. me.titleCmp.textEl.update(me.title || '&amp;#160;');
  350. }
  351. me.titleCmp.updateLayout();
  352. } else {
  353. me.titleCmp.on({
  354. render: function() {
  355. me.setTitle(title);
  356. },
  357. single: true
  358. });
  359. }
  360. } else {
  361. me.title = title;
  362. }
  363. },
  364. <span id='Ext-panel-Header-method-getMinWidth'> /**
  365. </span> * @private
  366. * Used when shrink wrapping a Panel to either content width or header width.
  367. * This returns the minimum width required to display the header, icon and tools.
  368. * **This is only intended for use with horizontal headers.**
  369. */
  370. getMinWidth: function() {
  371. var me = this,
  372. textEl = me.titleCmp.textEl.dom,
  373. result,
  374. tools = me.tools,
  375. l, i;
  376. // Measure text width as inline element so it doesn't stretch
  377. textEl.style.display = 'inline';
  378. result = textEl.offsetWidth;
  379. textEl.style.display = '';
  380. // Add tools width
  381. if (tools &amp;&amp; (l = tools.length)) {
  382. for (i = 0; i &lt; l; i++) {
  383. if (tools[i].el) {
  384. result += tools[i].el.dom.offsetWidth;
  385. }
  386. }
  387. }
  388. // Add iconWidth
  389. if (me.iconCmp) {
  390. result += me.iconCmp.el.dom.offsetWidth;
  391. }
  392. // Return with some space between title and tools/end of header.
  393. return result + 10;
  394. },
  395. <span id='Ext-panel-Header-method-setIconCls'> /**
  396. </span> * Sets the CSS class that provides the icon image for this header. This method will replace any existing
  397. * icon class if one has already been set.
  398. * @param {String} cls The new CSS class name
  399. */
  400. setIconCls: function(cls) {
  401. var me = this,
  402. isEmpty = !cls || !cls.length,
  403. iconCmp = me.iconCmp;
  404. me.iconCls = cls;
  405. if (!me.iconCmp &amp;&amp; !isEmpty) {
  406. me.initIconCmp();
  407. me.insert(0, me.iconCmp);
  408. } else if (iconCmp) {
  409. if (isEmpty) {
  410. me.iconCmp.destroy();
  411. delete me.iconCmp;
  412. } else {
  413. iconCmp.removeCls(iconCmp.iconCls);
  414. iconCmp.addCls(cls);
  415. iconCmp.iconCls = cls;
  416. }
  417. }
  418. },
  419. <span id='Ext-panel-Header-method-setIcon'> /**
  420. </span> * Sets the image path that provides the icon image for this header. This method will replace any existing
  421. * icon if one has already been set.
  422. * @param {String} icon The new icon path
  423. */
  424. setIcon: function(icon) {
  425. var me = this,
  426. isEmpty = !icon || !icon.length,
  427. iconCmp = me.iconCmp;
  428. me.icon = icon;
  429. if (!me.iconCmp &amp;&amp; !isEmpty) {
  430. me.initIconCmp();
  431. me.insert(0, me.iconCmp);
  432. } else if (iconCmp) {
  433. if (isEmpty) {
  434. me.iconCmp.destroy();
  435. delete me.iconCmp;
  436. } else {
  437. iconCmp.setSrc(me.icon);
  438. }
  439. }
  440. },
  441. <span id='Ext-panel-Header-method-addTool'> /**
  442. </span> * Add a tool to the header
  443. * @param {Object} tool
  444. */
  445. addTool: function(tool) {
  446. this.tools.push(this.add(tool));
  447. },
  448. <span id='Ext-panel-Header-method-onAdd'> /**
  449. </span> * @protected
  450. * Set up the `tools.&lt;tool type&gt;` link in the owning Panel.
  451. * Bind the tool to its owning Panel.
  452. * @param component
  453. * @param index
  454. */
  455. onAdd: function(component, index) {
  456. this.callParent(arguments);
  457. if (component instanceof Ext.panel.Tool) {
  458. component.bindTo(this.ownerCt);
  459. this.tools[component.type] = component;
  460. }
  461. },
  462. <span id='Ext-panel-Header-method-initRenderData'> /**
  463. </span> * Add bodyCls to the renderData object
  464. * @return {Object} Object with keys and values that are going to be applied to the renderTpl
  465. * @private
  466. */
  467. initRenderData: function() {
  468. return Ext.applyIf(this.callParent(), {
  469. bodyCls: this.bodyCls
  470. });
  471. }
  472. });
  473. </pre>
  474. </body>
  475. </html>