/*!
|
* Ext JS Library 3.1.0
|
* Copyright(c) 2006-2009 Ext JS, LLC
|
* licensing@extjs.com
|
* http://www.extjs.com/license
|
*/
|
/**
|
* @class Ext.layout.ContainerLayout
|
* <p>The ContainerLayout class is the default layout manager delegated by {@link Ext.Container} to
|
* render any child Components when no <tt>{@link Ext.Container#layout layout}</tt> is configured into
|
* a {@link Ext.Container Container}. ContainerLayout provides the basic foundation for all other layout
|
* classes in Ext. It simply renders all child Components into the Container, performing no sizing or
|
* positioning services. To utilize a layout that provides sizing and positioning of child Components,
|
* specify an appropriate <tt>{@link Ext.Container#layout layout}</tt>.</p>
|
* <p>This class is intended to be extended or created via the <tt><b>{@link Ext.Container#layout layout}</b></tt>
|
* configuration property. See <tt><b>{@link Ext.Container#layout}</b></tt> for additional details.</p>
|
*/
|
Ext.layout.ContainerLayout = Ext.extend(Object, {
|
/**
|
* @cfg {String} extraCls
|
* <p>An optional extra CSS class that will be added to the container. This can be useful for adding
|
* customized styles to the container or any of its children using standard CSS rules. See
|
* {@link Ext.Component}.{@link Ext.Component#ctCls ctCls} also.</p>
|
* <p><b>Note</b>: <tt>extraCls</tt> defaults to <tt>''</tt> except for the following classes
|
* which assign a value by default:
|
* <div class="mdetail-params"><ul>
|
* <li>{@link Ext.layout.AbsoluteLayout Absolute Layout} : <tt>'x-abs-layout-item'</tt></li>
|
* <li>{@link Ext.layout.Box Box Layout} : <tt>'x-box-item'</tt></li>
|
* <li>{@link Ext.layout.ColumnLayout Column Layout} : <tt>'x-column'</tt></li>
|
* </ul></div>
|
* To configure the above Classes with an extra CSS class append to the default. For example,
|
* for ColumnLayout:<pre><code>
|
* extraCls: 'x-column custom-class'
|
* </code></pre>
|
* </p>
|
*/
|
/**
|
* @cfg {Boolean} renderHidden
|
* True to hide each contained item on render (defaults to false).
|
*/
|
|
/**
|
* A reference to the {@link Ext.Component} that is active. For example, <pre><code>
|
* if(myPanel.layout.activeItem.id == 'item-1') { ... }
|
* </code></pre>
|
* <tt>activeItem</tt> only applies to layout styles that can display items one at a time
|
* (like {@link Ext.layout.AccordionLayout}, {@link Ext.layout.CardLayout}
|
* and {@link Ext.layout.FitLayout}). Read-only. Related to {@link Ext.Container#activeItem}.
|
* @type {Ext.Component}
|
* @property activeItem
|
*/
|
|
// private
|
monitorResize:false,
|
// private
|
activeItem : null,
|
|
constructor : function(config){
|
Ext.apply(this, config);
|
},
|
|
// private
|
layout : function(){
|
var target = this.container.getLayoutTarget();
|
if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){
|
target.addClass(this.targetCls)
|
}
|
this.onLayout(this.container, target);
|
this.container.fireEvent('afterlayout', this.container, this);
|
this.hasLayout = true;
|
},
|
|
// private
|
onLayout : function(ct, target){
|
this.renderAll(ct, target);
|
},
|
|
// private
|
isValidParent : function(c, target){
|
return target && c.getPositionEl().dom.parentNode == (target.dom || target);
|
},
|
|
// private
|
renderAll : function(ct, target){
|
var items = ct.items.items;
|
for(var i = 0, len = items.length; i < len; i++) {
|
var c = items[i];
|
if(c && (!c.rendered || !this.isValidParent(c, target))){
|
this.renderItem(c, i, target);
|
}
|
}
|
},
|
|
// private
|
renderItem : function(c, position, target){
|
if(c && !c.rendered){
|
c.render(target, position);
|
this.configureItem(c, position);
|
}else if(c && !this.isValidParent(c, target)){
|
if(Ext.isNumber(position)){
|
position = target.dom.childNodes[position];
|
}
|
target.dom.insertBefore(c.getPositionEl().dom, position || null);
|
c.container = target;
|
this.configureItem(c, position);
|
}
|
},
|
|
// private
|
configureItem: function(c, position){
|
if(this.extraCls){
|
var t = c.getPositionEl ? c.getPositionEl() : c;
|
t.addClass(this.extraCls);
|
}
|
// If we are forcing a layout, do so *before* we hide so elements have height/width
|
if(c.doLayout && this.forceLayout){
|
c.doLayout(false, true);
|
}
|
if (this.renderHidden && c != this.activeItem) {
|
c.hide();
|
}
|
},
|
|
onRemove: function(c){
|
if(this.activeItem == c){
|
delete this.activeItem;
|
}
|
if(c.rendered && this.extraCls){
|
var t = c.getPositionEl ? c.getPositionEl() : c;
|
t.removeClass(this.extraCls);
|
}
|
},
|
|
// private
|
onResize: function(){
|
var ct = this.container,
|
b = ct.bufferResize;
|
|
if (ct.collapsed){
|
return;
|
}
|
|
// Not having an ownerCt negates the buffering: floating and top level
|
// Containers (Viewport, Window, ToolTip, Menu) need to lay out ASAP.
|
if (b && ct.ownerCt) {
|
// If we do NOT already have a layout pending from an ancestor, schedule one.
|
// If there is a layout pending, we do nothing here.
|
// buffering to be deprecated soon
|
if (!ct.hasLayoutPending()){
|
if(!this.resizeTask){
|
this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
|
this.resizeBuffer = Ext.isNumber(b) ? b : 50;
|
}
|
ct.layoutPending = true;
|
this.resizeTask.delay(this.resizeBuffer);
|
}
|
}else{
|
ct.doLayout(false, this.forceLayout);
|
}
|
},
|
|
// private
|
runLayout: function(){
|
var ct = this.container;
|
ct.doLayout();
|
delete ct.layoutPending;
|
},
|
|
// private
|
setContainer : function(ct){
|
// No longer use events to handle resize. Instead this will be handled through a direct function call.
|
/*
|
if(this.monitorResize && ct != this.container){
|
var old = this.container;
|
if(old){
|
old.un(old.resizeEvent, this.onResize, this);
|
}
|
if(ct){
|
ct.on(ct.resizeEvent, this.onResize, this);
|
}
|
}
|
*/
|
this.container = ct;
|
},
|
|
// private
|
parseMargins : function(v){
|
if(Ext.isNumber(v)){
|
v = v.toString();
|
}
|
var ms = v.split(' ');
|
var len = ms.length;
|
if(len == 1){
|
ms[1] = ms[0];
|
ms[2] = ms[0];
|
ms[3] = ms[0];
|
}
|
if(len == 2){
|
ms[2] = ms[0];
|
ms[3] = ms[1];
|
}
|
if(len == 3){
|
ms[3] = ms[1];
|
}
|
return {
|
top:parseInt(ms[0], 10) || 0,
|
right:parseInt(ms[1], 10) || 0,
|
bottom:parseInt(ms[2], 10) || 0,
|
left:parseInt(ms[3], 10) || 0
|
};
|
},
|
|
/**
|
* The {@link Ext.Template Ext.Template} used by Field rendering layout classes (such as
|
* {@link Ext.layout.FormLayout}) to create the DOM structure of a fully wrapped,
|
* labeled and styled form Field. A default Template is supplied, but this may be
|
* overriden to create custom field structures. The template processes values returned from
|
* {@link Ext.layout.FormLayout#getTemplateArgs}.
|
* @property fieldTpl
|
* @type Ext.Template
|
*/
|
fieldTpl: (function() {
|
var t = new Ext.Template(
|
'<div class="x-form-item {itemCls}" tabIndex="-1">',
|
'<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',
|
'<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
|
'</div><div class="{clearCls}"></div>',
|
'</div>'
|
);
|
t.disableFormats = true;
|
return t.compile();
|
})(),
|
|
/*
|
* Destroys this layout. This is a template method that is empty by default, but should be implemented
|
* by subclasses that require explicit destruction to purge event handlers or remove DOM nodes.
|
* @protected
|
*/
|
destroy : function(){
|
if(!Ext.isEmpty(this.targetCls)){
|
var target = this.container.getLayoutTarget();
|
if(target){
|
target.removeClass(this.targetCls);
|
}
|
}
|
}
|
});
|
Ext.Container.LAYOUTS['auto'] = Ext.layout.ContainerLayout;
|