Page 1 of 2

Mouse over in Ruby is buggy?

PostPosted: Thu Jan 07, 2021 3:58 pm
by adamszabo
So I have this mouse over in green primitives and in Ruby, they are supposed to do the same thing but the Ruby one behaves differently? Please see attached schematic for the example. In the green version, click the blue square and hold and drag the mouse out, and the mouse over will change to false, since its not in the blue square anymore. In the Ruby one, it gets stuck to true. Any way to fix this? One thing thats curious is if I remove the "Drag" primitive from the green version the mouse over will work in the "bad" way like Ruby, so the Drag primitive changes something. In the Ruby version I do have the mouse move captured so it should be the same as the drag no?

Thanks

Re: Mouse over in Ruby is buggy?

PostPosted: Thu Jan 07, 2021 6:07 pm
by trogluddite
Mt first thought was that the "mouseMove(x, y)" method might work. But the behaviour was still the same after moving the area test into "mouseMove" (and making "isInMousePoint" always true). I then added the area test code into "mouseMoveCaptured" (keeping it in "mouseMove" too), and that did work! :D

So, the same behaviour is possible: but whereas the "MouseOver" primitive ignores the dragging status, Ruby has a very strict split between captured and non-captured mouse moves.

This actually brings into focus something that I noticed with Hugh's recent R-click problems: For non-captured events, Ruby always tests the "isInMousePoint" method first, and ignores the event if it returns false/nil. That's quite handy, as it means that we often don't need to repeat the area test inside every single "Up/Down/Move" method that we use. However that wouldn't be reliable during captures, where the drag might continue outside the defined area - so the "captured" methods bypass "isInMousePoint" and get called directly.

It's amazing how much there is still to discover and clarify about the Ruby GUI methods even after all these years! :lol:

Re: Mouse over in Ruby is buggy?

PostPosted: Thu Jan 07, 2021 6:11 pm
by adamszabo
Cool, would you mind showing that in code? Im not really sure I follow

Re: Mouse over in Ruby is buggy?

PostPosted: Thu Jan 07, 2021 6:22 pm
by trogluddite
Sorry - I was being lazy because I couldn't be bothered navigating the file system! :oops:
Mouse Over Issue Fix01.fsm
(1.37 KiB) Downloaded 826 times

Re: Mouse over in Ruby is buggy?

PostPosted: Thu Jan 07, 2021 6:40 pm
by adamszabo
D'oh, of course! Thanks! However now there is a mouse hand pointer even in the grey area where as it should only be when its over the Blue square. So I guess I should leave the area check in the isInMousePoint part?

Another thing is I noticed that now I get millions of triggers sent out to the mouse over boolean when I move the mouse which could cause lots of CPU usage, so I guess I need to write the area checks like this so they only output when it changes from true to false?

Code: Select all
x1, y1, w1, h1 = @area
m = x.between?(x1, x1 + w1) && y.between?(y1, y1 + h1)
output 0, m if @prev != m
@prev = m

Re: Mouse over in Ruby is buggy?

PostPosted: Thu Jan 07, 2021 6:46 pm
by DaveyBoy
you beat me to it Trog :)

was just about to say It appears to me that the isInMousePoint method only reports the coordinates while the left button is in the up position, hence the need to put the logic in the mouseMoveCaptured Method. Please correct me if I'm wrong.

Here's my solution Adam:

Re: Mouse over in Ruby is buggy?

PostPosted: Thu Jan 07, 2021 6:52 pm
by tulamide
adamszabo wrote:However now there is a mouse hand pointer even in the grey area where as it should only be when its over the Blue square. So I guess I should leave the area check in the isInMousePoint part?

No. The area check for cursor shapes goes into mouseCursor(x, y).

----------------------------------------------------------------------------------------


I'm not sure, if it is of interest for anyone, but since I had mouse dragging issues very early on, long before I discovered that there are "...captured" versions of the methods, I came to a global mouse up solution, that could also be helpful for right mouse button checks. It basically keeps track of still "active" mousemoves, although the mouse up already happened, by creating a top level non-visible graphic module that releases the mouse for every active mouse move.

Re: Mouse over in Ruby is buggy?

PostPosted: Thu Jan 07, 2021 7:03 pm
by adamszabo
Thanks DaveyBoy, your version is nice as well!

Tula, Im sure a lot of people would appreciate that it you are willing to share it with us!

Re: Mouse over in Ruby is buggy?

PostPosted: Thu Jan 07, 2021 7:29 pm
by trogluddite
DaveyBoy wrote:you beat me to it Trog

A neck-and-neck photo-finish after taking me nearly a decade to finally get it straight in my head! I'd best not gloat too much! :lol:

adamszabo wrote:So I guess I should leave the area check in the isInMousePoint part?

tulamide wrote:No. The area check for cursor shapes goes into mouseCursor(x, y).

It depends on the particular GUI, I think...

The reason for "isInMousePoint" is that it allows you to share the code for testing the active mouse area. If it returns false, then no other mouse method can get called (except the "...Captured" methods during a drag). In Adam's example, all of the non-dragging actions (mouse Up/Down/Move) are using the same "blue square" area, so it makes sense to share the test inside "isInMousePoint". If the default "hand" shape is acceptable, it will look after itself without needing "mouseCursor" in this case.

OTOH, if you don't want the default "hand" shape, or if the area tests are more complex (say, sub-divided into multiple nested controls), then "mouseCursor" will certainly be needed. You might also prefer to use "mouseCursor" just to make the meaning of the code more explicit, but it's not always needed functionally.

adamszabo wrote:so they only output when it changes

Yes - definitely a good idea! it's a shame that the stock toolbox controls aren't so careful with trigger limiting!

Re: Mouse over in Ruby is buggy?

PostPosted: Thu Jan 07, 2021 10:12 pm
by tulamide
trogluddite wrote:
adamszabo wrote:So I guess I should leave the area check in the isInMousePoint part?

tulamide wrote:No. The area check for cursor shapes goes into mouseCursor(x, y).

It depends on the particular GUI, I think...

The reason for "isInMousePoint" is that it allows you to share the code for testing the active mouse area. If it returns false, then no other mouse method can get called (except the "...Captured" methods during a drag). In Adam's example, all of the non-dragging actions (mouse Up/Down/Move) are using the same "blue square" area, so it makes sense to share the test inside "isInMousePoint". If the default "hand" shape is acceptable, it will look after itself without needing "mouseCursor" in this case.

OTOH, if you don't want the default "hand" shape, or if the area tests are more complex (say, sub-divided into multiple nested controls), then "mouseCursor" will certainly be needed. You might also prefer to use "mouseCursor" just to make the meaning of the code more explicit, but it's not always needed functionally.
I understand what you mean. And if there is no need for cursors other than the automatically set ones, of course you don't need mouseCursor.

But I'm also a great fan of making code maintainable, and we humans have a hard time reading code that isn't tidy and structured (I painfully experienced it a lot of times :mrgreen: ). My example would be an assumed combo control, say a text field with arrows on both sides. You would want the control to react no matter where it's clicked, but you'd want a, say, pointer cursor when over the arrows and a text cursor when over the text field. In this case it would be very confusing to check the areas in isInMousePoint, while executing the results in mouseCursor.