A Problem With Object_OnMouseLeaveEx(obj)

Tuesday, August 7, 2007 by ARIrish- | Discussion: DesktopX

I have a widget that autohides when you move the mouse away from it.  The code for the autohide is:

Sub Object_OnMouseLeaveEx(obj)
    If SuspendAction = False Then
        If Object.State = "AutoHide" Then
            HidePanel
        End If
    End If
End Sub

This works just fine, BUT, the object is a background, or drawer, in which there are other objects.  The problem is, when I move the mouse over one of these objects, DesktopX considers that a mouseleave and closes the drawer.  Is there some way I can apply the 'OnMouseLeave' to a group of objects rather than just one?

Thanks.
First Previous Page 1 of 2 Next Last
sViz
Reply #1 Tuesday, August 7, 2007 9:30 PM
As far as I know OnMouseLeave only applies to one object. I had the same problem and created a work around script. It's a bit crude but it worked. Here's a link to the article- LINK
ARIrish-
Reply #2 Tuesday, August 7, 2007 9:38 PM
That looks like it'll be really helpful.

Thanks a lot Much appreciated.
SirSmiley
Reply #3 Tuesday, August 7, 2007 9:48 PM
sViz, you can use the OnMouseLeaveEx(obj) just like your left click script in the DX Helper Widget.

The easiest way to accomplish what you want will be using something like this:
Code: vbscript
  1. For Each elem In desktopx.GroupObjects("myGroup")
  2. If elem.visible=True Then
  3. elem.visible=False
  4. End If
  5. Next
sViz
Reply #4 Tuesday, August 7, 2007 10:15 PM
You're right, SirS, but it still triggers OnMouseLeaveEx when I interact with the child object.

I've update my article with the For Each statement as that is much cleaner. (I've got to update my Script Helper now too!)
SirSmiley
Reply #5 Tuesday, August 7, 2007 10:24 PM
Not sure if I'm getting what you mean? With one script it shouldn't be triggered with the child object unless that object is named in the sub/function.

Now if you mean there are two separate scripts than obviously there will be an override.
Here's a simple script using default objects I just did quickly. http://www.box.net/shared/imce9jlpfj
sViz
Reply #6 Tuesday, August 7, 2007 10:45 PM
Ah, now I see what you mean. But I believe hyrax wanted the parent object to disappear OnMouseLeaveEx as well-not just the child objects. When you do that, OnMouseEnter the child objects = OnMouseLeave the parent object, and everything disappears.

Like this:

Code: vbscript
  1. Sub Object_OnMouseLeaveEx(obj)
  2. object.visible = False
  3. For Each elem In desktopx.GroupObjects("grpObj")
  4. If elem.visible=True Then
  5. elem.visible=False
  6. End If
  7. Next
  8. End Sub
  9. Sub Object_OnMouseEnterEx(obj)
  10. object.visible = True
  11. For Each elem In desktopx.GroupObjects("grpObj")
  12. If elem.visible=False Then
  13. elem.visible=True
  14. End If
  15. Next
  16. End Sub
SirSmiley
Reply #7 Tuesday, August 7, 2007 11:32 PM
There's only one glitch, if the object isn't a child object then your mouse enter event won't fire. This would be the work-a-round I would use
Code: vbscript
  1. Sub Object_OnMouseLeaveEx(obj)
  2. object.opacity= 1
  3. For Each elem In desktopx.GroupObjects("grpObj")
  4. If elem.visible=True Then
  5. elem.visible=False
  6. End If
  7. Next
  8. End Sub
  9. Sub Object_OnMouseEnterEx(obj)
  10. object.opacity= 100
  11. For Each elem In desktopx.GroupObjects("grpObj")
  12. If elem.visible=False Then
  13. elem.visible=True
  14. End If
  15. Next
  16. End Sub
sViz
Reply #8 Wednesday, August 8, 2007 12:30 AM
That works.  
Skarny
Reply #9 Saturday, September 15, 2007 7:23 PM
I have a similar 'drawer'/'container' set up in a lot of my objects.

The Ex functions receive events from all children of the parent containing it.
The obj variable contains the object reference which 'fired' the event.
So if you mouse_leaved a child called 'Child1' then obj.Name would be equal to "Child1"

I use this to tell the Ex function which objects to respond to.
The below uses 'Select obj.Name' to hide the parent object only for when the mouse leaves the parent object.

Code: vbscript
  1. Sub Object_OnMouseLeaveEx(obj)
  2. Select Case obj.Name
  3. Case Object.Name
  4. Object.Visible = False
  5. Case "child1"
  6. MsgBox("Your mouse has left child1")
  7. Case Else
  8. MsgBox("Your mouse has left a child object: "&obj.Name)
  9. End Select
  10. End Sub


You could add different responses for all the children objects by referring by name.
For example, to display a message box when you mouse leave the child objects called "child1".

You can use Case Else to cover for all 'other' children as well as in the above script too.

