I am trying to get the position of the component that is being hovered over by the mouse to no avail
-
@VirtualVirgin said in I am trying to get the position of the component that is being hovered over by the mouse to no avail:
What I am doing is working on custom tooltips using your video.
I use the broadcaster technique now. It's much better. I'm basically using what Christoph gave in the post I linked to, although I've tweaked it a bit. It does pretty much exactly what you want.
In fact here's the exact code I'm using - it's not perfect and I have some more tweaks to make. But you'll see where I'm adjusting the size of the panel to match the text length.
namespace Tooltips { const tooltipComponents = getComponents(); //! pnlTooltip const pnlTooltip = Content.getComponent("pnlTooltip"); pnlTooltip.showControl(false); pnlTooltip.set("enabled", false); pnlTooltip.setPaintRoutine(function(g) { var a = this.getLocalBounds(20); var radius = this.get("borderRadius"); g.drawDropShadow(a, Colours.withAlpha(Colours.black, 0.6), 20); g.setColour(this.get("bgColour")); g.fillRoundedRectangle(a, radius); g.setColour(Colours.withAlpha(this.get("itemColour"), 0.5)); g.drawRoundedRectangle([a[0] + radius / 4, a[1] + radius / 4, a[2] - radius / 2, a[3] - radius / 2], radius, 1); g.setFontWithSpacing("medium", 16, 0.0); g.setColour(this.get("textColour")); g.drawAlignedText(this.get("tooltip"), a, "centred"); }); //! Functions inline function: Array getComponents() { local result = []; local allComponents = Content.getAllComponents(""); local types = ["ScriptButton", "ScriptSlider", "ScriptTable", "ScriptComboBox", "ScriptPanel"]; for (x in allComponents) { if (!x.get("enabled")) continue; if (x.get("tooltip") == "") continue; if (!types.contains(x.get("type"))) continue; result.push(x); } return result; } //! Broadcaster const bcTooltipPanel = Engine.createBroadcaster({"id": "tooltip", "args": ["component", "event"]}); bcTooltipPanel.attachToComponentMouseEvents(tooltipComponents, "All Callbacks", ""); inline function addRemoveListeners(state) { if (!state) { bcTooltipPanel.removeListener("Update panel position"); bcTooltipPanel.removeListener("Show Tooltip"); return; } bcTooltipPanel.addListener(pnlTooltip, "Update panel position", function(component, event) { var interfaceSize = Content.getInterfaceSize(); this.set("tooltip", component.get("tooltip")); this.set("width", Engine.getStringWidth(this.get("tooltip"), "medium", 16, 0.0) + 75); this.set("x", component.getGlobalPositionX() + component.getWidth() / 2 - this.getWidth() / 2); this.set("y", component.getGlobalPositionY() + 10); if (this.get("x") + this.getWidth() > interfaceSize[0]) this.set("x", interfaceSize[0] - this.getWidth() - 5); if (this.get("y") + this.getHeight() > interfaceSize[1]) this.set("y", interfaceSize[1] - this.getHeight() - 5); this.repaint(); if (!event.hover || (component.get("tooltip") == "")) this.showControl(false); }); bcTooltipPanel.addDelayedListener(500, pnlTooltip, "Show Tooltip", function(component, event) { if (!event.hover || this.get("tooltip") == "") return; this.showControl(true); }); } const bcTooltipButton = Engine.createBroadcaster({id: "valueChanged", args: ["component", "value"]}); bcTooltipButton.attachToComponentValue("btnTooltips", "Tooltips button toggled"); bcTooltipButton.addListener({}, "Enable - disable tooltips", function(component, value) { addRemoveListeners(value); }); }
-
@d-healey
Uh oh!
I know nothing of broadcasters yet, so I'll have to watch your video on that first so I would know what I am doing to work with your script here.Thank you very much for sharing this!
I'll study it. -
@VirtualVirgin Broadcasters are great and I keep finding more and more uses for them. I plan to include them in a lot more videos.
A very simple explanation: you can think of a broadcaster like a YouTube channel, and a listener like a subscriber to the YouTube channel.
When the channel puts out a new video, all of the subscribers get told about it, and then if that video interests them they can go and watch it.
To bring this back to tooltips. We're creating a mouse broadcaster (channel) and every time the mouse goes over one of the specified components the channel puts out a message saying "hey, if anyone's interested, I've just gone over this component."
Then the listener (subscriber) on the tooltip panel gets the message, which contains a reference to the component and some information about the mouse event (such as the x/y position of the mouse). It can use this to then display the tooltip.
-
I made some tweaks and update the code above.
-
@d-healey said in I am trying to get the position of the component that is being hovered over by the mouse to no avail:
Another option is to put the component reference into an object, using its ID as a key - this is a good approach is you want to work with a lot of components this way.
So you would do something like:
const myComponents = {"Knob0": Content.getComponent("Knob0"), "Knob1": Content.getComponent("Knob1"), etc.};
So I am looking this option over.
Is there a way to generate the full list of components as object with the key : value pair from a loop?
const myComponents = {}; const allComponents = Content.getAllComponents(""); for (i = 0; i < allComponents.length; i++) myComponents[i] = {??? : Content.getComponent(allComponents[i])};
-
const componentsById = {}; for (x in Content.getAllComponents("")) componentsById[x.getId()] = x;
-
@VirtualVirgin you could also do like this, it also takes care of components inside other components inside other...etc
It's also based on the broadcaster function, a great implementation, thanks to Christoph!
HiseSnippet 2204.3ocsYstbabaEdWYs1lLIt1osYlN8FJmzYnJ0PSJQIpTMdLEIkbjqkISDiuLtIof6BRhnkKX1EjhLNpim9Hzmf7m9Bzm.+29TzWg7Fjd.vx8B4RJJkF8CpE.myAemq3fca5xLIddLWM8zslLfno+tFmNwg2qVOL0Q635Z5+FilLOJmxbZz4iYiHtDqZr9CXNDGtV0ICvddDKMc8a7HAG5oVWS922+vpXariIIbJMsmwnljmP6S4gy1rxegZaeD1hzh1OB0kpbrIyoFylMDP2MLJnM.adFtK4oXAYqYn8wXudZ5+ICqhkJ1YOS7t6UrzVllasW4s9nxlDbmNjcKtS4R60oTGrYgszzu4gVTNy8TNlS7zzWuJyZxo8Xm6n1fmQ8nssIhAE0NE1Y0zGwrsDpnXVsZ8n1VMmZ17z.ozLzHdCkQ7WXbB0hFLenw7txEPgbD0.puVb3ciXvqXT3UHB7R.R5Qfz5JHcOiSMcoC3gqHvy6XbrCm3BlGRLnnnUasKtkQMFPgCOee7YjibgAAbjc2BE1DA+rw9oSC9JON5.a6ffCOzCPSYtKgGaorYxHX592GU0kgsLwdfLQVjNTGYnlu3FgcQ.qyF1UsFH5Cc5RcH4McIf0JhTx95zHTFpUl+LJSh7lYSAAX2td.IuJi4zUxrIJCYj3gOWRAGqn3ySegOVwbN1rGhyPR5PBKa5D2i7JRawBl6D1POxgijJeLSArqvXTMrscaH.2S.CowYQR1x5ITPQc.UcVAAbfF3msBxoyPGSwiYCzwMUHeizuNcJZGTV4n78D6xFoSASlRXxEjuO7bGlKJqIh5D2uBTlRxsovulUXq2.8fXN6.h+LGKhqT2ytgjOwdjJkXG.en49xQsAe3YxGu.9IsR3Tu5hvAhkD8Rlk71hwr4zAMwND67VXNNOWMiPd.kJL4OG.rbnLnu8aElEHfHGh6JhbAZBqpE.V+cZ+41FWx.HClmUtzE.BuPESjl5XCPLvPiVhbkOIM71LSrs.P.heclwPLVv5JvONyFfybx7KLIyFW.PXpHlZEmRjbo6e+Tl8Hlmg.iXvJndXOz.rq3QriEpqK7qZrWZkelBRpv9QLgpkCTBvT9Gd.DZtOhlKmevhO.h5vytDAHMe9ZuhslRRlZxT1eAQfwI+XTtGfFje7zwSTimruv7mNkKgOz0QXF2O8Ex7yThvedOxTEcZlPhdo3arhCo2wWtJGiZ9Y8JQmU4RlA.g1cV6uhXxSBAIDcbrkDAKIsKgrtXb6mi3qCpzqfrKHncZc5nQ2njybylIJQxJRwxI7DFQHo3SYC4ftkMnXSWoRzUPf5z6rp+4k+7dTNQ3ekKdDSrIPMe7PaQw2h6JVJdpOuG0KVRtrNP27Vt3yOvl1EnoEYLed51DImBTnmHh2pxF5X4ksfvCZBJGTSUnQpj3.uBy4oLNogSVoF.VKzrK0oShqIretLaanjbRKKZrwcYLl0YX+1D2MgC7rGRBHDN7NdGAFKtifnMrXpbmQHj4bLbvZiADmE0FileL.z8PJeTAjxk8N7998NPrdFkb9.lKWiBsI7yma5hZREHZKeZyJr63yU0gbNyQJneVrotJB4TaJb9RLgnlZFgrwe8+9vqNR1ZVj78WCgr8xTm0UB4874nEV3MEx3NQmIAKhHVWSeGis2Me7+F0n8dNMyke2OoaoI895GUnALYmbhk9nZx0m2ZdW+MCx8aypxFKQv8lYxhKyXbSkf9k97bvPKJ643QDnTVeoz9fjVYg5EzbOb.UWBD2CwZ5F5hkjybni0zwyYEe+XQ.MglohElFN8b6a9Jp88UF6VJ+iau2KxUma0ZuZvOeSiup5yajqrynBkmTfVcRiZOuwiy8hFOtc4SgeNuAaTgZ4FAKUt1m18qG1n016bPtugV84km7nC4iU7mWS6yNttXSf1q8S0fzuADWNUjYqWmLBtajpW8TF0IdmwYCfakEdWK8aEOX4I31D6XAKxYJpMNTwbpLI5MpNmZw6ENwKqziP61KxkwNthe8SAHjhCIJVDhgaekqHDAM0ifl25d4n4kgnIsgPhMEazH4CpCteof3W9ed7y92+y+0C0l2VsBEahfuIWQqUD7cGiintvAq9aj1hcaxSOi41jyDEHu4rnFJ6Y.x2wmCHNg.42ZnNT+bJuGZa+9O7flI7fneHiede4JTKMDZU9aQsQ0m0F8EIDQMSafyo2AP+W6aCOyg01GvHLzrkvdosXbujx2iihiIQUhK02Ve0w8uxPsensVATeIgAQw7a6FAyu4UqR73Ji4OvOLYF.KpMEvapUpdSLq7GtzLnVW4nisz3P6cBLTmPFfNVEEGnE+Q+ZTw0hk4EVsjwsipSPcgnClQmnyoSzvjw6YzBtM.zIpqURF3UKjnTTvTZoFXq4.i0kXf2NzX96hGRv+wi7cVcjOegiu3RPdoPj+gIFLGYHz2Shg1qPyaKJ3t9O9RH63GbeaYvMT5MPg98x3l1ppJv8.E9BKQBfIw1F6trH5E1B4B5JHrthgtELdpRnFEfnaYnDbBUzVwtGWPnvbGukPnP8J8wim11W.jdGCovQsgsLACxUtWzEzHvbGVTgLG.eZzFUB1qD.0UnE0EE3M4Rgya9jP37tFJYJd24w.zMWbFbzq4unBge2eeFX71+Qk3gNZy+NnuqwILqg1Xd7WIt3CG3u.zRWr2Cs3cMCYw7IQu1w+2dO4qJDumQSJ2rWxXbsDvHzj+OEXz+qK7dFG1oCzUWH.W23nW7SymRPS85c5dBl6RE4fOcX+SYCcMIvt6.AHh2Jg9ZhaioFWXZd5oDGK4fe.9yewhhw59KVb5hZ8wltruzTccNw2u31xY.L4H+VOoLNQLFkv8E6SsneooYbQMGiaccYb6qKikttLty0kwcutLV95x3dWNihu10AC4r9pzFMsSZdn7Vv55G5HNPQFsp8+fXth6L
-
@ulrik said in I am trying to get the position of the component that is being hovered over by the mouse to no avail:
@VirtualVirgin you could also do like this, it also takes care of components inside other components inside other...etc
It's also based on the broadcaster function, a great implementation, thanks to Christoph!
HiseSnippet 2204.3ocsYstbabaEdWYs1lLIt1osYlN8FJmzYnJ0PSJQIpTMdLEIkbjqkISDiuLtIof6BRhnkKX1EjhLNpim9Hzmf7m9Bzm.+29TzWg7Fjd.vx8B4RJJkF8CpE.myAemq3fca5xLIddLWM8zslLfno+tFmNwg2qVOL0Q635Z5+FilLOJmxbZz4iYiHtDqZr9CXNDGtV0ICvddDKMc8a7HAG5oVWS922+vpXariIIbJMsmwnljmP6S4gy1rxegZaeD1hzh1OB0kpbrIyoFylMDP2MLJnM.adFtK4oXAYqYn8wXudZ5+ICqhkJ1YOS7t6UrzVllasW4s9nxlDbmNjcKtS4R60oTGrYgszzu4gVTNy8TNlS7zzWuJyZxo8Xm6n1fmQ8nssIhAE0NE1Y0zGwrsDpnXVsZ8n1VMmZ17z.ozLzHdCkQ7WXbB0hFLenw7txEPgbD0.puVb3ciXvqXT3UHB7R.R5Qfz5JHcOiSMcoC3gqHvy6XbrCm3BlGRLnnnUasKtkQMFPgCOee7YjibgAAbjc2BE1DA+rw9oSC9JON5.a6ffCOzCPSYtKgGaorYxHX592GU0kgsLwdfLQVjNTGYnlu3FgcQ.qyF1UsFH5Cc5RcH4McIf0JhTx95zHTFpUl+LJSh7lYSAAX2td.IuJi4zUxrIJCYj3gOWRAGqn3ySegOVwbN1rGhyPR5PBKa5D2i7JRawBl6D1POxgijJeLSArqvXTMrscaH.2S.CowYQR1x5ITPQc.UcVAAbfF3msBxoyPGSwiYCzwMUHeizuNcJZGTV4n78D6xFoSASlRXxEjuO7bGlKJqIh5D2uBTlRxsovulUXq2.8fXN6.h+LGKhqT2ytgjOwdjJkXG.en49xQsAe3YxGu.9IsR3Tu5hvAhkD8Rlk71hwr4zAMwND67VXNNOWMiPd.kJL4OG.rbnLnu8aElEHfHGh6JhbAZBqpE.V+cZ+41FWx.HClmUtzE.BuPESjl5XCPLvPiVhbkOIM71LSrs.P.heclwPLVv5JvONyFfybx7KLIyFW.PXpHlZEmRjbo6e+Tl8Hlmg.iXvJndXOz.rq3QriEpqK7qZrWZkelBRpv9QLgpkCTBvT9Gd.DZtOhlKmevhO.h5vytDAHMe9ZuhslRRlZxT1eAQfwI+XTtGfFje7zwSTimruv7mNkKgOz0QXF2O8Ex7yThvedOxTEcZlPhdo3arhCo2wWtJGiZ9Y8JQmU4RlA.g1cV6uhXxSBAIDcbrkDAKIsKgrtXb6mi3qCpzqfrKHncZc5nQ2njybylIJQxJRwxI7DFQHo3SYC4ftkMnXSWoRzUPf5z6rp+4k+7dTNQ3ekKdDSrIPMe7PaQw2h6JVJdpOuG0KVRtrNP27Vt3yOvl1EnoEYLed51DImBTnmHh2pxF5X4ksfvCZBJGTSUnQpj3.uBy4oLNogSVoF.VKzrK0oShqIretLaanjbRKKZrwcYLl0YX+1D2MgC7rGRBHDN7NdGAFKtifnMrXpbmQHj4bLbvZiADmE0FileL.z8PJeTAjxk8N7998NPrdFkb9.lKWiBsI7yma5hZREHZKeZyJr63yU0gbNyQJneVrotJB4TaJb9RLgnlZFgrwe8+9vqNR1ZVj78WCgr8xTm0UB4874nEV3MEx3NQmIAKhHVWSeGis2Me7+F0n8dNMyke2OoaoI895GUnALYmbhk9nZx0m2ZdW+MCx8aypxFKQv8lYxhKyXbSkf9k97bvPKJ643QDnTVeoz9fjVYg5EzbOb.UWBD2CwZ5F5hkjybni0zwyYEe+XQ.MglohElFN8b6a9Jp88UF6VJ+iau2KxUma0ZuZvOeSiup5yajqrynBkmTfVcRiZOuwiy8hFOtc4SgeNuAaTgZ4FAKUt1m18qG1n016bPtugV84km7nC4iU7mWS6yNttXSf1q8S0fzuADWNUjYqWmLBtajpW8TF0IdmwYCfakEdWK8aEOX4I31D6XAKxYJpMNTwbpLI5MpNmZw6ENwKqziP61KxkwNthe8SAHjhCIJVDhgaekqHDAM0ifl25d4n4kgnIsgPhMEazH4CpCteof3W9ed7y92+y+0C0l2VsBEahfuIWQqUD7cGiintvAq9aj1hcaxSOi41jyDEHu4rnFJ6Y.x2wmCHNg.42ZnNT+bJuGZa+9O7flI7fneHiede4JTKMDZU9aQsQ0m0F8EIDQMSafyo2AP+W6aCOyg01GvHLzrkvdosXbujx2iihiIQUhK02Ve0w8uxPsensVATeIgAQw7a6FAyu4UqR73Ji4OvOLYF.KpMEvapUpdSLq7GtzLnVW4nisz3P6cBLTmPFfNVEEGnE+Q+ZTw0hk4EVsjwsipSPcgnClQmnyoSzvjw6YzBtM.zIpqURF3UKjnTTvTZoFXq4.i0kXf2NzX96hGRv+wi7cVcjOegiu3RPdoPj+gIFLGYHz2Shg1qPyaKJ3t9O9RH63GbeaYvMT5MPg98x3l1ppJv8.E9BKQBfIw1F6trH5E1B4B5JHrthgtELdpRnFEfnaYnDbBUzVwtGWPnvbGukPnP8J8wim11W.jdGCovQsgsLACxUtWzEzHvbGVTgLG.eZzFUB1qD.0UnE0EE3M4Rgya9jP37tFJYJd24w.zMWbFbzq4unBge2eeFX71+Qk3gNZy+NnuqwILqg1Xd7WIt3CG3u.zRWr2Cs3cMCYw7IQu1w+2dO4qJDumQSJ2rWxXbsDvHzj+OEXz+qK7dFG1oCzUWH.W23nW7SymRPS85c5dBl6RE4fOcX+SYCcMIvt6.AHh2Jg9ZhaioFWXZd5oDGK4fe.9yewhhw59KVb5hZ8wltruzTccNw2u31xY.L4H+VOoLNQLFkv8E6SsneooYbQMGiaccYb6qKikttLty0kwcutLV95x3dWNihu10AC4r9pzFMsSZdn7Vv55G5HNPQFsp8+fXth6L
Thank you:)
I am trying to integrate this with the solution from David Healey's tooltips video.
I have a question on how to access now the position data to position my tooltips panel.
I see this is where you write the tooltips data with the tooltip and the position:if (isDefined(comp)) { TooltipPanel.data.tooltip = comp.get("tooltip") + " || pos: "+ trace(getPositionOfComponent(comp));
And then you write it out with aligned text in the paint routine:
if (isDefined(this.data.tooltip)) g.drawAlignedText(this.data.tooltip, this.getLocalBounds(0), "centred");
But how do I access the position data itself?
-
@VirtualVirgin said in I am trying to get the position of the component that is being hovered over by the mouse to no avail:
But how do I access the position data itself?
In the code under this, the position data is retrieved using this function:
getPositionOfComponent(comp)
getHoveredComponentBC.addListener(AllComponents, "get position", function(component, event) { if (event.hover) { var comp; for (c in AllComponents) if (c.get("id") == Content.getComponentUnderMouse()) { comp = c; break; } if (isDefined(comp)) { TooltipPanel.data.tooltip = comp.get("tooltip") + " || pos: "+ trace(getPositionOfComponent(comp)); TooltipPanel.repaint(); } } });
-
@ulrik
I tried that out earlier but I just keep getting errors from it:If I put a string in I get an object back?
-
@VirtualVirgin it's Content.getComponent("ScriptLabel1"), you forgot the "Content"
-
@ulrik said in I am trying to get the position of the component that is being hovered over by the mouse to no avail:
@VirtualVirgin it's Content.getComponent("ScriptLabel1"), you forgot the "Content"
Sorry, I was trying to use the function you provided:
// get the component object inline function getComponent(componentId) { for (c in AllComponents) if (c.get("id") == componentId) { return c; break; } }