2 var XUI_Layout_Canvas = X[ 'UI' ][ 'Layout' ][ 'Canvas' ] = XUI_createLayout( {
\r
3 name : 'CanvasLayout',
\r
5 overrideAttrsForSelf : {
\r
7 role : [ 0, XUI_Dirty.CLEAN, XUI_Attr_USER.UINODE, XUI_Attr_Type.INIT_ONLY | XUI_Attr_Type.LIST, 'none,chrome,container' ],
\r
9 width : [ '100%', XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT ],
\r
10 maxWidth : [ XUI_Attr_AUTO, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT ],
\r
11 height : [ 0, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT ],
\r
12 maxHeight : [ XUI_Attr_AUTO, XUI_Dirty.LAYOUT, XUI_Attr_USER.LAYOUT, XUI_Attr_Type.LENGTH | XUI_Attr_Type.PERCENT ]
\r
15 overrideAttrsForChild : {
\r
22 calculate : function( data, isNeedsDetection, x, y, w, h ){
\r
23 var uinodes, l, i, _x, _y, _w, _h, node;
\r
25 data.preMesure( w, h );
\r
27 console.log( w + ' > ' + data.boxWidth );
\r
29 // data.boxWidth と data.boxHeight のどちらかでも Infinity
\r
30 if( isNeedsDetection && data.boxWidth + data.boxHeight === XUI_Attr_AUTO ) return false;
\r
34 _w = data.contentWidth;
\r
35 _h = data.contentHeight;
\r
37 if( ( uinodes = data.uinodes ) && ( l = uinodes.length ) ){
\r
38 console.log( _w + ' x ' + _h + ' l:' + l );
\r
39 for( i = 0; i < l; ++i ){
\r
40 node = uinodes[ i ];
\r
41 node.calculate( false, _x, _y, _w, _h );
\r
44 if( data.contentHeight === XUI_Attr_AUTO ){
\r
45 data.contentHeight = data.contentHeightMin !== XUI_Attr_AUTO ? data.contentHeightMin : 0;
\r
50 if( !isNeedsDetection ){
\r
59 var XUI_Box = XUI_AbstractUINode.inherits(
\r
63 usableAttrs : XUI_Attr_createAttrDef( XUI_AbstractUINode.prototype.usableAttrs, XUI_Layout_Canvas.overrideAttrsForSelf ),
\r
69 hitChildData : null,
\r
70 pointerChildren : true,
\r
73 scrollingX : 0, // TODO 現在のスクロール位置
\r
74 scrollingY : 0, // TODO
\r
76 Constructor : function( user, layout, args ){
\r
78 l = args && args.length,
\r
80 uinodes, arg, _data, attrs, attrDef, p;
\r
82 //if( !args.length ) args = [ args ];
\r
84 if( !user[ 'instanceOf' ]( X.UI.Box ) ){
\r
85 //throw new Error( 'Box を継承したインスタンスだけが _Box のオーナーになれます' );
\r
90 // TODO デフォルトの attr 指定の中から XNODE に指定するものを集めて適用。
\r
91 this.xnode = X_Doc_create( 'div' );
\r
93 // すでに定義されていればそちらを採用
\r
94 // usableAttrs や attrClass が、layout を元に上書きされているため
\r
95 this.layout = this.layout || layout;
\r
97 for( ; i < l; ++i ){
\r
99 if( arg[ 'instanceOf' ] && arg[ 'instanceOf' ]( X.UI.AbstractUINode ) ){
\r
100 _data = X_Pair_get( arg );
\r
101 if( !uinodes ) this.uinodes = uinodes = [];
\r
102 uinodes[ ++j ] = _data;
\r
103 if( _data.parent ){
\r
104 //throw new Error( 'インスタンスはすでに親に追加されています ' + arg );
\r
107 if( X_Type_isObject( arg ) ){
\r
109 attrs = X_Class_override( attrs, arg );
\r
114 //throw new Error( 'AbstractUINode を継承したインスタンスを渡してください ' + arg );
\r
119 if( X_EMPTY_OBJECT[ p ] ) continue;
\r
120 ( attrDef = this.usableAttrs[ p ] ) && this.setAttr( p, attrDef, attrs[ p ] );
\r
124 initialize : function( root, rootData, parent, parentData ){
\r
125 var uinodes = this.uinodes,
\r
126 i = uinodes && uinodes.length;
\r
128 this.rootData = rootData;
\r
129 this.parent = parent;
\r
130 this.parentData = parentData;
\r
134 uinodes[ --i ].initialize( root, rootData, this.User, this );
\r
139 this.User[ 'dispatch' ]( { type : XUI_Event.INIT } );
\r
142 addToParent : function( parentXNode ){
\r
143 var uinodes = this.uinodes,
\r
144 l = uinodes && uinodes.length,
\r
147 parentXNode && parentXNode[ 'append' ]( this.xnode );
\r
150 for( i = 0; i < l; ++i ){
\r
151 uinodes[ i ].addToParent( this.xnode );
\r
156 this.User[ 'dispatch' ]( { type : XUI_Event.ADDED } );
\r
160 creationComplete : function(){
\r
161 var uinodes = this.uinodes,
\r
162 i = uinodes && uinodes.length;
\r
165 uinodes[ --i ].creationComplete();
\r
169 XUI_AbstractUINode.prototype.creationComplete.apply( this, arguments );
\r
172 calculate : function( isNeedsDetection, x, y, w, h ){
\r
173 var ret = this.layout.calculate( this, isNeedsDetection, x, y, w, h );
\r
178 updateLayout : function(){
\r
179 var uinodes = this.uinodes, i, l;
\r
181 if( uinodes && ( l = uinodes.length ) ){
\r
182 for( i = 0; i < l; ++i ){
\r
183 uinodes[ i ].updateLayout();
\r
186 XUI_AbstractUINode.prototype.updateLayout.call( this );
\r
189 capcher : function( x, y ){
\r
190 var uinodes, child, _x, _y, hit, i;
\r
191 if( this.pointerDisabled ) return false;
\r
192 delete this.hitChildData;
\r
195 if( this.pointerChildren && ( uinodes = this.uinodes ) && ( i = uinodes.length ) ){
\r
196 _x = x - this.scrollingX;
\r
197 _y = y - this.scrollingY;
\r
199 child = uinodes[ --i ];
\r
200 if( !child.pointerDisabled && child.boxX <= _x && _x < child.boxX + child.boxWidth && child.boxY <= _y && _y < child.boxY + child.boxHeight && child.capcher( _x, _y ) ){
\r
201 //console.log( 'hit child ' + _x + ' ' + _y + ' boxX:' + child.boxX + ' boxY:' + child.boxY );
\r
202 this.hitChildData = child;
\r
207 if( this.through ){
\r
208 this.hitChildData && !this.hovering && ( this.rootData.hoverList[ this.rootData.hoverList.length ] = this );
\r
209 return !!this.hitChildData;
\r
211 hit = 0 <= x && x < this.boxWidth && 0 <= y && y < this.boxHeight;
\r
212 ( this.hitChildData || hit ) && !this.hovering && ( this.rootData.hoverList[ this.rootData.hoverList.length ] = this );
\r
213 if( hit && this.hitChildData === null ) this.rootData.targetNodeData = this;
\r
214 return hit || !!this.hitChildData;
\r
217 addAt : function( index, _uinodes ){
\r
218 //console.log( '# AddAt ' + this.phase )
\r
219 var uinodes = this.uinodes,
\r
220 num = uinodes.length,
\r
221 p1 = 1 <= this.phase,
\r
222 p2 = 2 <= this.phase,
\r
223 p3 = 3 <= this.phase,
\r
228 //console.log( '### AddAt ' + this.phase )
\r
229 for( l = _uinodes.length; i < l; ++i ){
\r
230 data = X_Pair_get( _uinodes[ i ] );
\r
231 _p1 = p1 && data.phase < 1;
\r
232 _p2 = p2 && data.phase < 2;
\r
233 _p1 && data.initialize( this.root, this.rootData, this.User, this );
\r
235 _p2 && uinodes[ index + i ].xnode[ 'prev' ]( data.xnode );
\r
236 _p2 && data.addToParent( this.xnode );
\r
237 uinodes.splice( index + i, 0, data );
\r
239 _p2 && data.addToParent( this.xnode );
\r
240 uinodes[ uinodes.length ] = data;
\r
242 p3 && data.phase < 3 && data.creationComplete();
\r
244 4 <= this.phase && this.rootData.reserveCalc();
\r
247 remove : function( _uinodes ){
\r
248 //console.log( '# AddAt ' + this.phase )
\r
249 var uinodes = this.uinodes,
\r
250 i = _uinodes.length,
\r
253 //console.log( '### AddAt ' + this.phase )
\r
255 data = X_Pair_get( _uinodes[ --i ] );
\r
256 if( ( n = uinodes.indexOf( data ) ) !== -1 ){
\r
257 uinodes.splice( n, 1 );
\r
261 4 <= this.phase && this.rootData.reserveCalc();
\r
264 removeAt : function( from, length ){
\r
265 var uinodes = this.uinodes,
\r
266 i = uinodes.length,
\r
267 to = from + ( X_Type_isNumber( length ) && 1 <= length ? length : 1 ),
\r
270 node = uinodes[ --i ];
\r
271 if( from <= i && i < to ){
\r
272 uinodes.splice( i, 1 );
\r
276 4 <= this.phase && this.rootData.reserveCalc();
\r
279 _remove : function(){
\r
280 var uinodes = this.uinodes,
\r
281 i = uinodes.length;
\r
282 for( ; i; ){ uinodes[ --i ]._remove(); };
\r
284 switch( this.phase ){
\r
288 this.xnode[ 'remove' ]();
\r
291 delete this.rootData;
\r
292 delete this.parent;
\r
293 delete this.parentData;
\r
301 X.UI.Box = X.UI.AbstractUINode.inherits(
\r
305 Constructor : function(){
\r
306 X_Pair_create( this, XUI_Box( this, XUI_Layout_Canvas, arguments ) );
\r
309 add : function( /* node, node, node ... */ ){
\r
310 X_Pair_get( this ).addAt( this.numNodes() + 1, X_Object_cloneArray( arguments ) );
\r
313 addAt : function( index /* , node , node, node ... */ ){
\r
315 if( index < 0 ) index = 0;
\r
316 nodes = X_Object_cloneArray( arguments );
\r
317 X_Pair_get( this ).addAt( nodes.shift(), nodes );
\r
320 remove : function( /* node, node, node ... */ ){
\r
321 X_Pair_get( this )[ 'remove' ]( X_Object_cloneArray( arguments ) );
\r
324 removeAt : function( from, length ){
\r
325 X_Pair_get( this ).removeAt( from, length );
\r
328 getNodesByClass : function( klass ){
\r
330 uinodes = X_Pair_get( this ).uinodes,
\r
332 if( !uinodes || uinodes.length === 0 ) return ret;
\r
333 for( i = 0, l = uinodes.length; i < l; ++i ){
\r
334 node = uinodes[ i ].User;
\r
335 if( node[ 'instanceOf' ]( klass ) ) ret[ ret.length ] = node;
\r
339 getFirstChild : function(){
\r
340 return this.getNodeAt( 0 );
\r
342 getLastChild : function(){
\r
343 var uinodes = X_Pair_get( this ).uinodes;
\r
344 return uinodes && uinodes.length && uinodes[ uinodes.length - 1 ].User || null;
\r
346 getNodeAt : function( index ){
\r
347 if( index < 0 ) return null;
\r
348 var uinodes = X_Pair_get( this ).uinodes;
\r
349 return uinodes && uinodes[ index ].User || null;
\r
351 numNodes : function(){
\r
352 var uinodes = X_Pair_get( this ).uinodes;
\r
353 return uinodes && uinodes.length || 0;
\r
356 clone : function( opt_cloneListener ){
\r
357 var clone = XUI_AbstractUINode.prototype.clone.call( this, opt_cloneListener ),
\r
358 uinodes = X_Pair_get( this ).uinodes,
\r
360 l = uinodes && uinodes.length,
\r
363 for( ; i < l; ++i ){
\r
364 copies[ i ] = uinodes[ i ].clone( opt_cloneListener );
\r
367 return l ? clone.add.apply( clone, copies ) : clone;
\r
373 * layout が設定されている Box のサブクラスに対して、layout を指定できない.
\r
376 X.UI.Box.presets = function(){
\r
377 var args = arguments,
\r
380 shadow = X_Class_getClassDef( this ).privateClass,
\r
381 layout = shadow.prototype.layout,
\r
382 arg, attrs, supports, klass, klassDef, privateKlass, boxName;
\r
384 for( ; i < l; ++i ){
\r
386 if( !arg ) continue;
\r
387 // レイアウトの preset ができるのは layout が未定義な Box だけ
\r
388 if( !shadow.prototype.layout && arg[ 'instanceOf' ] && arg[ 'instanceOf' ]( XUI_LayoutBase ) ){
\r
391 if( ( klassDef = X_Class_getClassDef( arg ) ) && klassDef.isPrivate ){
\r
392 privateKlass = arg;
\r
393 layout = privateKlass.prototype.layout;
\r
395 if( X_Type_isObject( arg ) ){
\r
397 X_Class_override( attrs, arg, true );
\r
402 if( X_Type_isString( arg ) ){
\r
407 if( privateKlass ){
\r
409 * スーパークラスの属性定義リストをレイアウトの持つ属性定義で上書きした新しい属性定義リストを作る。
\r
411 supports = XUI_Attr_createAttrDef( privateKlass.prototype.usableAttrs, layout.overrideAttrsForSelf );
\r
413 klass = this.inherits( privateKlass );
\r
414 privateKlass.prototype.usableAttrs = supports;
\r
415 privateKlass.prototype.attrClass = XUI_Attr_preset( privateKlass.prototype.attrClass, supports, attrs );
\r
417 supports = XUI_Attr_createAttrDef( shadow.prototype.usableAttrs, layout.overrideAttrsForSelf );
\r
419 klass = this.inherits(
\r
424 usableAttrs : supports,
\r
425 attrClass : XUI_Attr_preset( shadow.prototype.attrClass, supports, attrs )
\r
431 klass.presets = this.presets || X.UI.Box.presets;
\r