1 var X_UI_rootData = null,
2 XUI_xnodeIneraction = null,
3 XUI_interactionBusy = false;
5 function X_UI_eventRellay( e ){
6 var font = X_ViewPort_baseFontSize,
7 x = e.pageX / font, // clientX は iOS4- で通らない?
9 type = XUI_Event.NameToID[ e.type ],
13 ret = X_CALLBACK_NONE,
14 list, parent, _ret, eventIn, eventOut;
16 // mouseup で alert を出すと mouseleave が発生、ということでイベント中のイベント発火を禁止
17 if( !data || XUI_interactionBusy ) return ret;
18 XUI_interactionBusy = true;
20 if( type !== XUI_Event._POINTER_MOVE ){
21 console.log( data.xnode.className() + '>' + e.type + ' ' + type + ' x:' + x + ', y:' + y );
23 //data !== X_UI_rootData && console.log( ( data.xnode[ 'className' ]() + data.xnode[ 'text' ]() ).substr( 0, 15 ) );
28 // TODO capture は pointer 毎に!
31 list = X_UI_rootData.hoverList;
32 ( X_UI_rootData.targetNodeData = X_UI_rootData ).capcher( x, y );
33 data = X_UI_rootData.targetNodeData;
40 _ret = data[ 'dispatch' ]( e, sysOnly );
42 if( X_UI_rootData !== data && _ret & X_CALLBACK_CAPTURE_POINTER ){
43 X_UI_rootData.monopolyNodeData = data;
46 if( X_UI_rootData.monopolyNodeData === data ) X_UI_rootData.monopolyNodeData = null;
47 if( type < XUI_Event._START_BUBLEUP || ret & X_CALLBACK_STOP_PROPAGATION ){
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 ) );
56 if( data !== X_UI_rootData ) ret |= X_UI_rootData[ 'dispatch' ]( e, sysOnly );
58 eventOut = X_Object_copy( e );
59 eventOut.type = XUI_Event.POINTER_OUT;
61 eventIn = X_Object_copy( e );
62 eventIn.type = XUI_Event.POINTER_IN;
64 for( i = list.length; i; ){
65 parent = data = list[ --i ];
66 while( parent.parentData && parent === parent.parentData.hitChildData ){
67 parent = parent.parentData;
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
77 data.hoverClassName && data.xnode.addClassName( data.hoverClassName );
78 data[ '_listeners' ] && data[ '_listeners' ][ XUI_Event.POINTER_IN ] && data[ 'dispatch' ]( eventIn, true ); // new Event
82 XUI_interactionBusy = false;
83 return ret | X_CALLBACK_PREVENT_DEFAULT;
86 function X_UI_onMouseOut( e ){
87 var list = X_UI_rootData.hoverList,
89 console.log( 'pointer out!!' + e.type + i + ' ' + e.pointerType );
91 e = X_Object_copy( e );
92 e.type = XUI_Event.POINTER_OUT;
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
105 * body が存在したら要素を作成、css も指定
106 * 背景画像を読み終える onload で活動開始
109 var XUI_Root = XUI_Box.inherits(
113 layout : XUI_Layout_Canvas,
115 calcReserved : false,
117 targetNodeData : null,
118 monopolyNodeData : null,
120 xnodeInteractiveLayer : null,
124 Constructor : function( user, layout, args ){
125 this[ 'Super' ]( user, layout, args );
127 if( X_ViewPort_readyState === X_EVENT_XDOM_READY ){
128 X_Timer_once( 0, this, this.start );
130 X_ViewPort[ 'listenOnce' ]( X_EVENT_XDOM_READY, this, this.start );
134 this.eventCounter = {};
136 X_UI_rootData = this;
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 );
144 this.initialize( this.User, this, null, null );
145 X_Timer_once( 0, this, this.addToView );
147 addToView : function(){
148 var counter = this.eventCounter;
150 // this.xnodeInteractiveLayer の前に追加する!
152 this.addToParent( X_Node_body );
154 this.xnodeInteractiveLayer = X_Node_body.create( 'div', {
155 'class' : 'mouse-operation-catcher',
159 X_Node_body[ 'listen' ]( 'pointerleave', this, X_UI_onMouseOut );
161 XUI_xnodeIneraction[ 'listen' ]( 'pointermove', X_UI_eventRellay );
162 if( counter[ XUI_Event._POINTER_MOVE ] ){
163 ++counter[ XUI_Event._POINTER_MOVE ];
165 counter[ XUI_Event._POINTER_MOVE ] = 1;
168 X_Timer_once( 0, this, this.afterAddToView );
170 afterAddToView : function(){
171 this.xnode[ 'className' ]( 'Root' );
173 this.creationComplete();
174 X_Timer_once( 0, this, XUI_Root_do1stCalculate );
177 reserveCalc : function(){
178 if( this.calcReserved === false ){
179 this.calcReserved = true;
180 X_Timer_once( 0, this, this.calculate );
183 calculate : function( e ){
184 var cancelable = !e || ( e.type !== X_EVENT_VIEW_RESIZED && e.type !== X_EVENT_BASE_FONT_RESIZED ),
187 if( ( this[ 'dispatch' ]( { type : XUI_Event.LAYOUT_BEFORE, 'cancelable' : cancelable } ) & X_CALLBACK_PREVENT_DEFAULT ) && cancelable ){
188 return X_CALLBACK_NONE;
191 size = X[ 'ViewPort' ][ 'getSize' ]();
192 font = X[ 'ViewPort' ][ 'getBaseFontSize' ]();
193 this.layout.calculate( this, false, 0, 0, size[ 0 ] / font, size[ 1 ] / font );
196 this.calcReserved = false;
198 X_ViewPort[ 'listenOnce' ]( X_EVENT_AFTER_UPDATE, this, XUI_Root_onViewUpdate );
200 return X_CALLBACK_NONE;
203 updateCoursor : function( cursor ){
207 _remove : function(){
208 X_EventDispatcher_unlistenAll( this.xnodeInteractiveLayer );
209 _Box.prototype._remove.call( this );
214 function XUI_Root_do1stCalculate(){
218 [ 'listen' ]( X_EVENT_VIEW_RESIZED, this, this.calculate )
219 [ 'listen' ]( X_EVENT_BASE_FONT_RESIZED, this, this.calculate );
222 function XUI_Root_onViewUpdate( e ){
223 this[ 'dispatch' ]( XUI_Event.LAYOUT_COMPLETE );
228 X.UI.Root = X.UI.Box.inherits(
232 Constructor : function(){
236 supports = XUI_Attr_createAttrDef( XUI_Box.prototype.usableAttrs, XUI_Layout_Canvas.overrideAttrsForSelf );
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, {
245 X_Pair_create( this, XUI_Root( this, XUI_Layout_Canvas, arguments ) );
249 X.UI.Root = X.UI.Box.presets(