@@ -35,20 +35,7 @@ qx.Class.define("osparc.ui.basic.AvatarGroup", {
3535 this . __orientation = orientation ;
3636 this . __maxVisible = Math . floor ( maxWidth / size ) - 1 ; // Reserve space for the extra avatar
3737
38- // Hover state handling
39- this . addListener ( "pointerover" , ( ) => {
40- if ( this . __collapseTimeout ) {
41- clearTimeout ( this . __collapseTimeout ) ;
42- this . __collapseTimeout = null ;
43- }
44- this . __expand ( true ) ;
45- } , this ) ;
46-
47- this . addListener ( "pointerout" , ( ) => {
48- this . __collapseTimeout = setTimeout ( ( ) => {
49- this . __expand ( false ) ;
50- } , 200 ) ; // short delay to avoid tooltip flicker collapse
51- } , this ) ;
38+ document . addEventListener ( "pointermove" , this . __onGlobalPointerMove . bind ( this ) ) ;
5239 } ,
5340
5441 members : {
@@ -57,6 +44,7 @@ qx.Class.define("osparc.ui.basic.AvatarGroup", {
5744 __users : null ,
5845 __avatars : null ,
5946 __collapseTimeout : null ,
47+ __isPointerInside : false ,
6048
6149 setUsers : function ( users ) {
6250 this . __users = users ;
@@ -123,7 +111,6 @@ qx.Class.define("osparc.ui.basic.AvatarGroup", {
123111 this . __expand ( false ) ;
124112 } ,
125113
126-
127114 __expand : function ( expand = true ) {
128115 const overlap = Math . floor ( this . __avatarSize * ( expand ? 0.1 : 0.7 ) ) ;
129116 this . __avatars . forEach ( ( avatar , index ) => {
@@ -134,5 +121,44 @@ qx.Class.define("osparc.ui.basic.AvatarGroup", {
134121 avatar . setZIndex ( index ) ;
135122 } ) ;
136123 } ,
124+
125+ __onGlobalPointerMove ( e ) {
126+ const domEl = this . getContentElement ( ) . getDomElement ( ) ;
127+ if ( ! domEl ) {
128+ return ;
129+ }
130+
131+ const rect = domEl . getBoundingClientRect ( ) ;
132+ const inside =
133+ e . clientX >= rect . left &&
134+ e . clientX <= rect . right &&
135+ e . clientY >= rect . top &&
136+ e . clientY <= rect . bottom ;
137+
138+ if ( inside ) {
139+ if ( ! this . __isPointerInside ) {
140+ this . __isPointerInside = true ;
141+ if ( this . __collapseTimeout ) {
142+ clearTimeout ( this . __collapseTimeout ) ;
143+ this . __collapseTimeout = null ;
144+ }
145+ this . __expand ( true ) ;
146+ }
147+ } else {
148+ if ( this . __isPointerInside ) {
149+ this . __isPointerInside = false ;
150+ if ( this . __collapseTimeout ) {
151+ clearTimeout ( this . __collapseTimeout ) ;
152+ }
153+ this . __collapseTimeout = setTimeout ( ( ) => {
154+ this . __expand ( false ) ;
155+ } , 200 ) ;
156+ }
157+ }
158+ }
159+ } ,
160+
161+ destruct : function ( ) {
162+ document . removeEventListener ( "pointermove" , this . __onGlobalPointerMove . bind ( this ) ) ;
137163 } ,
138164} ) ;
0 commit comments