1 var X_UI_Repeater_SUPPORT_ATTRS = {
\r
2 dataSource : [ null, XUI_Dirty.LAYOUT, XUI_Attr_USER.UINODE, XUI_Attr_Type.OBJECT ],
\r
3 itemRenderer : [ null, XUI_Dirty.LAYOUT, XUI_Attr_USER.UINODE, XUI_Attr_Type.OBJECT ]
\r
6 var XUI_Repeater = XUI_Box.inherits(
\r
10 layout : XUI_Layout_Vertical,
\r
12 dataSource : null, // Array.<object>, Array.<ItemData>
\r
14 itemRenderer : null,
\r
19 itemHeightLastEM : 0,
\r
21 Constructor : function( user, dataSource, itemRenderer, attr ){
\r
22 this.Super( user, null, [ attr ] );
\r
23 this.dataSource = dataSource;
\r
24 this.itemRenderer = itemRenderer;
\r
25 this.itemNodes = [];
\r
26 this.__item__ = X_Pair_get( itemRenderer );
\r
29 initialize : function(){
\r
30 XUI_AbstractUINode.prototype.initialize.apply( this, arguments );
\r
36 calculate : function( isNeedsDetection, x, y, allowedW, allowedH ){
\r
37 var dataSource = this[ 'dataSource' ];
\r
39 if( allowedW + allowedH === XUI_Attr_AUTO ) return false;
\r
41 this.preMesure( allowedW, allowedH );
\r
43 if( dataSource && dataSource.length ){
\r
44 this.updateItemRenderer( this.contentWidth, allowedH );
\r
46 if( this.contentHeight === XUI_Attr_AUTO ){
\r
47 this.contentHeight = this.contentHeightMin !== XUI_Attr_AUTO ? this.contentHeightMin : 0;
\r
52 if( !isNeedsDetection ){
\r
59 handleEvent : function( e ){
\r
65 updateItemRenderer : function( _w, _h ){
\r
66 var itemNodes = this.itemNodes,
\r
67 attrs = this.attrObject || this.attrClass.prototype,
\r
68 gapY = XUI_AbstractUINode_calcValue( attrs[ this.usableAttrs.gapY.No ], _w ),
\r
69 dataSource = this[ 'dataSource' ],
\r
70 renderer = this[ 'itemRenderer' ],
\r
71 l = dataSource.length,
\r
72 itemH = this.itemHeightLastEM,
\r
73 i = 0, data, node, _y = 0, last, n;
\r
75 for( ; i < l; ++i ){
\r
76 if( !( data = itemNodes[ i ] ) ){
\r
77 node = renderer.clone( true );
\r
78 this.addAt( i, [ node ] );
\r
79 data = itemNodes[ i ] = X_Pair_get( node );
\r
80 // init -> addToParent -> creationComplete
\r
82 data.setItemData( dataSource[ i ] );
\r
84 data.calculate( false, 0, _y, _w, _h );
\r
85 _y += ( itemH || data.boxHeight ) + gapY;
\r
87 // 一番最初のループ。ここでページあたりのアイテム数を計算
\r
88 if( !itemH && i === 0 ){
\r
90 this.itemHeightLastEM = itemH;
\r
91 this.itemHeightLast = itemH * X_ViewPort_baseFontSize;
\r
95 for( l = itemNodes.length; i < l; ++i ){
\r
96 // itemNodes[ i ] hide
\r
99 // TODO contentHeight は attr を無視する -> 未表示領域につくるアイテム数 GPU の有無で変わる
\r
100 this.contentHeight = l * ( itemH + gapY ) - gapY;
\r
103 onPropertyChange : function( name, newValue ){
\r
104 var itemNodes, i, l, uinode, dataList, from;
\r
107 case 'itemRenderer' :
\r
108 for( itemNodes = this.itemNodes, i = itemNodes && itemNodes.length; i; ){
\r
109 itemNodes[ --i ][ 'kill' ]();
\r
112 case 'dataSource' :
\r
113 if( itemNodes = this.itemNodes ){
\r
114 i = itemNodes.length;
\r
115 l = this[ 'dataSource' ].length;
\r
117 itemNodes[ --i ][ 'kill' ]();
\r
118 itemNodes.length = i;
\r
129 X.UI.Repeater = X.UI.Box.inherits(
\r
133 Constructor : function( dataSource, itemRenderer ){
\r
136 if( XUI_Repeater.prototype.usableAttrs === XUI_Box.prototype.usableAttrs ){
\r
137 supports = XUI_Attr_createAttrDef( XUI_Attr_Support, X_UI_Repeater_SUPPORT_ATTRS );
\r
138 XUI_Repeater.prototype.usableAttrs = supports = XUI_Attr_createAttrDef( supports, XUI_Layout_Vertical.overrideAttrsForSelf );
\r
140 XUI_Repeater.prototype.attrClass = XUI_Attr_preset( XUI_Box.prototype.attrClass, supports );
\r
144 // itemBase parent に追加されている uinode は不可
\r
145 // minHeight=300% height=auto
\r
146 X_Pair_create( this,
\r
149 dataSource, itemRenderer,
\r
151 name : 'ScrollBox-Scroller',
\r
152 role : 'container',
\r
156 minHeight : '100%',
\r
157 borderColor : 0x252527,
\r
158 borderWidth : [ 0.15, 0, 0 ],
\r
159 borderStyle : 'solid',
\r
161 bgColor : 0x444643,
\r
166 getItemDataAt : function(){
\r
170 add : function( /* node, node, node ... */ ){
\r
172 addAt : function( index /* , node , node, node ... */ ){
\r
174 remove : function( /* node, node, node ... */ ){
\r
176 removeAt : function( from, length ){
\r
178 getNodesByClass : function( klass ){
\r
180 getFirstChild : function(){
\r
182 getLastChild : function(){
\r
184 getNodeAt : function( index ){
\r
186 numNodes : function(){
\r
187 var uinodes = X_Pair_get( this ).uinodes;
\r
188 return uinodes && uinodes.length || 0;
\r