OSDN Git Service

Version 0.6.191, fix X.UI.ScrollBox & X.UI.Gesture.
[pettanr/clientJs.git] / 0.6.x / js / 20_ui / 20_Root.js
1 var X_UI_rootData  = null,
2         XUI_xnodeIneraction = null,
3         XUI_interactionBusy = false;
4
5 function X_UI_eventRellay( e ){
6         var font    = X_ViewPort_baseFontSize,
7                 x       = e.pageX / font, // clientX は iOS4- で通らない?
8                 y       = e.pageY / font,
9                 type    = XUI_Event.NameToID[ e.type ],
10                 i       = 0,
11                 data    = X_UI_rootData,
12                 sysOnly = false,
13                 ret     = X_CALLBACK_NONE,
14                 list, parent, _ret, eventIn, eventOut;
15
16         // mouseup で alert を出すと mouseleave が発生、ということでイベント中のイベント発火を禁止
17         if( !data || XUI_interactionBusy ) return ret;
18         XUI_interactionBusy = true;
19         
20         if( type !== XUI_Event._POINTER_MOVE ){
21                 console.log( data.xnode.className() + '>' + e.type + ' ' + type + ' x:' + x + ', y:' + y );
22                 //console.dir( data )
23                 //data !== X_UI_rootData && console.log( ( data.xnode[ 'className' ]() + data.xnode[ 'text' ]() ).substr( 0, 15 ) );
24         };
25         
26         e.type = type;
27
28         // TODO capture は pointer 毎に!
29
30         
31         list = X_UI_rootData.hoverList;
32         ( X_UI_rootData.targetNodeData = X_UI_rootData ).capcher( x, y );
33         data = X_UI_rootData.targetNodeData;
34
35
36
37         
38         
39         while( true ){
40                 _ret = data[ 'dispatch' ]( e, sysOnly );
41                 ret |= _ret;
42                 if( X_UI_rootData !== data && _ret & X_CALLBACK_CAPTURE_POINTER ){
43                         X_UI_rootData.monopolyNodeData = data;
44                         break;
45                 };
46                 if( X_UI_rootData.monopolyNodeData === data ) X_UI_rootData.monopolyNodeData = null;
47                 if( type < XUI_Event._START_BUBLEUP || ret & X_CALLBACK_STOP_PROPAGATION ){
48                         break;
49                 };
50                 if( !data.parentData ) break;
51                 data = data.parentData;
52                 if( type !== XUI_Event._POINTER_MOVE ){
53                         //data !== X_UI_rootData && console.log( ( data.xnode[ 'className' ]() + data.xnode[ 'text' ]() ).substr( 0, 15 ) );
54                 };
55         };
56         if( data !== X_UI_rootData ) ret |= X_UI_rootData[ 'dispatch' ]( e, sysOnly );
57
58         eventOut = X_Object_copy( e );
59         eventOut.type = XUI_Event.POINTER_OUT;
60
61         eventIn = X_Object_copy( e );
62         eventIn.type = XUI_Event.POINTER_IN;
63         
64         for( i = list.length; i; ){
65                 parent = data = list[ --i ];
66                 while( parent.parentData && parent === parent.parentData.hitChildData ){
67                         parent = parent.parentData;
68                 };
69                 if( parent !== X_UI_rootData ){
70                         data.hoverClassName && data.xnode[ 'removeClass' ]( data.hoverClassName );
71                         data[ '_listeners' ] && data[ '_listeners' ][ XUI_Event.POINTER_OUT ] && data[ 'dispatch' ]( eventOut, false ); // new Event
72                         delete data.hovering;
73                         list.splice( i, 1 );
74                         continue;
75                 };
76                 if( !data.hovering ){
77                         data.hoverClassName && data.xnode.addClassName( data.hoverClassName );
78                         data[ '_listeners' ] && data[ '_listeners' ][ XUI_Event.POINTER_IN ] && data[ 'dispatch' ]( eventIn, true ); // new Event
79                         data.hovering = true;
80                 };
81         };
82         XUI_interactionBusy = false;
83         return ret | X_CALLBACK_PREVENT_DEFAULT;
84 };
85
86 function X_UI_onMouseOut( e ){
87         var list = X_UI_rootData.hoverList,
88                 i = list.length;
89         console.log( 'pointer out!!' + e.type + i + ' ' + e.pointerType );
90
91         e = X_Object_copy( e );
92         e.type = XUI_Event.POINTER_OUT;
93         
94         for( ; i; ){
95                 data = list[ --i ];
96                 //console.log( data.xnode.className() );
97                 data.hoverClassName && data.xnode[ 'removeClass' ]( data.hoverClassName );
98                 data[ '_listeners' ] && data[ '_listeners' ][ XUI_Event.POINTER_OUT ] && data[ 'dispatch' ]( e, false ); // new Event
99                 delete data.hovering;
100         };
101         list.length = 0;
102 };
103
104 /*
105  * body が存在したら要素を作成、css も指定
106  * 背景画像を読み終える onload で活動開始
107  */
108
109 var XUI_Root = XUI_Box.inherits(
110         '_Root',
111         X_Class.FINAL,
112         {
113                 layout                : XUI_Layout_Canvas,
114                 
115                 calcReserved          : false,
116                 hoverList             : null,
117                 targetNodeData        : null,
118                 monopolyNodeData      : null,
119                 
120                 xnodeInteractiveLayer : null,
121                 eventCounter          : null,
122                 cursorStyle           : null,
123                 
124                 Constructor : function( user, layout, args ){
125                         this[ 'Super' ]( user, layout, args );
126                         
127                         if( X_ViewPort_readyState === X_EVENT_XDOM_READY ){
128                                 X_Timer_once( 0, this, this.start );
129                         } else {
130                                 X_ViewPort[ 'listenOnce' ]( X_EVENT_XDOM_READY, this, this.start );
131                         };
132                         
133                         this.hoverList    = [];
134                         this.eventCounter = {};
135                         
136                         X_UI_rootData = this;
137                 },
138                 
139                 start : function(){
140                         // hover や rollover rollout のための move イベントの追加
141                         // TODO この切り替えを ViewPort へ
142                         XUI_xnodeIneraction = ( X_UA[ 'IE' ] < 9 ? X_ViewPort_document : X_UA[ 'Opera' ] < 8 ? X_Node_body : X_ViewPort );      
143                         
144                         this.initialize( this.User, this, null, null );
145                         X_Timer_once( 0, this, this.addToView );
146                 },
147                 addToView : function(){
148                         var     counter = this.eventCounter;
149                         
150                         // this.xnodeInteractiveLayer の前に追加する!
151
152                         this.addToParent( X_Node_body );
153                         
154                         this.xnodeInteractiveLayer = X_Node_body.create( 'div', {
155                                 'class'      : 'mouse-operation-catcher',
156                                 unselectable : 'on'
157                         } );
158                         
159                         X_Node_body[ 'listen' ]( 'pointerleave', this, X_UI_onMouseOut );
160                         
161                         XUI_xnodeIneraction[ 'listen' ]( 'pointermove', X_UI_eventRellay );
162                         if( counter[ XUI_Event._POINTER_MOVE ] ){
163                                 ++counter[ XUI_Event._POINTER_MOVE ];
164                         } else {
165                                 counter[ XUI_Event._POINTER_MOVE ] = 1;
166                         };
167
168                         X_Timer_once( 0, this, this.afterAddToView );
169                 },
170                 afterAddToView : function(){
171                         this.xnode[ 'className' ]( 'Root' );
172                         
173                         this.creationComplete();
174                         X_Timer_once( 0, this, XUI_Root_do1stCalculate );
175                 },
176                 
177                 reserveCalc : function(){
178                         if( this.calcReserved === false ){
179                                 this.calcReserved = true;
180                                 X_Timer_once( 0, this, this.calculate );
181                         };
182                 },
183                 calculate : function( e ){
184                         var cancelable = !e || ( e.type !== X_EVENT_VIEW_RESIZED && e.type !== X_EVENT_BASE_FONT_RESIZED ),
185                                 size, font, w, h;
186                         
187                         if( ( this[ 'dispatch' ]( { type : XUI_Event.LAYOUT_BEFORE, 'cancelable' : cancelable } ) & X_CALLBACK_PREVENT_DEFAULT ) && cancelable ){
188                                 return X_CALLBACK_NONE;
189                         };
190                         
191                         size = X[ 'ViewPort' ][ 'getSize' ]();
192                         font = X[ 'ViewPort' ][ 'getBaseFontSize' ]();
193                         this.layout.calculate( this, false, 0, 0, size[ 0 ] / font, size[ 1 ] / font );
194                         this.updateLayout();
195                         
196                         this.calcReserved = false;
197                         
198                         X_ViewPort[ 'listenOnce' ]( X_EVENT_AFTER_UPDATE, this, XUI_Root_onViewUpdate );
199                         
200                         return X_CALLBACK_NONE;
201                 },
202                 
203                 updateCoursor : function( cursor ){
204                         
205                 },
206                 
207                 _remove : function(){
208                         X_EventDispatcher_unlistenAll( this.xnodeInteractiveLayer );
209                         _Box.prototype._remove.call( this );
210                 }
211         }
212 );
213
214 function XUI_Root_do1stCalculate(){
215         this.calculate();
216         this.phase = 4;
217         X_ViewPort
218                 [ 'listen' ]( X_EVENT_VIEW_RESIZED, this, this.calculate )
219                 [ 'listen' ]( X_EVENT_BASE_FONT_RESIZED, this, this.calculate );
220 };
221
222 function XUI_Root_onViewUpdate( e ){
223         this[ 'dispatch' ]( XUI_Event.LAYOUT_COMPLETE );
224 };
225
226 //var XUI_Root;
227 // TODO singleton
228 X.UI.Root = X.UI.Box.inherits(
229         'Root',
230         X_Class.NONE,
231         {
232                 Constructor : function(){
233                         var supports;
234                         
235                         //if( !XUI_Root ){
236                                 supports = XUI_Attr_createAttrDef( XUI_Box.prototype.usableAttrs, XUI_Layout_Canvas.overrideAttrsForSelf );
237                                 
238                                 XUI_Root.prototype.layout       = XUI_Layout_Canvas;
239                                 XUI_Root.prototype.usableAttrs = supports;
240                                 XUI_Root.prototype.attrClass    = XUI_Attr_preset( XUI_Box.prototype.attrClass, supports, {
241                                                                         width  : '100%',
242                                                                         height : '100%'
243                                                                 } );
244                         //};
245                         X_Pair_create( this, XUI_Root( this, XUI_Layout_Canvas, arguments ) );
246                 }
247         });
248 /*
249 X.UI.Root = X.UI.Box.presets(
250         'Root',
251         XUI_Root,
252         {
253                 width  : '100%',
254                 height : '100%'
255         }
256 );*/
257