OSDN Git Service

Version 0.6.48, fix X.UA for s60 Safari.
[pettanr/clientJs.git] / 0.6.x / js / ui / 08_Box.js
1 \r
2 X.UI.Layout.Canvas = X.UI.Layout.create( {\r
3         name : 'CanvasLayout',\r
4         \r
5         overrideAttrsForSelf : {\r
6                 selectable  : false,\r
7                 role        : [ 0, X.UI.Dirty.CLEAN, X.UI.Attr.USER.UINODE, X.UI.Attr.Type.INIT_ONLY | X.UI.Attr.Type.LIST, 'none,chrome,container' ],\r
8                 \r
9                 width       : [ '100%',         X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT ],\r
10                 maxWidth    : [ X.UI.Attr.AUTO, X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT ],\r
11                 height      : [ 0,              X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT ],\r
12                 maxHeight   : [ X.UI.Attr.AUTO, X.UI.Dirty.LAYOUT, X.UI.Attr.USER.LAYOUT, X.UI.Attr.Type.LENGTH | X.UI.Attr.Type.PERCENT ]\r
13         },\r
14         \r
15         overrideAttrsForChild : {\r
16                 left   : true,\r
17                 top    : true,\r
18                 bottom : true,\r
19                 right  : true\r
20         },\r
21         \r
22         calculate : function( data, isNeedsDetection, x, y, w, h ){\r
23                 var uinodes, l, i, _x, _y, _w, _h, node;\r
24 \r
25                 data.preMesure( w, h );\r
26                 \r
27                 if( isNeedsDetection && ( data.boxWidth === X.UI.Attr.AUTO || data.boxHeight === X.UI.Attr.AUTO ) ) return;\r
28                 \r
29                 _x = data.contentL;\r
30                 _y = data.contentT;\r
31                 _w = data.contentWidth;\r
32                 _h = data.contentHeight;\r
33 \r
34                 if( ( uinodes = data.uinodes ) && ( l = uinodes.length ) ){\r
35                         for( i = 0; i < l; ++i ){\r
36                                 node = uinodes[ i ];\r
37                                 node.calculate( false, _x, _y, _w, _h );        \r
38                         };\r
39                 } else\r
40                 if( data.contentHeight === X.UI.Attr.AUTO ){\r
41                         data.contentHeight = data.minContentHeight !== X.UI.Attr.AUTO ? data.minContentHeight : 0;\r
42                 };\r
43                 \r
44                 data.postMesure();\r
45                 data.updateLayout( x, y );\r
46         }\r
47 });\r
48 \r
49 \r
50 var _Box = _AbstractUINode.inherits(\r
51         '_Box',\r
52         X.Class.PRIVATE_DATA | X.Class.SUPER_ACCESS, // 現状 super 指定がないとconstructor未定擬時に親のconstructor が使われない\r
53         {\r
54                 layout          : null,\r
55                 uinodes         : null,\r
56                 xnodes          : null,\r
57                 \r
58                 hitChildData    : null,\r
59                 pointerChildren : true,\r
60                 through         : false,\r
61 \r
62                 Constructor : function( layout, args ){\r
63                         var i = 0,\r
64                                 l = args.length,\r
65                                 j = -1,\r
66                                 uinodes, arg, _data, attrs, support;\r
67                         \r
68                         if( !this.User.instanceOf( Box ) ){\r
69                                 //throw new Error( 'Box を継承したインスタンスだけが _Box のオーナーになれます' );\r
70                         };                      \r
71                         \r
72                         this.xnode  = X.Dom.Node.create( 'div' );\r
73                         \r
74                         // すでに定義されていればそちらを採用\r
75                         // supportAttrs や attrClass が、layout を元に上書きされているため\r
76                         this.layout = this.layout || layout;\r
77                         \r
78                         for( ; i < l; ++i ){\r
79                                 arg = args[ i ];\r
80                                 if( arg.instanceOf && arg.instanceOf( AbstractUINode ) ){\r
81                                         _data = X.Class._getPrivate( arg );\r
82                                         if( !uinodes ) this.uinodes = uinodes = [];\r
83                                         uinodes[ ++j ] = _data;\r
84                                         if( _data.parent ){\r
85                                                 //throw new Error( 'インスタンスはすでに親に追加されています ' + arg );\r
86                                         };\r
87                                 } else\r
88                                 if( arg.instanceOf && arg.instanceOf( X.UI.Layout.Base ) ){\r
89                                         //this.layout = arg;\r
90                                 } else\r
91                                 if( X.Type.isObject( arg ) ){\r
92                                         if( attrs ){\r
93                                                 attrs = X.Class._override( attrs, arg );\r
94                                         } else {\r
95                                                 attrs = arg;\r
96                                         };\r
97                                 } else {\r
98                                         //throw new Error( 'AbstractUINode を継承したインスタンスを渡してください ' + arg );\r
99                                 };\r
100                         };\r
101                         \r
102                         for( p in attrs ){\r
103                                 ( support = this.supportAttrs[ p ] ) && this.setAttr( p, support, attrs[ p ] );\r
104                         };\r
105                 },\r
106         /* Rellay */\r
107                 initialize : function( root, rootData, parent, parentData ){\r
108                         var uinodes = this.uinodes,\r
109                                 i       = uinodes && uinodes.length;\r
110                         this.root       = root;\r
111                         this.rootData   = rootData;\r
112                         this.hoverList  = rootData.hoverList;\r
113                         this.parent     = parent;\r
114                         this.parentData = parentData;\r
115                         //this.xnode      = X.Dom.Node.create( 'div' );\r
116                         \r
117                         if( i ){\r
118                                 for( ; i; ){\r
119                                         uinodes[ --i ].initialize( root, rootData, this.User, this );\r
120                                 };                              \r
121                         };\r
122                         \r
123                         this.phase = 1;\r
124                         this.User.dispatch( { type : X.UI.Event.INIT } );\r
125                 },\r
126                 \r
127                 addToParent : function( parentXNode ){\r
128                         var uinodes = this.uinodes,\r
129                                 l       = uinodes && uinodes.length,\r
130                                 i;\r
131 \r
132                         parentXNode && parentXNode.append( this.xnode );\r
133                         \r
134                         if( l ){\r
135                                 for( i = 0; i < l; ++i ){\r
136                                         uinodes[ i ].addToParent( this.xnode );\r
137                                 };\r
138                         };\r
139                         \r
140                         this.phase = 2;\r
141                         this.User.dispatch( { type : X.UI.Event.ADDED } );\r
142                 },\r
143                 \r
144         /* Rellay */\r
145                 creationComplete : function(){\r
146                         var uinodes = this.uinodes,\r
147                                 i       = uinodes && uinodes.length;\r
148                         if( i ){\r
149                                 for( ; i; ){\r
150                                         uinodes[ --i ].creationComplete();\r
151                                 };                              \r
152                         };\r
153                         \r
154                         this.phase = 3;\r
155                         this.User.dispatch( { type : X.UI.Event.CREATION_COMPLETE } );\r
156                 },\r
157                 \r
158                 calculate : function( isNeedsDetection, x, y, w, h ){\r
159                         this.layout.calculate( this, isNeedsDetection, x, y, w, h );                    \r
160                         this.phase = 4;\r
161                 },\r
162                 \r
163                 capcher : function( x, y ){\r
164                         var uinodes, child, _x, _y, hit, i;\r
165                         if( this.pointerDisabled ) return false;\r
166                         delete this.hitChildData;\r
167                         x -= this.x;\r
168                         y -= this.y;\r
169                         if( this.pointerChildren && ( uinodes = this.uinodes ) ){\r
170                                 _x = x - this.scrollingX;\r
171                                 _y = y - this.scrollingY;\r
172                                 for( i = uinodes.length; i; ){\r
173                                         child = uinodes[ --i ];\r
174                                         if( !child.pointerDisabled && child.l <= _x && _x < child.r && child.t <= _y && _y < child.b && child.capcher( _x, _y ) ){\r
175                                                 this.hitChildData = child;\r
176                                                 break;\r
177                                         };\r
178                                 };\r
179                         };\r
180                         if( this.through ){\r
181                                 this.hitChildData && !this.hovering && ( this.hoverList[ this.hoverList.length ] = this );\r
182                                 return !!this.hitChildData;\r
183                         };\r
184                         hit = 0 <= x && x < this.w && 0 <= y && y < this.h;\r
185                         ( this.hitChildData || hit ) && !this.hovering && ( this.hoverList[ this.hoverList.length ] = this );\r
186                         if( hit && this.hitChildData === null ) this.rootData.targetNodeData = this;\r
187                         return hit || !!this.hitChildData;\r
188                 },\r
189                 \r
190                 addAt : function( index, _uinodes ){\r
191                         //console.log( '# AddAt ' + this.phase )\r
192                         var uinodes = this.uinodes,\r
193                                 num     = uinodes.length,\r
194                                 p1      = 1 <= this.phase,\r
195                                 p2      = 2 <= this.phase,\r
196                                 p3      = 3 <= this.phase,\r
197                                 i       = 0,\r
198                                 _p1, _p2,\r
199                                 l, data;\r
200 \r
201                         //console.log( '### AddAt ' + this.phase )\r
202                         for( l = _uinodes.length; i < l; ++i ){\r
203                                 data = X.Class._getPrivate( _uinodes[ i ] );\r
204                                 _p1  = p1 && data.phase < 1;\r
205                                 _p2  = p2 && data.phase < 2;\r
206                                 _p1 && data.initialize( this.root, this.rootData, this.User, this );\r
207                                 if( index <= num ){\r
208                                         // _p2 && this.xnode.insertBefore( data.xnode, uinodes[ index + i ].xnode );\r
209                                         _p2 && uinodes[ index + i ].xnode.before( data.xnode );\r
210                                         _p2 && data.addToParent( this.xnode );\r
211                                         uinodes.splice( index + i, 0, data );\r
212                                 } else {\r
213                                         _p2 && data.addToParent( this.xnode );\r
214                                         uinodes[ uinodes.length ] = data;       \r
215                                 };\r
216                                 //p3 && data.phase < 3 && data.afterAddition();\r
217                                 p3 && data.phase < 4 && data.creationComplete();\r
218                         };\r
219                         4 <= this.phase && this.rootData.reserveCalc();\r
220                 },\r
221                 \r
222                 remove : function( _uinodes ){\r
223                         //console.log( '# AddAt ' + this.phase )\r
224                         var uinodes = this.uinodes,\r
225                                 i       = _uinodes.length,\r
226                                 n, data;\r
227 \r
228                         //console.log( '### AddAt ' + this.phase )\r
229                         for( ; i; ){\r
230                                 data = X.Class._getPrivate( _uinodes[ --i ] );\r
231                                 if( ( n = uinodes.indexOf( data ) ) !== -1 ){\r
232                                         uinodes.splice( n, 1 );\r
233                                         data._remove();\r
234                                 };\r
235                         };\r
236                         4 <= this.phase && this.rootData.reserveCalc();\r
237                 },\r
238                 \r
239                 removeAt : function( from, length ){\r
240                         var uinodes = this.uinodes,\r
241                                 i       = uinodes.length,\r
242                                 to      = from + ( X.Type.isNumber( length ) && 1 <= length ? length : 1 ),\r
243                                 node;\r
244                         for( ; i; ){\r
245                                 node = uinodes[ --i ];\r
246                                 if( from <= i && i < to ){\r
247                                         uinodes.splice( i, 1 );\r
248                                         node._remove();\r
249                                 };\r
250                         };\r
251                         4 <= this.phase && this.rootData.reserveCalc();\r
252                 },\r
253                 \r
254                 _remove : function(){\r
255                         var uinodes = this.uinodes,\r
256                                 i       = uinodes.length;\r
257                         for( ; i; ){ uinodes[ --i ]._remove(); };\r
258                                         \r
259                         switch( this.phase ){\r
260                                 case 4:\r
261                                 case 3:\r
262                                 case 2:\r
263                                         this.xnode.remove();\r
264                                 case 1:\r
265                                         delete this.root;\r
266                                         delete this.rootData;\r
267                                         delete this.parent;\r
268                                         delete this.parentData;\r
269                                         delete this.xnode;\r
270                         };\r
271                         delete this.phase;\r
272                 }\r
273         }\r
274 );\r
275 \r
276 var Box = AbstractUINode.inherits(\r
277         'Box',\r
278         X.Class.SUPER_ACCESS,\r
279         _Box,\r
280         {\r
281                 Constructor : function(){\r
282                         X.Class._newPrivate( this, X.UI.Layout.Canvas, arguments );\r
283                 },\r
284                 \r
285                 add : function( node /* , node, node ... */ ){\r
286                         X.Class._getPrivate( this ).addAt( this.numNodes() + 1, Array.prototype.slice.call( arguments ) );\r
287                         return this;\r
288                 },\r
289                 addAt : function( index, node /* , node, node ... */ ){\r
290                         if( index < 0 ) index = 0;\r
291                         X.Class._getPrivate( this ).addAt( arguments[ 0 ], Array.prototype.slice.call( arguments, 1 ) );\r
292                         return this;\r
293                 },\r
294                 remove : function( node /* , node, node ... */ ){\r
295                         X.Class._getPrivate( this ).remove( Array.prototype.slice.call( arguments ) );\r
296                         return this;\r
297                 },\r
298                 removeAt : function( from, length ){\r
299                         X.Class._getPrivate( this ).removeAt( from, length );\r
300                         return this;\r
301                 },\r
302                 getNodesByClass : function( klass ){\r
303                         var ret     = [],\r
304                                 uinodes = X.Class._getPrivate( this ).uinodes,\r
305                                 i, l, node;\r
306                         if( !uinodes || uinodes.length === 0 ) return ret;\r
307                         for( i = 0, l = uinodes.length; i < l; ++i ){\r
308                                 node = uinodes[ i ].User;\r
309                                 if( node.instanceOf( klass ) ) ret[ ret.length ] = node;\r
310                         };\r
311                         return ret;\r
312                 },\r
313                 getFirstChild : function(){\r
314                         return this.getNodeAt( 0 );\r
315                 },\r
316                 getLastChild : function(){\r
317                         var uinodes = X.Class._getPrivate( this ).uinodes;\r
318                         return uinodes && uinodes.length && uinodes[ uinodes.length - 1 ].User || null;\r
319                 },\r
320                 getNodeAt : function( index ){\r
321                         if( index < 0 ) return null;\r
322                         var uinodes = X.Class._getPrivate( this ).uinodes;\r
323                         return uinodes && uinodes[ index ].User || null;\r
324                 },\r
325                 numNodes : function(){\r
326                         var uinodes = X.Class._getPrivate( this ).uinodes;\r
327                         return uinodes && uinodes.length || 0;\r
328                 }\r
329         }\r
330 );\r
331 \r
332 /*\r
333  * layout が設定されている Box のサブクラスに対して、layout を指定できない.\r
334  * \r
335  */\r
336 Box.presets = function(){\r
337         var args   = arguments,\r
338                 i      = 0,\r
339                 l      = args.length,   \r
340                 shadow = X.Class._getClassDef( this ).privateClass,\r
341                 layout = shadow.prototype.layout,\r
342                 arg, attrs, supports, klass, klassDef, privateKlass, boxName;\r
343                         \r
344         for( ; i < l; ++i ){\r
345                 arg = args[ i ];\r
346                 if( !arg ) continue;\r
347                 // レイアウトの preset ができるのは layout が未定義な Box だけ\r
348                 if( !shadow.prototype.layout && arg.instanceOf && arg.instanceOf( X.UI.Layout.Base ) ){\r
349                         layout = arg;\r
350                 } else\r
351                 if( ( klassDef = X.Class._getClassDef( arg ) ) && klassDef.isPrivate ){\r
352                         privateKlass = arg;\r
353                         layout = privateKlass.prototype.layout;\r
354                 } else\r
355                 if( X.Type.isObject( arg ) ){\r
356                         if( attrs ){\r
357                                 X.Class._override( attrs, arg, true );\r
358                         } else {\r
359                                 attrs = arg;\r
360                         };\r
361                 } else\r
362                 if( X.Type.isString( arg ) ){\r
363                         boxName = arg;\r
364                 };\r
365         };\r
366         \r
367         if( privateKlass ){\r
368                 supports = X.UI.Attr.createAttrDef( privateKlass.prototype.supportAttrs, layout.overrideAttrsForSelf );\r
369                 \r
370                 klass = this.inherits( privateKlass );\r
371                 privateKlass.prototype.supportAttrs = supports,\r
372                 privateKlass.prototype.attrClass    = privateKlass.prototype.attrClass( supports, attrs );\r
373         } else {\r
374                 supports = X.UI.Attr.createAttrDef( shadow.prototype.supportAttrs, layout.overrideAttrsForSelf );\r
375                 \r
376                 klass = this.inherits(\r
377                         boxName,\r
378                         shadow.inherits(\r
379                                 {\r
380                                         layout       : layout,\r
381                                         supportAttrs : supports,\r
382                                         attrClass    : shadow.prototype.attrClass( supports, attrs )\r
383                                 }\r
384                         )\r
385                 );              \r
386         };\r
387 \r
388         klass.presets = this.presets || Box.presets;\r
389         \r
390         return klass;\r
391 };\r