Форк Rambox
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
7.5 KiB

/**
* The class is the default component layout for {@link Ext.Component} when no explicit
* `{@link Ext.Component#componentLayout componentLayout}` is configured.
*
* This class uses template methods to perform the individual aspects of measurement,
* calculation and publication of results. The methods called depend on the component's
* {@link Ext.Component#getSizeModel size model}.
*
* ## configured / calculated
*
* In either of these size models, the dimension of the outer element is of a known size.
* The size is found in the `ownerContext` (the {@link Ext.layout.ContextItem} for the owner
* component) as either "width" or "height". This value, if available, is passed to the
* `publishInnerWidth` or `publishInnerHeight` method, respectively.
*
* ## shrinkWrap
*
* When a dimension uses the `shrinkWrap` size model, that means the content is measured,
* then the outer (owner) size is calculated and published.
*
* For example, for a shrinkWrap width, the following sequence of calls are made:
*
* - `Ext.layout.component.Component#measureContentWidth`
* - `publishOwnerWidth`
* - `calculateOwnerWidthFromContentWidth`
* - `publishInnerWidth` (in the event of hitting a min/maxWidth constraint)
*
* ## natural
*
* When a dimension uses the `natural` size model, the measurement is made on the outer
* (owner) element. This size is then used to determine the content area in much the same
* way as if the outer element had a `configured` or `calculated` size model.
*
* - `Ext.layout.component.Component#measureOwnerWidth`
* - `publishInnerWidth`
*
* @protected
*/
Ext.define('Ext.layout.component.Auto', {
/* Begin Definitions */
alias: 'layout.autocomponent',
extend: 'Ext.layout.component.Component',
/* End Definitions */
type: 'autocomponent',
/**
* @cfg {Boolean} [setHeightInDom=false]
* @protected
* When publishing height of an auto Component, it is usually not written to the DOM.
* Setting this to `true` overrides this behaviour.
*/
setHeightInDom: false,
/**
* @cfg {Boolean} [setWidthInDom=false]
* @protected
* When publishing width of an auto Component, it is usually not written to the DOM.
* Setting this to `true` overrides this behaviour.
*/
setWidthInDom: false,
waitForOuterHeightInDom: false,
waitForOuterWidthInDom: false,
beginLayoutCycle: function(ownerContext, firstCycle){
var me = this,
lastWidthModel = me.lastWidthModel,
lastHeightModel = me.lastHeightModel,
el = me.owner.el;
me.callParent(arguments);
if (lastWidthModel && lastWidthModel.fixed && ownerContext.widthModel.shrinkWrap) {
el.setWidth(null);
}
if (lastHeightModel && lastHeightModel.fixed && ownerContext.heightModel.shrinkWrap) {
el.setHeight(null);
}
},
calculate: function(ownerContext) {
var me = this,
measurement = me.measureAutoDimensions(ownerContext),
heightModel = ownerContext.heightModel,
widthModel = ownerContext.widthModel,
width, height;
// It is generally important to process widths before heights, since widths can
// often effect heights...
if (measurement.gotWidth) {
if (widthModel.shrinkWrap) {
me.publishOwnerWidth(ownerContext, measurement.contentWidth);
} else if (me.publishInnerWidth) {
me.publishInnerWidth(ownerContext, measurement.width);
}
} else if (!widthModel.auto && me.publishInnerWidth) {
width = me.waitForOuterWidthInDom ? ownerContext.getDomProp('width')
: ownerContext.getProp('width');
if (width === undefined) {
me.done = false;
} else {
me.publishInnerWidth(ownerContext, width);
}
}
if (measurement.gotHeight) {
if (heightModel.shrinkWrap) {
me.publishOwnerHeight(ownerContext, measurement.contentHeight);
} else if (me.publishInnerHeight) {
me.publishInnerHeight(ownerContext, measurement.height);
}
} else if (!heightModel.auto && me.publishInnerHeight) {
height = me.waitForOuterHeightInDom ? ownerContext.getDomProp('height')
: ownerContext.getProp('height');
if (height === undefined) {
me.done = false;
} else {
me.publishInnerHeight(ownerContext, height);
}
}
if (!measurement.gotAll) {
me.done = false;
}
},
calculateOwnerHeightFromContentHeight: function (ownerContext, contentHeight) {
return contentHeight + ownerContext.getFrameInfo().height;
},
calculateOwnerWidthFromContentWidth: function (ownerContext, contentWidth) {
return contentWidth + ownerContext.getFrameInfo().width;
},
publishOwnerHeight: function (ownerContext, contentHeight) {
var me = this,
owner = me.owner,
height = me.calculateOwnerHeightFromContentHeight(ownerContext, contentHeight),
constrainedHeight, dirty, heightModel;
if (isNaN(height)) {
me.done = false;
} else {
constrainedHeight = Ext.Number.constrain(height, owner.minHeight, owner.maxHeight);
if (constrainedHeight === height) {
dirty = me.setHeightInDom;
} else {
heightModel = me.sizeModels[
(constrainedHeight < height) ? 'constrainedMax' : 'constrainedMin'];
height = constrainedHeight;
if (ownerContext.heightModel.calculatedFromShrinkWrap) {
// Don't bother to invalidate since that will come soon... but we need
// to signal our ownerLayout that we need an invalidate to actually
// make good on the determined (constrained) size!
ownerContext.heightModel = heightModel;
} else {
ownerContext.invalidate({ heightModel: heightModel });
}
}
ownerContext.setHeight(height, dirty);
}
},
publishOwnerWidth: function (ownerContext, contentWidth) {
var me = this,
owner = me.owner,
width = me.calculateOwnerWidthFromContentWidth(ownerContext, contentWidth),
constrainedWidth, dirty, widthModel;
if (isNaN(width)) {
me.done = false;
} else {
constrainedWidth = Ext.Number.constrain(width, owner.minWidth, owner.maxWidth);
if (constrainedWidth === width) {
dirty = me.setWidthInDom;
} else {
widthModel = me.sizeModels[
(constrainedWidth < width) ? 'constrainedMax' : 'constrainedMin'];
width = constrainedWidth;
if (ownerContext.widthModel.calculatedFromShrinkWrap) {
// Don't bother to invalidate since that will come soon... but we need
// to signal our ownerLayout that we need an invalidate to actually
// make good on the determined (constrained) size!
ownerContext.widthModel = widthModel;
} else {
ownerContext.invalidate({ widthModel: widthModel });
}
}
ownerContext.setWidth(width, dirty);
}
}
});