/** * Component layout for buttons * @private */ Ext.define('Ext.layout.component.Button', { /* Begin Definitions */ alias: ['layout.button'], extend: 'Ext.layout.component.Auto', /* End Definitions */ type: 'button', cellClsRE: /-btn-(tl|br)\b/, htmlRE: /<.*>/, constructor: function () { this.callParent(arguments); this.hackWidth = Ext.isIE && (!Ext.isStrict || Ext.isIE6 || Ext.isIE7); this.heightIncludesPadding = Ext.isIE6 && Ext.isStrict; }, // TODO - use last run results if text has not changed? beginLayout: function (ownerContext) { this.callParent(arguments); this.cacheTargetInfo(ownerContext); }, beginLayoutCycle: function(ownerContext) { var me = this, empty = '', owner = me.owner, btnEl = owner.btnEl, btnInnerEl = owner.btnInnerEl, text = owner.text, htmlAutoHeight; me.callParent(arguments); btnInnerEl.setStyle('overflow', empty); // Clear all element widths if (!ownerContext.widthModel.natural) { owner.el.setStyle('width', empty); } // If the text is HTML we need to let the browser automatically size things to cope with the case where the text // is multi-line. This incurs a cost as we then have to measure those elements to derive other sizes htmlAutoHeight = ownerContext.heightModel.shrinkWrap && text && me.htmlRE.test(text); btnEl.setStyle('width', empty); btnEl.setStyle('height', htmlAutoHeight ? 'auto' : empty); btnInnerEl.setStyle('width', empty); btnInnerEl.setStyle('height', htmlAutoHeight ? 'auto' : empty); btnInnerEl.setStyle('line-height', htmlAutoHeight ? 'normal' : empty); btnInnerEl.setStyle('padding-top', empty); owner.btnIconEl.setStyle('width', empty); }, calculateOwnerHeightFromContentHeight: function (ownerContext, contentHeight) { return contentHeight; }, calculateOwnerWidthFromContentWidth: function (ownerContext, contentWidth) { return contentWidth; }, measureContentWidth: function (ownerContext) { var me = this, owner = me.owner, btnEl = owner.btnEl, btnInnerEl = owner.btnInnerEl, text = owner.text, btnFrameWidth, metrics, sizeIconEl, width, btnElContext, btnInnerElContext; // IE suffers from various sizing problems, usually caused by relying on it to size elements automatically. Even // if an element is sized correctly it can prove necessary to set that size explicitly on the element to get it // to size and position its children correctly. While the exact nature of the problems varies depending on the // browser version, doctype and button configuration there is a common solution: set the sizes manually. if (owner.text && me.hackWidth && btnEl) { btnFrameWidth = me.btnFrameWidth; // If the button text is something like '<' or '<<' then we need to escape it or it won't be measured // correctly. The button text is supposed to be HTML and strictly speaking '<' and '<<' aren't valid HTML. // However in practice they are commonly used and have worked 'correctly' in previous versions. if (text.indexOf('>') === -1) { text = text.replace(/= 0) { btnInnerItem.setProp('line-height', btnHeight - btnFrameHeight + 'px'); } // Button text may contain markup that would force it to wrap to more than one line (e.g. 'Button
Label'). // When this happens, we cannot use the line-height set above for vertical centering; we instead reset the // line-height to normal, measure the rendered text height, and add padding-top to center the text block // vertically within the button's height. This is more expensive than the basic line-height approach so // we only do it if the text contains markup. if (text && me.htmlRE.test(text)) { btnInnerItem.setProp('line-height', 'normal'); btnInnerEl.setStyle('line-height', 'normal'); textHeight = Ext.util.TextMetrics.measure(btnInnerEl, text).height; paddingTop = Math.floor(Math.max(btnHeight - btnFrameHeight - textHeight, 0) / 2); btnInnerItem.setProp('padding-top', me.btnFrameTop + paddingTop); btnInnerItem.setHeight(btnHeight - (me.heightIncludesPadding ? paddingTop : 0)); } }, publishInnerWidth: function(ownerContext, width) { var me = this, isNum = Ext.isNumber, btnItem = ownerContext.getEl('btnEl'), btnInnerItem = ownerContext.getEl('btnInnerEl'), btnWidth = isNum(width) ? width - me.adjWidth : width; btnItem.setWidth(btnWidth); btnInnerItem.setWidth(btnWidth); }, clearTargetCache: function(){ delete this.adjWidth; }, cacheTargetInfo: function(ownerContext) { var me = this, owner = me.owner, scale = owner.scale, padding, frameSize, btnWrapPadding, btnInnerEl, innerFrameSize; // The cache is only valid for a particular scale if (!('adjWidth' in me) || me.lastScale !== scale) { // If there has been a previous layout run it could have sullied the line-height if (me.lastScale) { owner.btnInnerEl.setStyle('line-height', ''); } me.lastScale = scale; padding = ownerContext.getPaddingInfo(); frameSize = ownerContext.getFrameInfo(); btnWrapPadding = ownerContext.getEl('btnWrap').getPaddingInfo(); btnInnerEl = ownerContext.getEl('btnInnerEl'); innerFrameSize = btnInnerEl.getPaddingInfo(); Ext.apply(me, { // Width adjustment must take into account the arrow area. The btnWrap is the which has padding to accommodate the arrow. adjWidth : btnWrapPadding.width + frameSize.width + padding.width, adjHeight : btnWrapPadding.height + frameSize.height + padding.height, btnFrameWidth : innerFrameSize.width, btnFrameHeight : innerFrameSize.height, btnFrameTop : innerFrameSize.top, // Use the line-height rather than height because if the text is multi-line then the height will be 'wrong' minTextHeight : parseInt(btnInnerEl.getStyle('line-height'), 10) }); } me.callParent(arguments); } });