/**
* Created by seeker910 on 13-12-31.
*/
/*
layouter 所用到的数据全部来自对象本身属性,不是dom对象数据。
* */
Rsd.define("Rsd.common.Layouter", {
extend:'Rsd.common.Object',
singleton:true,
xtype: 'layouter',
constructor: function Layouter () {
},
/**
* @description 处理 dom对象
* @description 设置位置相关属性:width、height、margin...以及自定义style,display=none 不参与布局
* */
layout: function layout(obj) {
//监控 layout 执行次数
//console.trace('in layouter',obj.id,obj.width);
if (Rsd.isCreated(obj) == false) {
return;
}
if (obj.isHidden()) {
return;
}
if (obj.dom == null) {
return;
}
var _sizeUnit = obj.sizeUnit||'px';
//sytle样式 在属性中控制 布局后的 样式发生改变
var _element = obj.style.element;
if(obj.style.element)
{
delete obj.style.element;
}
obj.setElStyle(_element||obj.dom,obj.style,_sizeUnit);
if(_element)
{
obj.style.element = _element;
}
//设置 高度 宽度 属性,单独控制
var _domStyle = {};
if (!Rsd.isUndefined(obj.width)) {
_domStyle.width = obj.width;
}
if (!Rsd.isUndefined(obj.height) ) {
_domStyle.height = obj.height;
}
if (!Rsd.isUndefined(obj.flex) ) {
_domStyle.flex = obj.flex;
}
obj.setElStyle(obj.dom,_domStyle,_sizeUnit);
var _names = ['top', 'right', 'bottom', 'left'];
var _margin = obj.margin;
obj.margin ={ top: 0, right: 0, bottom: 0, left: 0 };
if (_margin) {
var _ms;
if (Rsd.getType(_margin) == '[object String]') {
_ms = _margin.split(' ');
for (var i in _ms) {
if ( Rsd.isNumber(Number(_ms[i]))) {
obj.margin[_names[i]] = _ms[i] + _sizeUnit;
}
else {
obj.margin[_names[i]] = _ms[i];
}
}
}
if (Rsd.getType(_margin) == '[object Array]') {
_ms = _margin;
for (var i in _ms) {
if ( Rsd.isNumber(Number(_ms[i]))) {
obj.margin[_names[i]] = _ms[i] + _sizeUnit;
}
else {
obj.margin[_names[i]] = _ms[i];
}
}
}
if (Rsd.getType(_margin) == '[object Object]') {
_ms = _margin;
for (var i in _ms) {
if (Rsd.isNumber(Number(_ms[i]))) {
obj.margin[i] = _ms[i] + _sizeUnit;
}
else {
obj.margin[i] = _ms[i];
}
}
}
}
obj.dom.style.marginTop = obj.margin.top;
obj.dom.style.marginRight = obj.margin.right;
obj.dom.style.marginBottom = obj.margin.bottom;
obj.dom.style.marginLeft = obj.margin.left;
//debugger;
var me = this;
setTimeout(function () {
me.layoutContent(obj.header || obj.label, obj.body || obj.ctrl,obj.sizeUnit);
if(obj.__blockOpacity !==true)
{
obj.dom.style.opacity = null;//不能在 show 方法中设置该值,不是所有的控件都会调用 show方法
}
},0);
},
/**
*
* @description 布局子控件 ,layoutBorder,layoutVbox,layoutHbox,layoutFit,layoutAuto
* */
layoutItems:function layoutItems(obj){
//debugger;
if (obj.items && Rsd.getType(obj.items) == '[object Array]' && obj.items.length > 0) {
switch (obj.layout.type.toLowerCase()) {
case 'border':
this.layoutBorder(obj);
break;
case 'vbox':
this.layoutVbox(obj);
break;
case 'hbox':
this.layoutHbox(obj);
break;
case 'fit':
this.layoutFit(obj);
break;
case 'auto':
this.layoutAuto(obj);
break;
default:
throw new Error('Object id\'s [' + obj.id+ '] layout value is unknown value [' + obj.layout.type + '] in class ' + obj.$className + '.');
break;
}
}
},
/**
* 边框布局:以上下左右为起点布局控件
* 容器:高度和宽度固定
* 子控件:高度固定,宽度固定
* region:top,bottom,left,right,center
* */
layoutBorder:function layoutBorder(obj){
//debugger;
if(obj.layout.type != 'border')
{
return;
}
obj.addCls('body','x-layout-border');
var _item;
var _i_margins = [0, 0, 0, 0];
var _sizeUnit = obj.sizeUnit||'px';
for (var i=0; i< obj.items.length ;i++) {
_item = obj.items[i];
if(!_item)
{
throw new Error('items['+i+'] is null in object '+ obj.id + '.');
}
if(!Rsd.isObject(_item))
{
throw new Error('items['+i+'] is not a object in object '+ obj.id + '.');
}
if(!(_item instanceof Rsd.common.ComponentX))
{
continue;
}
if(_item.floating || _item.fixed)
{
continue;
}
switch (_item.region) {
case 'top':
case 'north':
_item.addCls('dom','x-layout-border-north');
var _position = {};
_position.top = _i_margins[0] + _sizeUnit;
_position.right = _i_margins[1] + _sizeUnit;
_position.bottom = null;
_position.left = _i_margins[3] + _sizeUnit;
_item.setPosition(_position);
if (!_item.height) {
continue;
}
if (typeof (_item.height) == 'string' && parseInt(_item.height)) {
_i_margins[0] += parseInt(_item.height);
}else
{
_i_margins[0] += _item.height;
}
break;
case 'right':
case 'east':
_item.addCls('dom','x-layout-border-east');
var _position = {};
_position.top = _i_margins[0] + _sizeUnit;
_position.right = _i_margins[1] + _sizeUnit;
_position.bottom = _i_margins[2] + _sizeUnit;
_position.left = null;
_item.setPosition(_position);
if (!_item.width) {
continue;
}
if (typeof (_item.width) == 'string' && parseInt(_item.width)) {
_i_margins[1] += parseInt(_item.width);
}else {
_i_margins[1] += _item.width;
}
break;
case 'bottom':
case 'south':
_item.addCls('dom','x-layout-border-south');
var _position = {};
_position.top = null;
_position.right = _i_margins[1] + _sizeUnit;
_position.bottom = _i_margins[2] + _sizeUnit;
_position.left = _i_margins[3] + _sizeUnit;
_item.setPosition(_position);
if (!_item.height) {
continue;
}
if (typeof (_item.height) == 'string' && parseInt(_item.height))
{
_i_margins[2] += parseInt(_item.height);
}
else
{
_i_margins[2] += _item.height;
}
break;
case 'left':
case 'west':
_item.addCls('dom','x-layout-border-west');
var _position = {};
_position.top = _i_margins[0]+ _sizeUnit;
_position.right = null;
_position.bottom = _i_margins[2]+ _sizeUnit;
_position.left = _i_margins[3]+ _sizeUnit;
_item.setPosition(_position);
if (!_item.width) {
continue;
}
if (typeof (_item.width) == 'string' && parseInt(_item.width)) {
_i_margins[3] += parseInt(_item.width);
}
else
{
_i_margins[3] += _item.width;
}
break;
case 'center':
_item.width = 'auto';
_item.height = 'auto';
break;
default:
throw new Error('Property region(top/north,right/east,bottom/south,left/west,center) of component['+ _item.$className +'] is unknown value ['+_item.region+'] in '+ obj.$className +'.');
break;
}
}
for (var i=0; i< obj.items.length ;i++) {
_item = obj.items[i];
if(!(_item instanceof Rsd.common.ComponentX))
{
continue;
}
if(_item.floating || _item.fixed)
{
continue;
}
switch (_item.region) {
case 'center':
_item.width = null;
_item.height = null;
_item.addCls('dom','x-layout-border-center');
var _position = {};
_position.top = _i_margins[0] + _sizeUnit;
_position.right = _i_margins[1] + _sizeUnit;
_position.bottom = _i_margins[2] + _sizeUnit;
_position.left = _i_margins[3] + _sizeUnit;
_item.setPosition(_position);
if(_i_margins[0]==0 && _i_margins[2]==0)
{
//_item.height = '100%';
}
if(_i_margins[1]==0 && _i_margins[3]==0) {
//_item.width = '100%';
}
break;
default:
break;
}
}
},
/**
* 流式布局:单列多行
* 容器:高度和宽度固定,
* 子控件:高度不固,宽度固定
* display:flex ,flex-direction:column; 一列多行布局
* */
layoutVbox:function layoutVbox(obj){
if(obj.layout.type != 'vbox')
{
return;
}
switch (obj.layout.align)
{
case 'left':
obj.addCls('body','x-layout-vbox-left');
break;
case 'right':
obj.addCls('body','x-layout-vbox-right');
break;
case 'top':
obj.addCls('body','x-layout-vbox-top');
break;
case 'bottom':
obj.addCls('body','x-layout-vbox-bottom');
break;
case 'center':
obj.addCls('body','x-layout-vbox-center');
break;
default :
throw new Error('Property align of layout is unknown value ['+_item.align || obj.layout.align+'].');
break;
}
},
/**
* 流式布局:单行多列
* 容器:高度和宽度固定,
* 子控件:高度固定,宽度不固定
* display:flex ,flex-direction:row; 一行多列布局
* */
layoutHbox:function layoutHbox(obj){
if(obj.layout.type != 'hbox')
{
return;
}
switch (obj.layout.align)
{
case 'left':
obj.addCls('body','x-layout-hbox-left');
break;
case 'right':
obj.addCls('body','x-layout-hbox-right');
break;
case 'top':
obj.addCls('body','x-layout-hbox-top');
case 'bottom':
obj.addCls('body','x-layout-hbox-bottom');
break;
case 'center':
obj.addCls('body','x-layout-hbox-center');
break;
default :
throw new Error('Property align(left,right,top,bottom,center) of layout is unknown value ['+_item.align || obj.layout.align+'].');
break;
}
},
/***
* 自适应布局:只有一个子控件,子控件填满整个父控件,随父控件大小变化而变化。
* 如果有多个控件,只显示第一个子控件
*/
layoutFit:function layoutFit(obj)
{
if(obj.layout.type != 'fit')
{
return;
}
obj.addCls('body','x-layout-fit');
var _align = obj.layout.align;
var _item;
for (var i=0; i< obj.items.length ;i++) {
_item = obj.items[i];
if(_item.floating || _item.fixed)
{
continue;
}
switch (_align)
{
case 'center':
_item.addCls('dom','x-layout-fit-center');
break;
case 'left':
_item.addCls('dom','x-layout-fit-left');
break;
case 'right':
_item.addCls('dom','x-layout-fit-right');
break;
case 'top':
_item.addCls('dom','x-layout-fit-top');
break;
case 'bottom':
_item.addCls('dom','x-layout-fit-bottom');
break;
default :
throw new Error('Property align of layout is unknown value ['+_align+'].');
break;
}
}
},
/**
* 流式布局:多行多列
* 容器:高度和宽度固定,
* 子控件:高度不固定,宽度不固定
*
* */
layoutAuto:function layoutAuto(obj){
if(obj.layout.type != 'auto')
{
return;
}
obj.addCls('body','x-layout-auto');
var _align = obj.layout.align;
var _item;
for (var i=0; i< obj.items.length ;i++) {
_item = obj.items[i];
if(_item.floating || _item.fixed)
{
continue;
}
switch (_align)
{
case 'center':
_item.addCls('dom','x-layout-auto-center');
break;
case 'left':
_item.addCls('dom','x-layout-auto-left');
break;
case 'right':
_item.addCls('dom','x-layout-auto-right');
break;
case 'top':
_item.addCls('dom','x-layout-auto-top');
break;
case 'bottom':
_item.addCls('dom','x-layout-auto-bottom');
break;
default :
throw new Error('Property align of layout is unknown value ['+_align+'].');
break;
}
}
},
/**
* @description 布局 header(label),body(ctrl)
* */
layoutContent: function layoutContent(header,body,sizeUnit) {
var _h_element = header && header.element;
var _body_element = body && body.element;
var _position = header && header.position||'top';
var _space = parseInt(header && header.space)||0;
var _sizeUnit = sizeUnit||'px';
//在存在 label 或 header 时 ,设置body ,ctrl 样式
if(_body_element && _h_element)
{
_body_element.style.flexGrow = 1;
_body_element.style.flexShrink = 1;
_body_element.style.flexBasis ='0%';
//调整间隔
switch (_position.toLowerCase()) {
case 'top':
{
//_body_element.style.alignSelf = 'center';
_body_element.style.marginTop = _space + 'px' ;
}
break;
case 'bottom':
{
//_body_element.style.alignSelf = 'center';
_body_element.style.marginBottom = _space + 'px' ;
}
break;
case 'left':
{
_body_element.style.alignSelf = 'center';
_body_element.style.marginLeft = _space+ 'px';
}
break;
case 'right':
{
_body_element.style.alignSelf = 'center';
_body_element.style.marginRight = _space + 'px' ;
}
break
default:
throw new Error('Property position of header or label is unknown value ['+header.position+'].');
}
}
//设置 label 或 header 样式
if (_h_element) {
var _h_style = header.style || {};
Rsd.setElStyle(_h_element,_h_style,_sizeUnit);
switch (_position.toLowerCase()) {
case 'top':
{
_h_element.style.width = '100%';
_h_element.style.textAlign = header.align || 'center';
_h_element.style.height = header.height == null ? 'auto' :(Rsd.isNumber(Number(header.height))?(header.height + _sizeUnit):header.height);
}
break;
case 'bottom':
{
_h_element.style.width = '100%';
_h_element.style.textAlign = header.align || 'center';
_h_element.style.height = header.height == null ? 'auto' :(Rsd.isNumber(Number(header.height)) ? ( header.height + _sizeUnit):header.height);
}
break;
case 'left':
{
_h_element.style.textAlign = header.align || 'right';
_h_element.style.height = '100%';
_h_element.style.width = header.width == null ? 'auto' : ( Rsd.isNumber(Number(header.width)) ? ( header.width + _sizeUnit):header.width);
}
break;
case 'right':
{
//debugger;
_h_element.style.textAlign = header.align || 'left';
_h_element.style.height = '100%';
_h_element.style.width = header.width == null ? 'auto' : (Rsd.isNumber(Number(header.width)) ? ( header.width + _sizeUnit):header.width);
}
break
default:
throw new Error('Property position of header or label is unknown value ['+header.position+'].');
break;
}
//行高处理
if(header.lineHeight)
{
_h_element.style.lineHeight = header.lineHeight + _sizeUnit;
}
else
{
_h_element.style.lineHeight = _h_element.clientHeight?(_h_element.clientHeight + _sizeUnit):'unset';
}
if(header.content instanceof Rsd.common.ComponentX)
{
header.content.doLayout();
}
}
if(body && body.style)
{
Rsd.setElStyle(_body_element,body.style,_sizeUnit);
}
}
});