3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.panel.Header
17 * @extends Ext.container.Container
18 * Simple header class which is used for on {@link Ext.panel.Panel} and {@link Ext.window.Window}
20 Ext.define('Ext.panel.Header', {
21 extend: 'Ext.container.Container',
22 uses: ['Ext.panel.Tool', 'Ext.draw.Component', 'Ext.util.CSS'],
23 alias: 'widget.header',
31 '<div id="{id}-body" class="{baseCls}-body<tpl if="bodyCls"> {bodyCls}</tpl>',
33 '<tpl for="uiCls"> {parent.baseCls}-body-{parent.ui}-{.}</tpl>',
35 '<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>></div>'],
39 * The title text to display
43 * @cfg {String} iconCls
44 * CSS class for icon in header. Used for displaying an icon to the left of a title.
47 initComponent: function() {
55 me.indicateDragCls = me.baseCls + '-draggable';
56 me.title = me.title || ' ';
57 me.tools = me.tools || [];
58 me.items = me.items || [];
59 me.orientation = me.orientation || 'horizontal';
60 me.dock = (me.dock) ? me.dock : (me.orientation == 'horizontal') ? 'top' : 'left';
62 //add the dock as a ui
63 //this is so we support top/right/left/bottom headers
64 me.addClsWithUI(me.orientation);
65 me.addClsWithUI(me.dock);
67 me.addChildEls('body');
70 if (!Ext.isEmpty(me.iconCls)) {
72 me.items.push(me.iconCmp);
76 if (me.orientation == 'vertical') {
77 // Hack for IE6/7's inability to display an inline-block
78 if (Ext.isIE6 || Ext.isIE7) {
79 me.width = this.width || 24;
80 } else if (Ext.isIEQuirks) {
81 me.width = this.width || 25;
87 clearInnerCtOnLayout: true,
88 bindToOwnerCtContainer: false
91 cls: me.baseCls + '-text',
99 if (Ext.isArray(ui)) {
102 ruleStyle = '.' + me.baseCls + '-text-' + ui;
103 if (Ext.scopeResetCSS) {
104 ruleStyle = '.' + Ext.baseCSSPrefix + 'reset ' + ruleStyle;
106 rule = Ext.util.CSS.getRule(ruleStyle);
111 Ext.apply(me.textConfig, {
112 'font-family': style.fontFamily,
113 'font-weight': style.fontWeight,
114 'font-size': style.fontSize,
118 me.titleCmp = Ext.create('Ext.draw.Component', {
119 ariaRole : 'heading',
125 items: [ me.textConfig ],
126 // this is a bit of a cheat: we are not selecting an element of titleCmp
127 // but rather of titleCmp.items[0] (so we cannot use childEls)
129 textEl: '.' + me.baseCls + '-text'
136 clearInnerCtOnLayout: true,
137 bindToOwnerCtContainer: false
139 me.titleCmp = Ext.create('Ext.Component', {
141 ariaRole : 'heading',
144 cls: me.baseCls + '-text-container',
146 '<span id="{id}-textEl" class="{cls}-text {cls}-text-{ui}">{title}</span>'
156 me.items.push(me.titleCmp);
159 me.items = me.items.concat(me.tools);
163 initIconCmp: function() {
164 this.iconCmp = Ext.create('Ext.Component', {
167 '<img id="{id}-iconEl" alt="" src="{blank}" class="{cls}-icon {iconCls}"/>'
170 blank : Ext.BLANK_IMAGE_URL,
172 iconCls: this.iconCls,
173 orientation: this.orientation
175 childEls: ['iconEl'],
176 iconCls: this.iconCls
180 afterRender: function() {
183 me.el.unselectable();
184 if (me.indicateDrag) {
185 me.el.addCls(me.indicateDragCls);
194 afterLayout: function() {
196 me.callParent(arguments);
198 // IE7 needs a forced repaint to make the top framing div expand to full width
205 addUIClsToElement: function(cls, force) {
207 result = me.callParent(arguments),
208 classes = [me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls],
211 if (!force && me.rendered) {
213 me.body.addCls(me.bodyCls);
215 me.body.addCls(classes);
219 array = me.bodyCls.split(' ');
221 for (i = 0; i < classes.length; i++) {
222 if (!Ext.Array.contains(array, classes[i])) {
223 array.push(classes[i]);
227 me.bodyCls = array.join(' ');
229 me.bodyCls = classes.join(' ');
237 removeUIClsFromElement: function(cls, force) {
239 result = me.callParent(arguments),
240 classes = [me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls],
243 if (!force && me.rendered) {
245 me.body.removeCls(me.bodyCls);
247 me.body.removeCls(classes);
251 array = me.bodyCls.split(' ');
253 for (i = 0; i < classes.length; i++) {
254 Ext.Array.remove(array, classes[i]);
257 me.bodyCls = array.join(' ');
265 addUIToElement: function(force) {
269 me.callParent(arguments);
271 cls = me.baseCls + '-body-' + me.ui;
272 if (!force && me.rendered) {
274 me.body.addCls(me.bodyCls);
280 array = me.bodyCls.split(' ');
282 if (!Ext.Array.contains(array, cls)) {
286 me.bodyCls = array.join(' ');
292 if (!force && me.titleCmp && me.titleCmp.rendered && me.titleCmp.textEl) {
293 me.titleCmp.textEl.addCls(me.baseCls + '-text-' + me.ui);
298 removeUIFromElement: function() {
302 me.callParent(arguments);
304 cls = me.baseCls + '-body-' + me.ui;
307 me.body.removeCls(me.bodyCls);
309 me.body.removeCls(cls);
313 array = me.bodyCls.split(' ');
314 Ext.Array.remove(array, cls);
315 me.bodyCls = array.join(' ');
321 if (me.titleCmp && me.titleCmp.rendered && me.titleCmp.textEl) {
322 me.titleCmp.textEl.removeCls(me.baseCls + '-text-' + me.ui);
326 onClick: function(e) {
327 if (!e.getTarget(Ext.baseCSSPrefix + 'tool')) {
328 this.fireEvent('click', e);
332 getTargetEl: function() {
333 return this.body || this.frameBody || this.el;
337 * Sets the title of the header.
338 * @param {String} title The title to be set
340 setTitle: function(title) {
343 if (me.titleCmp.rendered) {
344 if (me.titleCmp.surface) {
345 me.title = title || '';
346 var sprite = me.titleCmp.surface.items.items[0],
347 surface = me.titleCmp.surface;
349 surface.remove(sprite);
350 me.textConfig.type = 'text';
351 me.textConfig.text = title;
352 sprite = surface.add(me.textConfig);
353 sprite.setAttributes({
358 me.titleCmp.autoSizeSurface();
360 me.title = title || ' ';
361 me.titleCmp.textEl.update(me.title);
383 * Sets the CSS class that provides the icon image for this header. This method will replace any existing
384 * icon class if one has already been set.
385 * @param {String} cls The new CSS class name
387 setIconCls: function(cls) {
389 isEmpty = !cls || !cls.length,
390 iconCmp = me.iconCmp,
394 if (!me.iconCmp && !isEmpty) {
396 me.insert(0, me.iconCmp);
397 } else if (iconCmp) {
399 me.iconCmp.destroy();
402 el.removeCls(iconCmp.iconCls);
404 iconCmp.iconCls = cls;
410 * Add a tool to the header
411 * @param {Object} tool
413 addTool: function(tool) {
414 this.tools.push(this.add(tool));
419 * Set up the tools.<tool type> link in the owning Panel.
420 * Bind the tool to its owning Panel.
424 onAdd: function(component, index) {
425 this.callParent([arguments]);
426 if (component instanceof Ext.panel.Tool) {
427 component.bindTo(this.ownerCt);
428 this.tools[component.type] = component;