stefsouron
Reply #10 Sunday, October 21, 2007 9:24 PM
As sViz has told, this doesn't work, because when the mouse enters a child object, it leaves the parent object, even if the pointer is always "over" it (that's the way DX is done). So in this case, the Object_OnMouseEnterEx sub receives as obj the child object, as expected, but in the same time, the Object_OnMouseLeaveEx receives as obj the parent object, so it desappears.

The only solution I've found, and sViz told me on another post he found the same, is to test if the mouse cursor is always inside the bounds of the parent object (in a rectangular manner), like this :

Code: vbscript


When that sub is trigerred by the entering of the mouse over a child object, its cursor is always in the rectangular bos of the parent object, so the result of the If...Then will be false and then the parent won't hide.

To go further, it's possible by this method to add a "margin" around the object, by setting it at the calculation of l,r,t & b, like that :

l = Object.Left - 5
r = Object.Right + 5
etc...

In this case, the parent object hides when the mouse leaves it PLUS a 5 pixels margin.

Bye...
Code: vbscript
Code: vbscript
Code: vbscript
SirSmiley
Reply #11 Sunday, October 21, 2007 9:48 PM
Interesting. I'd recommend setting that up as a separate function because of the formula and passing the object name as a variable.
stefsouron
Reply #12 Sunday, October 21, 2007 9:59 PM
I wanted to modify my precedent post but I've lost the code... If someone could explain me how to use the "Code Block" tags of the post editor, thank you...
So here it is :

Sub Object_OnMouseLeave ' Ex version is possible too
Dim x,y,l,r,t,b
x = System.CursorX
y = System.CursorY
l = Object.Left ' assuming the script is in the parent object
r = Object.Right
b = Object.Bottom
If x < l Or x > r Or y < t Or y > b Then
Object.Visible = False ' or anything the object is to do when mouse leaves
End If
End Sub

And of course, SirSmiley, it's good to place the test in a separate function, which returns a boolean, that's what I'm doing myself.
milksama
Reply #13 Monday, October 22, 2007 10:30 AM

To use the code blocks, all you really need to do is put your code within the tag:

Don't forget to define t   

If x < l Or x > r Or y < t Or y > b Then

You shouldn't even need this test in there. Object_OnMouseLeave() will work with objects of any size/shape whereas your version will only work with rectangular objects.

Another thing to take note is that this callback will really only be triggered once, so if you're still within the bounding box of the object, it will stay visible even when moving your mouse off the object. (Of course if you're using a rectangular objects, this wouldn't be a concern.)

You could test this using the default circular DX object and then slowly moving your mouse off of it (I used 100% opacity on mouseenter and 50% opacity on script enter and on mouseleave when testing). The object will stay visible.

-Mike
[Stardock Support]

stefsouron
Reply #14 Monday, October 22, 2007 2:07 PM
I know that works only for a rectangular zone, and I said it. But it's the only way we've found at this time to prevent the mouse leave event that occurs when the mouse enters a child object. As you generally need this kind of behaviour in docks or launchers application, the container is often near rectangular, so it's fine.

For a more graphically complex container, I can't see a way... If someone knows how to get the alpha value of an object's pixel, let me know, because in this case, the test could be possible, and we can declare we're outside the object when the alpha at mouse's cursor is equal to zero.
Skarny
Reply #15 Friday, November 2, 2007 10:38 PM
What about checking all children if in a Mouse Over state and THEN only hiding if they aren't.
This way, whenever the appbar loses mouseover focus it will only hide if none of it's children are being mouseovered.

Example

Sub Object_OnMouseLeave
hide = True <--- a flag to tell the function whether or not to hide the appbar
For Each chld in Object.Children
If chld.State = "Mouse Over" Then
hide = False
Exit For
End If
Next

If hide = True then
'hide function
Else
'whatever/nothing
End If
End Sub


*Above has not been tested, just a theoretical script idea.
stefsouron
Reply #16 Monday, November 5, 2007 4:31 AM
That's a very good idea. But just a question (i have no time to test it). If a child object doesn't have states implemented (i.e. in the properties dialog there is only the or 'mouse away' state, does it responds 'mouse over' or not ?
SirSmiley
Reply #17 Monday, November 5, 2007 2:20 PM
Yes.
Tiggz
Reply #18 Thursday, December 20, 2007 1:26 PM
Maybe the mouseleave event fires before the mouseover event though...

What you can do is to make the mouseleave event start a timer, and a mouseover event for any of the children kills the timer - if the timer fires, it does the relevant hiding then kills itself.

This serves the dual purpose of providing a delay for the hiding to allow for accidental slips of the mouse.
ZubaZ
Reply #19 Thursday, December 20, 2007 1:36 PM
Tiggz?

Tiggz!!!

 
HAPTORK
Reply #20 Thursday, December 20, 2007 1:59 PM
Tiggz. My favorite.
Autograph please..

Please login to comment and/or vote for this skin.

Welcome Guest! Please take the time to register with us.
There are many great features available to you once you register, including:

  • Richer content, access to many features that are disabled for guests like commenting on the forums and downloading skins.
  • Access to a great community, with a massive database of many, many areas of interest.
  • Access to contests & subscription offers like exclusive emails.
  • It's simple, and FREE!



web-wc01