Measuring parentpatcher's "scrolling drift"?
Hello,
In order to test if the mouse is on a given object or not, I have made a little device based on [js].
I cannot use [hover] because the actual objects for which I need this test to take place cannot be expected to have a scripting name…
I have a getsize function in JS such as :
function getsize()
{
var boxPos = this.patcher.box.rect; // [x1, y1, x2, y2]
var winPos = this.patcher.parentpatcher.wind.location; // [x, y, width, height]
var zoom = this.patcher.parentpatcher.getattr("zoomfactor");
var globalX = winPos[0] + (boxPos[0] * zoom) + 35;
var globalY = winPos[1] + (boxPos[1] * zoom) + 35;
var width = (boxPos[2] - boxPos[0]) * zoom;
var height = (boxPos[1] - boxPos[3]) * zoom;
outlet(0, [ globalX, globalX + width, globalY, globalY - height ]);
}
I added +35 empirically, I assume because of the toolbar (I'm not really sure how to handle that otherwise…).Inside the abstraction (which is just a test, I need this detection device in several objects), I compare the coordinates with a mousestate and then I get 0 or 1. Easy.
The tricky part for me was the zoom, it seemed I handled it well with the getattr("zoomfactor") and multiplying the coordinates
But remains for me a BIG issue : how to detect the object when the patching window is being scrolled away from the starting point? In this case, no matter what zoom % I have (even default 100%) the real box position and the mousestate cannot align anymore. As show in this video :
Is there any way to retrieve the parent patcher scrolling drift? I'm not sure how to call that in English…
If you know an idea to detect if toolbar is on/off in parent patcher as well, I'm also interested…
Thanks !
Check the [mousestate] mode
message. mode 1
gives you coordinates relative to the patcher, just like the objects position, so scroll shouldn't be an issue.
What do you mean by "because the actual objects for which I need this test to take place cannot be expected to have a scripting name"?
Sorry if it wasn't clear : I have a family of objects that interact with each other in a very non-Max way, to program in another language (Lisp) in a modular way. Objects are instantiated freely by users, and patches can use hundreds of those objects, so I cannot expect users to add manually a scripting name for each box — that would be the only way to use the hover object in my context. Basically I needed a hover-like mechanism without scripting name, handled from within each object individually.
You pointed me exactly in the right direction : I was taking the problem the wrong way, instead of using the "winPos" (this.patcher.parentpatcher.wind.location), all I needed was to using the "boxPos" one (this.patcher.box.rect).
And for mousestate, instead of mode 1 (mouse position relative to mousestate's patcher) I need to use mode 2 (relative to frontmost patcher). This fixes everything : the toolbar doesn't require an extra value, since the top left corner of patch background is always [0, 0] ; the zoom is handled as before, and the scrolling is treated properly.
Thank you so much !
in case the objects have known and fixed positions(?) and do not overlap, you can easily abuse [lcd] or [jit.pwindow] to get the mouse position.
then if x is in a certain range and if y is within a certain range, read entry 17 from a coll. and if the patcher is zoomed, all these values are simply to be scaled likewise.
offset with [mousestate] is indeed a bit difficult, since you can not get a mother pather to output its position by thispatcher. (it most likely works with js or java, but no idea about that.)
No precisely it's like a patching aid so objects may move and be re-arranged a lot so I cannot assume it's stable. But it's ok I got my solution it's working perfectly now.