X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2Fui%2F06_AbstractUINode.js;h=73d9c4bb6788a84683db200ab8261067a3227f55;hb=46d3fdf2559c59963e53ff6136c3fd58cd8f7a6d;hp=65bfd496f28c698756ebc99f517eb5b4681e8723;hpb=d0f13b6086143af1a134cf24282e817b5a86ca42;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/ui/06_AbstractUINode.js b/0.6.x/js/ui/06_AbstractUINode.js index 65bfd49..73d9c4b 100644 --- a/0.6.x/js/ui/06_AbstractUINode.js +++ b/0.6.x/js/ui/06_AbstractUINode.js @@ -2,72 +2,63 @@ var _AbstractUINode = X.EventDispatcher.inherits( '_AbstractUINode', X.Class.ABSTRACT | X.Class.PRIVATE_DATA, { - phase : 0, - root : null, - rootData : null, - parent : null, - parentData : null, - rawElement : null, - rawStyle : null, + phase : 0, + dirty : X.UI.Dirty.CLEAN, - //events : null, // X.EventDispatcher で設定される - reserveEvents : null, - gesture : null, - //elmScroll : null, - //elmScroller : null, - //elmScrollbar : null, - - style : null, - styleData : null, - forChrome : false, // メッキ + root : null, + rootData : null, + hoverList : null, + parent : null, + parentData : null, + xnode : null, - x : 0, - y : 0, - w : 0, - h : 0, - t : 0, // top - l : 0, // left - b : 0, // bottom - r : 0, // right - absoluteX : 0, - absoluteY : 0, - //_scrollX : 0, - //_scrollY : 0, - scrollingX : 0, - scrollingY : 0, - _cursor : '', - hitChildData : null, - hitSelf : false, - _disabled : false, - _childDisabled : false, - through : false, - clip : false, - hover : false, - hoverStyleName : null, - isHover : false, - scroll : false, - dragdrop : false, - tooltip : null, + supportAttrs : X.UI.Attr.Support, + attrClass : X.UI.AttrClass, + attrObject : null, + unverifiedAttrs : null, + + role : null, + pointerDisabled : false, + hoverClassName : null, + hovering : false, - _content : null, - updateContent : false, + reserveEvents : null, + gesture : null, + + absoluteX : 0, + absoluteY : 0, - boxWidth : 0, - boxHeight : 0, + boxX : 0, + boxY : 0, + scrollWidth : 0, + scrollHeight : 0, + boxWidth : X.UI.Attr.AUTO, + minBoxWidth : 0, + maxBoxWidth : X.UI.Attr.AUTO, + boxHeight : X.UI.Attr.AUTO, + minBoxHeight : 0, + maxBoxHeight : X.UI.Attr.AUTO, contentL : 0, contentT : 0, contentR : 0, contentB : 0, boxSizingOffsetLR : 0, boxSizingOffsetTB : 0, - contentWidth : 0, + contentWidth : X.UI.Attr.AUTO, minContentWidth : 0, - maxContentWidth : AUTO, + maxContentWidth : X.UI.Attr.AUTO, lastContentWidth : -1, - contentHeight : 0, + contentHeight : X.UI.Attr.AUTO, minContentHeight : 0, - maxContentHeight : AUTO, + maxContentHeight : X.UI.Attr.AUTO, + lastContentHeight : -1, + constraintW : false, + constraintH : false, + autoWidth : false, + autoHeight : false, + percentWidth : false, + percentHeight : false, // :hover, :focus, :disabled initialize : function( root, rootData, parent, parentData ){ @@ -75,44 +66,25 @@ var _AbstractUINode = X.EventDispatcher.inherits( this.rootData = rootData; this.parent = parent; this.parentData = parentData; - this.rawElement = X.Dom.Node.create( 'div' ); - - this.styleData.initialize(); + //this.xnode = X.Dom.Node.create( 'div' ); + this.phase = 1; - this.phase = 1; this.dispatch( { type : X.UI.Event.INIT } ); }, addToParent : function( parentElement ){ - //parentElement && parentElement.appendChild( this.rawElement ); - parentElement && parentElement.append( this.rawElement ); + parentElement && parentElement.append( this.xnode ); this.phase = 2; this.dispatch( { type : X.UI.Event.ADDED } ); }, - - /* Rellay - afterAddition : function(){ - this.styleData.afterAddition(); - - this.phase = 3; - this.dispatch( { type : X.UI.Event.CREATION_COMPLETE } ); - }, */ creationComplete : function(){ - if( this.phase < 3 ) return; - - var nodes = this.nodes, - events = this.reserveEvents, + var events = this.reserveEvents, l, i; - if( nodes ){ - for( i = 0, l = nodes.length; i < l; ++i ){ - nodes[ i ].creationComplete(); - }; - }; - this.mesure(); - // this.scroll === true && ScrollBarManager.register( this ); + this.phase = 3; + this.User.dispatch( { type : X.UI.Event.CREATION_COMPLETE } ); // html 要素が親に追加されるまで控えていたイベントの登録 if( events && ( l = events.length ) ){ @@ -121,258 +93,494 @@ var _AbstractUINode = X.EventDispatcher.inherits( }; events.length = 0; delete this.reserveEvents; - }; + }; }, - mesure : function(){ - var elm = this.rawElement, - x, y, w, h, parent; - if( elm ){ - w = elm.width();//w = elm.offsetWidth; - h = elm.height();//h = elm.offsetHeight; - x = elm.x();//x = elm.offsetLeft; - y = elm.y();//y = elm.offsetTop; - if( this.x !== x || this.y !== y || this.w !== w || this.h !== h ){ - this.x = x; - this.y = y; - this.w = w; - this.h = h; - ( parent = this.parentData ) && this.updateAbsoluteXY( parent.absoluteX, parent.absoluteY ); - }; - }; - this.updateRectangle(); - }, + /* + * _UINode への setAttr の他、attrClass.prototype への setAttr にも対応する + * 親要素が変化した場合、unverifiedAttrs を元に attrObject を再設定. + */ + setAttr : function( name, def, v ){ + var attrs = X.UI.attrClassProto || this.attrObject, + propID = def.No || def[ 5 ], + defaultVal = X.UI.attrClassProto ? attrs[ propID ] : this.attrClass.prototype[ propID ], // def[ 0 ], + currentVal = attrs ? attrs[ propID ] : defaultVal, + dirty = def[ 1 ], + user = def[ 2 ], + type = def[ 3 ], + list = def[ 4 ], + length = !!( type & X.UI.Attr.Type.LENGTH ), + minusLen = !!( type & X.UI.Attr.Type.MINUS_LENGTH ), + percent = !!( type & X.UI.Attr.Type.PERCENT ), + minusPct = !!( type & X.UI.Attr.Type.MINUS_PERCENT ), + numerical = !!( type & X.UI.Attr.Type.NUMERICAL ), + auto = !!( type & X.UI.Attr.Type.AUTO ), + color = !!( type & X.UI.Attr.Type.COLOR ), + url = !!( type & X.UI.Attr.Type.URL ), + fontName = !!( type & X.UI.Attr.Type.FONT_NAME ), + flag = !!( type & X.UI.Attr.Type.BOOLEAN ), + combi = !!( type & X.UI.Attr.Type.COMBI ), + quartet = !!( type & X.UI.Attr.Type.QUARTET ), + _v, i, l, nodes, root, roots; - updateAbsoluteXY : function( x, y /* , scrollX, scrollY */ ){ - var nodes = this.nodes, i; - this.absoluteX = x = this.x + x; - this.absoluteY = y = this.y + y; - if( !nodes ) return; - for( i = nodes.length; i; ){ - nodes[ --i ].updateAbsoluteXY( x, y ); + if( X.Type.isString( v ) ){ + //v = v.toLowercase(); + if( url || fontName ){ + // good + } else + if( auto && v === 'auto' ){ + v = X.UI.Attr.AUTO; + } else + if( list && ( _v = list[ v ] ) ){ + // good + v = _v; + } else + if( ( percent || minusPct ) && v.lastIndexOf( '%' ) !== -1 && isFinite( _v = parseFloat( v ) ) && v === _v + '%' ){ + // good + } else + if( ( length || minusLen ) && v.lastIndexOf( 'em' ) !== -1 && isFinite( _v = parseFloat( v ) ) && v === _v + 'em' ){ + v = _v; + } else + if( v.indexOf( ' ' ) !== -1 ){ + v = v.split( ' ' ); + } else + if( color && X.Type.isNumber( _v = X.Dom.Style.parseColor( v ) ) ){ + v = _v; + } else { + // bad + return; + }; }; - }, - - updateRectangle : function(){ - var w = this.w, h = this.h, x = this.x, y = this.y, - l = x, t = y, r = x + w, b = y + h, - nodes = this.nodes, i, node; + + if( ( quartet || combi ) && !X.Type.isArray( v ) ){ + v = [ v ]; + }; + + if( X.Type.isNumber( v ) ){ + if( + ( length && ( 0 <= v ) ) || + ( minusLen && ( v <= 0 ) ) || + ( percent && 0 <= v && v <= 1 ) || + ( minusPct && -1 <= v && v < 0 ) || + ( numerical && 0 <= v ) || + ( auto && v === X.UI.Attr.AUTO ) || + ( color && 0 <= v && v <= 0xFFFFFF ) || + ( list && list[ v ] ) + ){ + // good + } else { + // bad + return; + }; + } else + if( X.Type.isBoolean( v ) && !flag ){ + return; + } else + if( X.Type.isArray( v ) ){ + if( v.length <= 4 && quartet ){ + type &= ~X.UI.Attr.Type.QUARTET; + switch( v.length ){ + case 1 : + this.setAttr( false, [ defaultVal, user, dirty, type, list, propID ], v[ 0 ] ); + this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 0 ] ); + this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 0 ] ); + this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 0 ] ); + break; + case 2 : + this.setAttr( false, [ defaultVal, user, dirty, type, list, propID ], v[ 0 ] ); + this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 1 ] ); + this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 0 ] ); + this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 1 ] ); + break; + case 3 : + this.setAttr( false, [ defaultVal, user, dirty, type, list, propID ], v[ 0 ] ); + this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 1 ] ); + this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 2 ] ); + this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 1 ] ); + break; + case 4 : + this.setAttr( false, [ defaultVal, user, dirty, type, list, propID ], v[ 0 ] ); + this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 1 ] ); + this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 2 ] ); + this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 3 ] ); + break; + }; + } else + if( v.length === 2 && combi ){ + type &= ~X.UI.Attr.Type.COMBI; + this.setAttr( false, [ defaultVal, user, dirty, type, list, propID ], v[ 0 ] ); + this.setAttr( false, [ defaultVal, user, dirty, type, list, ++propID ], v[ 1 ] ); + } else { + // bad + return; + }; + + if( !X.UI.attrClassProto && user === X.UI.Attr.USER.XNODE && this.xnode ){ + this.xnode.css( X.UI.Attr.Rename[ name ] || name, this._createCssText( name ) ); + //console.log( ( X.UI.Attr.Rename[ name ] || name ) + ' ' + this._createCssText( name ) + ' ' + propID + ' ' + attrs[ propID ] ); + }; + return; + }; + + if( !v && v !== 0 ) v = defaultVal; + + if( X.UI.attrClassProto ){ + attrs[ propID ] = v; + return; + }; + + if( currentVal !== v ){ + switch( propID ){ + case X.UI.Attr.Support.left.No : + this.constraintW = attrs[ X.UI.Attr.Support.right.No ] !== null; + break; + case X.UI.Attr.Support.right.No : + this.constraintW = attrs[ X.UI.Attr.Support.left.No ] !== null; + break; + case X.UI.Attr.Support.top.No : + this.constraintH = attrs[ X.UI.Attr.Support.bottom.No ] !== null; + break; + case X.UI.Attr.Support.bottom.No : + this.constraintH = attrs[ X.UI.Attr.Support.top.No ] !== null; + break; + case X.UI.Attr.Support.width.No : + this.autoWidth = v === X.UI.Attr.AUTO; + this.percentWidth = X.Type.isString( v ); + break; + case X.UI.Attr.Support.height.No : + this.autoHeight = v === X.UI.Attr.AUTO; + this.percentHeight = X.Type.isString( v ); + break; + }; - if( nodes && this.clip === false ){ - for( i = nodes.length; i; ){ - node = nodes[ --i ]; - if( node.l + x < l ) l = x + node.l; - if( node.t + y < t ) t = y + node.t; - if( r < node.r + x ) r = x + node.r; - if( b < node.b + y ) b = y + node.b; + if( defaultVal === v ){ + if( attrs ) delete attrs[ propID ]; + } else { + if( !attrs ) attrs = this.attrObject = new this.attrClass; + attrs[ propID ] = v; }; + + if( name && user === X.UI.Attr.USER.XNODE && this.xnode ){ + this.xnode.css( X.UI.Attr.Rename[ name ] || name, this._createCssText( name ) ); + //console.log( ( X.UI.Attr.Rename[ name ] || name ) + ' ' + this._createCssText( name ) + ' ' + propID + ' ' + attrs[ propID ] ); + } else + if( this.dirty < dirty ) this.dirty = dirty; }; - // update - if( b !== this.b || r !== this.r || t !== this.t || l !== this.l ){ - this.l = l; - this.t = t; - this.r = r; - this.b = b; - this.parentData && this.parentData.clip === false && this.parentData.updateRectangle(); + }, + + _createCssText : function( name ){ + var attrs = this.attrObject || this.attrClass.prototype || X.UI.AttrClass, + def = this.supportAttrs[ name ], + no = def.No, + v = attrs[ def.No ], + type = def[ 3 ], + list = def[ 4 ], + flag = !!( type & X.UI.Attr.Type.BOOLEAN ), + combi = !!( type & X.UI.Attr.Type.COMBI ), + quartet = !!( type & X.UI.Attr.Type.QUARTET ); + + if( quartet ){ + if( attrs[ no + 1 ] === attrs[ no + 3 ] ){ + if( v === attrs[ no + 2 ] ){ + if( v === attrs[ no + 1 ] ){ + return this._createCssValue( v, type, list ); + }; + return [ + this._createCssValue( v, type, list ), + this._createCssValue( attrs[ no + 1 ], type, list ) + ].join( ' ' ); + }; + return [ + this._createCssValue( v, type, list ), + this._createCssValue( attrs[ no + 1 ], type, list ), + this._createCssValue( attrs[ no + 2 ], type, list ) + ].join( ' ' ); + }; + return [ + this._createCssValue( v, type, list ), + this._createCssValue( attrs[ no + 1 ], type, list ), + this._createCssValue( attrs[ no + 2 ], type, list ), + this._createCssValue( attrs[ no + 3 ], type, list ) + ].join( ' ' ); + } else + if( combi ){ + return [ + this._createCssValue( v, type, list ), + this._createCssValue( attrs[ no + 1 ], type, list ) + ].join( ' ' ); + } else + if( flag ){ + return v ? list : 'normal'; // }; + return this._createCssValue( v, type, list ); }, - - capcher : function( x, y ){ - var nodes, child, _x, _y, hit, i; - if( this._disabled === true ) return false; - delete this.hitChildData; - x -= this.x; - y -= this.y; - // この部分 Box に移動 - if( nodes = this.nodes ){ - _x = x - this.scrollingX; - _y = y - this.scrollingY; - for( i = nodes.length; i; ){ - child = nodes[ --i ]; - if( child._disabled === false && child.l <= _x && _x < child.r && child.t <= _y && _y < child.b && child.capcher( _x, _y ) === true ){ - this.hitChildData = child; - break; + + _createCssValue : function( v, type, list ){ + var length = !!( type & X.UI.Attr.Type.LENGTH ), + minusLen = !!( type & X.UI.Attr.Type.MINUS_LENGTH ), + percent = !!( type & X.UI.Attr.Type.PERCENT ), + minusPct = !!( type & X.UI.Attr.Type.MINUS_PERCENT ), + numerical = !!( type & X.UI.Attr.Type.NUMERICAL ), + auto = !!( type & X.UI.Attr.Type.AUTO ), + color = !!( type & X.UI.Attr.Type.COLOR ), + url = !!( type & X.UI.Attr.Type.URL ), + fontName = !!( type & X.UI.Attr.Type.FONT_NAME ); + + if( X.Type.isNumber( v ) ){ + if( auto && v === X.UI.Attr.AUTO ) return 'auto'; + if( length || minusLen ) return v + 'em'; + if( numerical ) return v; + if( list && list[ v ] ) return list[ v ]; + if( color ){ + if( v < 0x100000 ){ + v = '00000' + v.toString( 16 ); + return '#' + v.substr( v.length - 6 ); }; + return '#' + v.toString( 16 ); }; }; - if( this.through === true ){ - this.hitChildData && this.hitSelf === false && this.rootData.hoverList.push( this ); - return !!this.hitChildData; + if( X.Type.isString( v ) ){ + if( percent || minusPct || url || fontName ) return v; }; - hit = 0 <= x && x < this.w && 0 <= y && y < this.h; - ( this.hitChildData || hit ) && this.hitSelf === false && this.rootData.hoverList.push( this ); - if( hit === true && this.hitChildData === null ) this.rootData.targetNodeData = this; - return hit || !!this.hitChildData; + }, + + getAttr : function( name ){ + var attrs = this.attrObject || this.attrClass.prototype || X.UI.AttrClass, + support = this.supportAttrs[ name ], + v, type, list; + if( !support ) return; + + if( name.indexOf( 'border' ) === 0 ){ + name = name.substr( 6 ); + return [ this.getAttr( 'borderTop' + name ), this.getAttr( 'borderRight' + name ), this.getAttr( 'borderBottom' + name ), this.getAttr( 'borderLeft' + name ) ]; + }; + + type = support[ 3 ]; + // Unit + if( type & X.UI.Attr.Type.QUARTET ){ + return [ this.getAttr( name + 'Top' ), this.getAttr( name + 'Right' ), this.getAttr( name + 'Bottom' ), this.getAttr( name + 'Left' ) ]; + }; + if( type & X.UI.Attr.Type.COMBI ) return [ v, data[ ++propID ] ]; + + v = attrs[ support.No ]; + if( type & X.UI.Attr.Type.AUTO && v === X.UI.Attr.AUTO ) return 'auto'; + + list = support[ 4 ]; + if( list ) return list[ v ]; + + if( type & X.UI.Attr.Type.COLOR && X.Type.isNumber( v ) ) return v; + if( !( type & X.UI.Attr.Type.NUMERICAL ) && X.Type.isNumber( v ) ) return v + 'em'; + return v; }, + // em, px, % + getAttrWithUnit : function( prop, unit ){ + + }, + _remove : function(){ switch( this.phase ){ case 4: case 3: - //this.styleData.afterAddition(); + case 2: - //this.rawElement.parentNode.removeChild( this.rawElement ); - this.rawElement.remove(); + case 1: - //this.styleData.initialize(); + this.xnode.destroy(); + delete this.root; delete this.rootData; delete this.parent; delete this.parentData; - delete this.rawElement; + delete this.xnode; + + delete this.phase; }; - delete this.phase; + }, //killed - - - content : function( v ){ - if( Type.isString( v ) === true ){ - if( !this.rawText || this.rawText.data !== v ){ - this._content = v; - this.updateContent = true; - }; - return this.User; - } else - if( v === null ){ - if( this._content !== v && this.rawText ){ - this.updateContent = true; - }; - delete this._content; - return this.User; + + calculate : function( isNeedsDetection, x, y, allowedW, allowedH ){ + this.preMesure( allowedW, allowedH ); + + if( this.boxWidth === X.UI.Attr.AUTO || this.boxHeight === X.UI.Attr.AUTO ){ + this.mesure(); + this.postMesure(); }; - if( this._content || this._content === null ) return this._content; - if( this.rawText ) return this.rawText.data; - return null; + + !isNeedsDetection && this.updateLayout( x, y ); + }, + + /** + * X.Dom.BoxModel の情報を引きながら top,left,width,height,padding,border の設定 + */ + updateLayout : function( x, y ){ + this.boxX = x; + this.boxY = y; + this.xnode + .css( 'left', x ? x + 'em' : 0 ) + .css( 'top', y ? y + 'em' : 0 ) + .css( 'width', this.contentWidth ? _AbstractUINode.ceil( this.contentWidth ) + 'em' : 0 ) + .css( 'height', this.contentHeight ? _AbstractUINode.ceil( this.contentHeight ) + 'em' : 0 ) + .css( 'padding', this._createCssText( 'padding' ) ) + .css( 'borderWidth', this._createCssText( 'borderWidth' ) ); }, - - /* * 親の サイズを元に自身のサイズを計算していく */ - preMesure : function( allowW, allowH ){ - var style = this.styleData, - styles, calc, box, min, max, + preMesure : function( allowedW, allowedH ){ + var attrs = this.attrObject || this.attrClass.prototype || X.UI.AttrClass, + calc = _AbstractUINode.calcValue, + box = attrs[ X.UI.Attr.Support.sizing.No ], + min, max, + boxL, boxT, boxR, boxB, contentW, contentH, boxMinus, paddingT, paddingR, paddingB, paddingL, borderT, borderR, borderB, borderL; - - if( style ){ - styles = style.data; - calc = _AbstractUINode.calcValue; - box = styles[ X.Css.AttrNo.sizing ]; - - // Width が確定するパターン - // 自身が constraintW の場合 親が AUTO ではない - // 自身が constraintW でない場合自身が AUTO はなくかつ親 が AUTO の場合 or 自身は % でない - if( style.constraintW ? allowW !== AUTO : !style.autoWidth && ( allowW !== AUTO || !style.percentWidth ) ){ - if( style.constraintW ){ // 制約レイアウト - contentW = allowW - calc( styles[ X.Css.AttrNo.left ], allowW ) - calc( styles[ X.Css.AttrNo.right ], allowW ); - } else { - contentW = _AbstractUINode.finalValue( styles[ X.Css.AttrNo.width ], styles[ X.Css.AttrNo.minWidth ], styles[ X.Css.AttrNo.maxWidth ], allowW ); - }; - paddingR = calc( styles[ X.Css.AttrNo.padding + 1 ], allowW ); - paddingL = calc( styles[ X.Css.AttrNo.padding + 3 ], allowW ); - borderR = styles[ X.Css.AttrNo.border + 1 ]; - borderL = styles[ X.Css.AttrNo.border + 3 ]; - boxMinus = 0; - switch( box ){ - case 2 : // border-box - boxMinus -= borderR + borderL; - case 1 : // padding-box - boxMinus -= paddingR + paddingL; - // case 0 : // content-box - }; - this.contentL = borderL + paddingL; - this.contentR = borderR + paddingR; - this.contentWidth = contentW + boxMinus; - this.boxWidth = contentW - boxMinus + this.contentL + this.contentR; - this.boxSizingOffsetLR = boxMinus; - } else { - this.boxWidth = this.contentWidth = AUTO; - min = styles[ X.Css.AttrNo.minWidth ]; - max = styles[ X.Css.AttrNo.maxWidth ]; - this.minContentWidth = 1 <= min ? min : 0; - this.maxContentWidth = 1 <= max ? max : AUTO; - delete this.boxSizingOffsetLR; - }; - - // Height - if( style.constraintH ? allowH !== AUTO : !style.autoHeight && ( allowH !== AUTO || !style.percentHeight ) ){ - if( style.constraintH ){ // 制約レイアウト - contentH = allowH - calc( styles[ X.Css.AttrNo.top ], allowH ) - calc( styles[ X.Css.AttrNo.bottom ], allowH ); - } else { - contentH = _AbstractUINode.finalValue( styles[ X.Css.AttrNo.height ], styles[ X.Css.AttrNo.minHeight ], styles[ X.Css.AttrNo.maxHeight ], allowH ); - }; - paddingT = calc( styles[ X.Css.AttrNo.padding + 0 ], allowH );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して - paddingB = calc( styles[ X.Css.AttrNo.padding + 2 ], allowH ); - borderT = styles[ X.Css.AttrNo.border + 0 ]; - borderB = styles[ X.Css.AttrNo.border + 2 ]; - this.boxHeight = contentH; - boxMinus = 0; - switch( box ){ - case 2 : // border-box - boxMinus -= borderT + borderB; - case 1 : // padding-box - boxMinus -= paddingT + paddingB; - // case 0 : // content-box - }; - this.contentT = borderT + paddingT; - this.conetntB = borderB + paddingB; - this.contentHeight = contentH + boxMinus; - this.boxHeight = contentH - boxMinus + this.contentT + this.conetntB; // padding-box の場合 border だけ足される - this.boxSizingOffsetTB = boxMinus; + + // Width が確定するパターン + // 自身が constraintW の場合 親が AUTO ではない + // 自身が constraintW でない場合自身が AUTO はなくかつ親 が AUTO の場合 or 自身は % でない + + paddingR = calc( attrs[ X.UI.Attr.Support.padding.No + 1 ], allowedW ); + paddingL = calc( attrs[ X.UI.Attr.Support.padding.No + 3 ], allowedW ); + borderR = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 1 ], allowedW ); + borderL = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 3 ], allowedW ); + boxMinus = 0; + switch( box ){ + case 3 : // border-box + boxMinus -= borderR + borderL; + case 2 : // padding-box + boxMinus -= paddingR + paddingL; + // case 1 : // content-box + }; + this.contentL = borderL + paddingL; + this.contentR = borderR + paddingR; + + if( this.constraintW ? allowedW !== X.UI.Attr.AUTO : !this.autoWidth && ( allowedW !== X.UI.Attr.AUTO || !this.percentWidth ) ){ + if( this.constraintW ){ // 制約レイアウト + contentW = allowedW - ( boxL = calc( attrs[ X.UI.Attr.Support.left.No ], allowedW ) ) - ( boxR = calc( attrs[ X.UI.Attr.Support.right.No ], allowedW ) ); } else { - this.boxHeight = this.contentHeight = AUTO; - min = styles[ X.Css.AttrNo.minHeight ]; - max = styles[ X.Css.AttrNo.maxHeight ]; - this.minContentHeight = 1 <= min ? min : 0; - this.maxContentHeight = 1 <= max ? max : AUTO; - delete this.boxSizingOffsetTB; + contentW = _AbstractUINode.finalValue( attrs[ X.UI.Attr.Support.width.No ], attrs[ X.UI.Attr.Support.minWidth.No ], attrs[ X.UI.Attr.Support.maxWidth.No ], allowedW ); }; - } else { - this.boxWidth = this.contentWidth = allowW; - this.boxHeight = this.contentHeight = allowH; + this.contentWidth = contentW + boxMinus; + this.scrollWidth = this.contentWidth + this.contentL + this.contentR; + this.boxWidth = contentW - boxMinus + this.contentL + this.contentR; + this.boxSizingOffsetLR = boxMinus; delete this.minContentWidth; delete this.maxContentWidth; + delete this.minBoxWidth; + delete this.maxBoxWidth; + } else { + this.minContentWidth = calc( attrs[ X.UI.Attr.Support.minWidth.No ], allowedW ) + boxMinus; + this.maxContentWidth = calc( attrs[ X.UI.Attr.Support.maxWidth.No ], allowedW ) + boxMinus; + this.scrollWidth = this.contentWidth + this.contentL + this.contentR; + this.minBoxWidth = this.minContentWidth - boxMinus + this.contentL + this.contentR; + this.maxBoxWidth = this.maxContentWidth - boxMinus + this.contentL + this.contentR; + //delete this.contentWidth; + //delete this.scrollWidth; + //delete this.boxWidth; + //delete this.boxSizingOffsetLR; + }; + + paddingT = calc( attrs[ X.UI.Attr.Support.padding.No + 0 ], allowedH );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して + paddingB = calc( attrs[ X.UI.Attr.Support.padding.No + 2 ], allowedH ); + borderT = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 0 ], allowedH ); + borderB = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 2 ], allowedH ); + boxMinus = 0; + switch( box ){ + case 3 : // border-box + boxMinus -= borderT + borderB; + case 2 : // padding-box + boxMinus -= paddingT + paddingB; + // case 1 : // content-box + }; + this.contentT = borderT + paddingT; + this.contentB = borderB + paddingB; + + // Height + if( this.constraintH ? allowedH !== X.UI.Attr.AUTO : !this.autoHeight && ( allowedH !== X.UI.Attr.AUTO || !this.percentHeight ) ){ + if( this.constraintH ){ // 制約レイアウト + contentH = allowedH - ( boxT = calc( attrs[ X.UI.Attr.Support.top.No ], allowedH ) ) - ( boxB = calc( attrs[ X.UI.Attr.Support.bottom.No ], allowedH ) ); + } else { + contentH = _AbstractUINode.finalValue( attrs[ X.UI.Attr.Support.height.No ], attrs[ X.UI.Attr.Support.minHeight.No ], attrs[ X.UI.Attr.Support.maxHeight.No ], allowedH ); + }; + this.contentHeight = contentH + boxMinus; + this.scrollHeight = this.contentHeight + this.contentT + this.contentB; + this.boxHeight = contentH - boxMinus + this.contentT + this.contentB; // padding-box の場合 border だけ足される + this.boxSizingOffsetTB = boxMinus; delete this.minContentHeight; delete this.maxContentHeight; - delete this.contentL; - delete this.contentT; - delete this.contentR; - delete this.contentB; + delete this.minBoxHeight; + delete this.maxBoxHeight; + } else { + this.minContentHeight = calc( attrs[ X.UI.Attr.Support.minHeight.No ], allowedH ) + boxMinus; + this.maxContentHeight = calc( attrs[ X.UI.Attr.Support.maxHeight.No ], allowedH ) + boxMinus; + this.minBoxHeight = this.minContentHeight - boxMinus + this.contentT + this.contentB; + this.maxBoxHeight = this.maxContentHeight - boxMinus + this.contentT + this.contentB; + + //delete this.contentHeight; + //delete this.scrollHeight; + //delete this.boxHeight; + //delete this.boxSizingOffsetTB; + }; + + if( this.parentData && this.parentData.layout.overrideAttrsForChild.left ){ + if( this.constraintW ){ + this.boxX = ( boxL || boxL === 0 ) ? boxL : calc( attrs[ X.UI.Attr.Support.left.No ], allowedW ); + } else + if( attrs[ X.UI.Attr.Support.right.No ] === null ){ + this.boxX = ( boxL || boxL === 0 ) ? boxL : calc( attrs[ X.UI.Attr.Support.left.No ], allowedW ); + } else { + this.boxX = alllowW - this.boxWidth - ( ( boxR || boxR === 0 ) ? boxR : calc( attrs[ X.UI.Attr.Support.right.No ], allowedW ) ); + }; + } else { + delete this.boxX; + }; + + if( this.parentData && this.parentData.layout.overrideAttrsForChild.top ){ + if( this.constraintH ){ + this.boxY = ( boxT || boxT === 0 ) ? boxT : calc( attrs[ X.UI.Attr.Support.top.No ], allowedH ); + } else + if( attrs[ X.UI.Attr.Support.bottom.No ] === null ){ + this.boxY = ( boxT || boxT === 0 ) ? boxT : calc( attrs[ X.UI.Attr.Support.top.No ], allowedH ); + } else { + this.boxY = allowedH - this.boxHeight - ( ( boxB || boxB === 0 ) ? boxB : calc( attrs[ X.UI.Attr.Support.bottom.No ], allowedH ) ); + }; + } else { + delete this.boxY; }; }, /** - * 要素の追加・削除 - * 1. ペイントがある // 予約のみ - * 2. コンテンツがある // 予約のみ * - * 3. コンテンツを削除 // 予約のみ - * 4. 要素を削除 // 予約のみ - * - * コンテンツの再計算 - * 0. 要素追加して css セット - * 1. コンテンツの変更 - * 2. font 指定の変更 - * 3. contentWidth の変更 (コンテンツの高さの再計算) 前回の contentWidth の保持 - * - * contentSize, scrollSize の決定 + * 描画・計測を行って、contentSize, scrollSize の決定 */ - _mesure : function( dirty ){ - var content = this._content, - root = this.rootData, - style = this.styleData, - w = this.contentWidth, - h = this.contentHeight; - switch( this.updateContent === true ? X.Css.Dirty.CONTENT : dirty ){ + mesure : function(){ + var dirty = this.dirty, + w, h, xnode; + + if( dirty === X.UI.Dirty.CLEAN ){ + if( this.percentWidth || this.percentHeight ){ + + }; + }; + + switch( dirty ){ + + case X.UI.Dirty.CONTENT : // コンテンツが変更された + case X.UI.Dirty.FONT : // フォントサイズが変更された + delete this.lastContentWidth; + delete this.lastContentHeight; + + case X.UI.Dirty.LAYOUT : // レイアウトの再計算が必要 + + default : // TODO レイアウト崩れに対処 パフォーマンス悪い! - case X.Css.Dirty.CONTENT : // コンテンツが変更された - case X.Css.Dirty.FONT : // フォントサイズが変更された - this.hasTextNode && Node.root._startUpdate(); - this.lastContentWidth = -1; - case X.Css.Dirty.REFLOW : // レイアウトの再計算が必要 + w = this.contentWidth; + h = this.contentHeight; + xnode = this.xnode; + /* http://web-designs.seesaa.net/article/188400668.html * min-width の値が max-width の値より大きい場合は、max-width の値は min-width の値に設定される。 * @@ -390,157 +598,161 @@ var _AbstractUINode = X.EventDispatcher.inherits( * 3. content のサイズがすでに決定している * コンテンツの高さの再取得が必要 * 必要でない - */ - if( this.hasTextNode ){ - elm = this.rawElement; - if( w === AUTO ){ - w = this.contentWidth = elm.width(); + */ + if( xnode._xnodes && xnode._xnodes.length ){ + if( w === X.UI.Attr.AUTO ){ + w = this.contentWidth = xnode.css( 'width', 'auto' ).width() / xnode._getCharSize(); + console.log( xnode.width() + ' ' + xnode._getCharSize() + ' > ' + w ); + this.scrollWidth = w + this.contentL + this.contentR; if( this.maxContentWidth < w - this.boxSizingOffsetLR ) this.contentWidth = this.maxContentWidth + this.boxSizingOffsetLR; if( w - this.boxSizingOffsetLR < this.minContentWidth ) this.contentWidth = this.minContentWidth + this.boxSizingOffsetLR; this.lastContentWidth = this.contentWidth; - w !== this.contentWidth && elm.css( 'width', this.contentWidth + 'px' ); + w !== this.contentWidth && xnode.css( 'width', _AbstractUINode.ceil( this.contentWidth ) + 'em' ); - if( h === AUTO ){ - this.conetntHeight = h = elm.height(); + if( h === X.UI.Attr.AUTO ){ + this.contentHeight = h = xnode.css( 'height', 'auto' ).scrollHeight() / xnode._getCharSize(); // scrollHeight() ?? this.scrollHeight = h + this.contentT + this.contentB; if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB; if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB; } else { - this.scrollHeight = elm.height() + this.contentT + this.contentB; + this.scrollHeight = h + this.contentT + this.contentB; }; + + this.lastContentHeight = h; } else - if( h === AUTO ){ + if( h === X.UI.Attr.AUTO ){ if( w !== this.lastContentWidth ){ - elm.css( 'width', w + 'px' ); + xnode.css( 'width', _AbstractUINode.ceil( w ) + 'em' ); + this.lastContentWidth = w; - this.conetntHeight = h = elm.height(); + this.contentHeight = h = xnode.css( 'height', 'auto' ).scrollHeight() / xnode._getCharSize(); this.scrollWidth = w + this.contentL + this.contentR; this.scrollHeight = h + this.contentT + this.contentB; if( this.maxContentHeight < h - this.boxSizingOffsetTB ) this.contentHeight = this.maxContentHeight + this.boxSizingOffsetTB; if( h - this.boxSizingOffsetTB < this.minContentHeight ) this.contentHeight = this.minContentHeight + this.boxSizingOffsetTB; } else { - this.scrollWidth = w + this.contentL + this.contentR; - this.scrollHeight = h + this.contentT + this.contentB; - //root.paintReserve( this ); + this.contentHeight = this.lastContentHeight = h = + this.lastContentHeight === -1 ? xnode.css( 'height', 'auto' ).scrollHeight() / xnode._getCharSize() : this.lastContentHeight; + this.scrollWidth = w + this.contentL + this.contentR; + this.scrollHeight = h + this.contentT + this.contentB; }; } else - if( dirty !== X.Css.Dirty.REFLOW ){ - this.contentWidth = elm.width(); - this.contentHeight = elm.height(); + if( dirty !== X.UI.Dirty.LAYOUT ){ + this.contentWidth = this.lastContentWidth = w; //xnode.width(); + this.contentHeight = this.lastContentHeight = xnode.css( 'height', 'auto' ).scrollHeight() / xnode._getCharSize(); this.scrollWidth = this.contentWidth + this.contentL + this.contentR; this.scrollHeight = this.contentHeight + this.contentT + this.contentB; } else { - //root.paintReserve( this ); this.scrollWidth = w + this.contentL + this.contentR; this.scrollHeight = h + this.contentT + this.contentB; }; } else { // コンテンツを持たないため基本のサイズは0 - if( w === AUTO ) this.contentWidth = w = 0 < this.minContentWidth ? this.minContentWidth : 0; - if( h === AUTO ) this.contentHeight = h = 0 < this.minContentHeight ? this.minContentHeight : 0; + if( w === X.UI.Attr.AUTO ) this.contentWidth = w = 0 < this.minContentWidth ? this.minContentWidth : 0; + if( h === X.UI.Attr.AUTO ) this.contentHeight = h = 0 < this.minContentHeight ? this.minContentHeight : 0; this.scrollWidth = w + this.contentL + this.contentR; this.scrollHeight = h + this.contentT + this.contentB; - //root.paintReserve( this ); }; + + delete this.dirty; break; - case X.Css.Dirty.PAINT : // 再描画のみ必要 - root.paintReserve( this ); - break; + //case X.UI.Dirty.PAINT : // 再描画のみ必要 + // break; }; }, /** - * 自身のコンテンツサイズを元に AUTO な width, height を確定していく + * 自身の contentWidth, contentHeight を元に AUTO な width, height を確定していく */ postMesure : function(){ - var style = this.styleData, - styles, calc, box, + var attrs = this.attrObject || this.attrClass.prototype || X.UI.AttrClass, + calc = _AbstractUINode.calcValue, + box = attrs[ X.UI.Attr.Support.sizing.No ], contentW, contentH, contentPlus, paddingT, paddingR, paddingB, paddingL, borderT, borderR, borderB, borderL, min, max; - if( style ){ - styles = style.data; - calc = _AbstractUINode.advancedCalcValue; + + // Width + if( this.boxWidth === X.UI.Attr.AUTO ){ contentW = this.contentWidth; - box = styles[ X.Css.AttrNo.sizing ]; + paddingR = calc( attrs[ X.UI.Attr.Support.padding.No + 1 ], contentW ); + paddingL = calc( attrs[ X.UI.Attr.Support.padding.No + 3 ], contentW ); + borderR = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 1 ], contentW ); + borderL = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 3 ], contentW ); + contentPlus = 0; + switch( box ){ + case 3 : // border-box + contentPlus = borderR + borderL; + case 2 : // padding-box + contentPlus += paddingR + paddingL; + // case 1 : // content-box + }; - // Width - if( this.boxWidth === AUTO ){ - paddingR = calc( styles[ X.Css.AttrNo.padding + 1 ], contentW ); - paddingL = calc( styles[ X.Css.AttrNo.padding + 3 ], contentW ); - borderR = styles[ X.Css.AttrNo.border + 1 ]; - borderL = styles[ X.Css.AttrNo.border + 3 ]; - contentPlus = 0; - switch( box ){ - case 2 : // border-box - contentPlus = borderR + borderL; - case 1 : // padding-box - contentPlus += paddingR + paddingL; - // case 0 : // content-box - }; - - if( !style.constraintW ){ - contentW += contentPlus; - min = styles[ X.Css.AttrNo.minWidth ]; - max = styles[ X.Css.AttrNo.maxWidth ]; - if( contentW < min && contentPlus < min ){ - this.contentWidth = min - contentPlus; - } else - if( max < contentW && contentPlus < max ){ - this.contentWidth = max - contentPlus; - }; + if( !this.constraintW ){ + contentW += contentPlus; + min = calc( attrs[ X.UI.Attr.Support.minWidth.No ], contentW ); + max = calc( attrs[ X.UI.Attr.Support.maxWidth.No ], contentW ); + if( contentW < min && contentPlus < min ){ + this.contentWidth = min - contentPlus; + } else + if( max < contentW && contentPlus < max ){ + this.contentWidth = max - contentPlus; }; - this.contentL = borderL + paddingL; - this.contentR = borderR + paddingR; - this.boxWidth = this.contentWidth + this.contentL + this.contentR; }; - // Height - if( this.boxHeight === AUTO ){ - contentH = this.contentHeight; - paddingT = calc( styles[ X.Css.AttrNo.padding + 0 ], contentH );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して - paddingB = calc( styles[ X.Css.AttrNo.padding + 2 ], contentH ); - borderT = styles[ X.Css.AttrNo.border + 0 ]; - borderB = styles[ X.Css.AttrNo.border + 2 ]; - contentPlus = 0; - switch( box ){ - case 2 : // border-box - contentPlus = borderT + borderB; - case 1 : // padding-box - contentPlus += paddingT + paddingB; - // case 0 : // content-box - }; - if( !style.constraintH ){ - contentH += contentPlus; - min = styles[ X.Css.AttrNo.minHeight ]; - max = styles[ X.Css.AttrNo.maxHeight ]; - if( contentH < min && contentPlus < min ){ - this.contentHeight = min - contentPlus; - } else - if( max < contentH && contentPlus < max ){ - this.contentHeight = max - contentPlus; - }; + this.contentL = borderL + paddingL; + this.contentR = borderR + paddingR; + this.boxWidth = this.contentWidth + this.contentL + this.contentR; + }; + // Height + if( this.boxHeight === X.UI.Attr.AUTO ){ + contentH = this.contentHeight; + paddingT = calc( attrs[ X.UI.Attr.Support.padding.No + 0 ], contentH );// paddingTRBL の % 指定は 最大幅に対して TB でも幅に対して + paddingB = calc( attrs[ X.UI.Attr.Support.padding.No + 2 ], contentH ); + borderT = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 0 ], contentH ); + borderB = calc( attrs[ X.UI.Attr.Support.borderWidth.No + 2 ], contentH ); + contentPlus = 0; + switch( box ){ + case 3 : // border-box + contentPlus = borderT + borderB; + case 2 : // padding-box + contentPlus += paddingT + paddingB; + // case 1 : // content-box + }; + if( !this.constraintH ){ + contentH += contentPlus; + min = calc( attrs[ X.UI.Attr.Support.minHeight.No ], contentH ); + max = calc( attrs[ X.UI.Attr.Support.maxHeight.No ], contentH ); + if( contentH < min && contentPlus < min ){ + this.contentHeight = min - contentPlus; + } else + if( max < contentH && contentPlus < max ){ + this.contentHeight = max - contentPlus; }; - this.contentT = borderT + paddingT; - this.contentB = borderB + paddingB; - this.boxHeight = this.contentHeight + this.contentT + this.contentB; - }; - } else { - this.boxWidth = this.contentWidth; - this.boxHeight = this.contentHeight; - delete this.minContentWidth; - delete this.maxContentWidth; - delete this.minContentHeight; - delete this.maxContentHeight; - delete this.contentL; - delete this.contentT; - delete this.contentR; - delete this.contentB; + }; + this.contentT = borderT + paddingT; + this.contentB = borderB + paddingB; + this.boxHeight = this.contentHeight + this.contentT + this.contentB; + }; + }, + + capcher : function( x, y ){ + if( this.pointerDisabled ) return false; + + x -= this.boxX; + y -= this.boxY; + + if( 0 <= x && x < this.boxWidth && 0 <= y && y < this.boxHeight ){ + + !this.hovering && ( this.rootData.hoverList[ this.rootData.hoverList.length ] = this ); + this.rootData.targetNodeData = this; + return true; }; }, + listen : function( type, arg1, arg2, arg3 ){ var root, events, counter; if( X.UI.Event._START_POINTER <= type && type <= X.UI.Event._END_POINTER ){ @@ -556,13 +768,14 @@ var _AbstractUINode = X.EventDispatcher.inherits( this.gesture.listen( type ); }; } else { + console.log( type ) root = this.rootData; counter = root.eventCounter; if( counter[ type ] ){ ++counter[ type ]; } else { counter[ type ] = 1; - root.elmMouseCatch.listen( X.UI.Event.IdToName[ type ], eventRellay ); + root.xnodeInteractiveLayer.listen( X.UI.Event.IdToName[ type ], eventRellay ); }; }; }; @@ -594,7 +807,7 @@ var _AbstractUINode = X.EventDispatcher.inherits( if( !counter[ type ] ) return this; --counter[ type ]; if( counter[ type ] === 0 ){ - X.Dom.Event.remove( root.elmMouseCatch, X.UI.Event.IdToName[ type ], eventRellay ); + root.xnodeInteractiveLayer.unlisten( X.UI.Event.IdToName[ type ], eventRellay ); delete counter[ type ]; }; }; @@ -621,55 +834,82 @@ var _AbstractUINode = X.EventDispatcher.inherits( } ); +_AbstractUINode.calcValue = function( styleValue, srcValue ){ + /* + * String の場合は必ず % + */ + if( X.Type.isString( styleValue ) ){ + return srcValue * parseFloat( styleValue ) / 100; + }; + if( !X.Type.isNumber( styleValue ) ) return 0; + return styleValue; +}; + _AbstractUINode.finalValue = function( styleValue, styleMin, styleMax, srcValue ){ var calc = _AbstractUINode.calcValue, v = calc( styleValue, srcValue ), - min = calc( styleMin, srcValue ), - max = calc( styleMax, srcValue ); - if( v < min ) return min; - if( max < v ) return max; - return v; -}; -_AbstractUINode.calcValue = function( styleValue, srcValue ){ - switch( styleValue ){ - case 0 : - return 0; - case AUTO : - return AUTO; - case FULL : - return srcValue; // 100% - }; - if( 1 <= styleValue ) return styleValue; // legth - if( -1 < styleValue ) return FLOOR( srcValue * styleValue ); // % - return styleValue; // - length + min = calc( styleMin, srcValue ), + max = calc( styleMax, srcValue ); + return v <= min ? min : max <= v ? max : v; }; -_AbstractUINode.advancedCalcValue = function( styleValue, srcValue ){ - switch( styleValue ){ - case 0 : - return 0; - case AUTO : - return srcValue; - case FULL : - //throw new Error( 'advancedCalcValue FULL' ); - // return ; // 100% +_AbstractUINode.ceil = function( v ){ + if( 0 <= v ){ + return ( v * 10 + 0.999 | 0 ) / 10; }; - if( 1 <= styleValue ) return styleValue; - if( -1 < styleValue ) return FLOOR( ( srcValue / ( 1 - styleValue ) ) * styleValue ); // % - return styleValue; // - length + return ( -v * 10 + 0.999 | 0 ) / -10; }; - var AbstractUINode = X.Class.create( 'AbstractUINode', X.Class.ABSTRACT | X.Class.SUPER_ACCESS, { - style : null, parent : function(){ return X.Class._getPrivate( this ).parent; }, root : function(){ return X.Class._getPrivate( this ).root; }, + + /* + * unverifiedAttrs に全ての指定を控える + * サポートされていない場合は無視される.親のレイアウトによって変わる + */ + attr : function( nameOrObject, valueOrUnit ){ + var p = X.Class._getPrivate( this ), + layout, k, def, attrs, v; + if( nameOrObject && X.Type.isObject( nameOrObject ) ){ + // setter + layout = p.parentData && p.parentData.layout.overrideAttrsForChild; // root には parent がない + for( k in nameOrObject ){ + // 親のレイアウトマネージャの許可しない + if( layout && !layout[ k ] ){ + continue; + }; + if( def = p.supportAttrs[ k ] ){ + p.setAttr( k, def, nameOrObject[ k ] ); + }; + }; + } else + if( X.Type.isString( nameOrObject ) ){ + if( valueOrUnit !== undefined ){ + if( 'em,%'.indexOf( valueOrUnit ) === -1 ){ + // setter + p.setAttr( nameOrObject, valueOrUnit ); + } else { + // getter with unit + return p.getAttrWithUnit( nameOrObject, valueOrUnit ); + }; + }; + // getter + if( attrs = ( p.attrObject || p.attrClass.prototype || X.UI.AttrClass ) ){ + def = p.supportAttrs[ nameOrObject ]; + return def && attrs[ def.No ]; + }; + return v; + }; + return this; + }, + listen : function( type, arg1, arg2, arg3 ){ X.Class._getPrivate( this ).listen( type, arg1, arg2, arg3 ); return this; @@ -682,15 +922,16 @@ var AbstractUINode = X.Class.create( X.Class._getPrivate( this ).unlisten( type, arg1, arg2, arg3 ); return this; }, + dispatch : function( e ){ + return X.Class._getPrivate( this ).dispatch( e ); + }, + getNextNode : function(){ }, getPrevNode : function(){ }, - dispatch : function( e ){ - return X.Class._getPrivate( this ).dispatch( e ); - }, nodeIndex : function( v ){ var data = X.Class._getPrivate( this ); if( typeof v === 'number' ){ @@ -702,20 +943,13 @@ var AbstractUINode = X.Class.create( displayIndex : function(){ }, - // ちゃんとやれば不要! - mesure : function(){ - var data = X.Class._getPrivate( this ); - data.mesure(); - 4 <= data.phase && data.rootData.reserveCalc(); - return this; - }, getX : function(){ // dirty の場合、rootData.calculate - return X.Class._getPrivate( this ).x; + return X.Class._getPrivate( this ).boxX; }, getY : function(){ // dirty の場合、rootData.calculate - return X.Class._getPrivate( this ).y; + return X.Class._getPrivate( this ).boxY; }, getAbsoluteX : function(){ // dirty の場合、rootData.calculate @@ -727,11 +961,11 @@ var AbstractUINode = X.Class.create( }, getWidth : function(){ // dirty の場合、rootData.calculate - return X.Class._getPrivate( this ).w; + return X.Class._getPrivate( this ).boxWidth; }, getHeight : function(){ // dirty の場合、rootData.calculate - return X.Class._getPrivate( this ).h; + return X.Class._getPrivate( this ).boxHeight; }, scrollTo : function( x, y ){ X.Class._getPrivate( this ).scrollTo( x, y ); @@ -751,4 +985,5 @@ var AbstractUINode = X.Class.create( return X.Class._getPrivate( this ).cursor( v ); } } -); \ No newline at end of file +); +