OSDN Git Service

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