Good morning, I’m having issues with a script and wonder if someone had any ideas.
What I have is a template with a button, when that button is pressed it passes parameters from the UDT to a popup window and opens said popup window at the mouse cursor location.
I tested the below script with just a normal button on a screen and it works, but when I try to do it with a templates button the window does shift over some in the right direction, but not to the mouse cursor. I assume this has something to do with the button being inside of the template container instead of the root container?
mouseX = event.x
mouseY = event.y
compX = event.source.getX()
compY = event.source.getY()
parWindow = system.gui.getParentWindow(event)
windowX = parWindow.getX()
windowY = parWindow.getY()
param1 = event.source.parent.MotorNumber
window = system.nav.openWindow('Popup Windows/PRP_Motor_FVNR', {'MotorNumber' : param1})
window.setLocation(mouseX+compX+windowX,mouseY+compY+windowY)
Correct, the x & y of the event are relative to the component of the event. To obtain the placement on the screen, you’ll need to traverse the chain of parents of the component, adding their offsets. You are missing the position of the template within the window.
Thanks both of you! I’d been brute forcing it from some forum posts and what I thought would work - but the SwingUtilities documents will be helpful
So I was able to find another forum post trying to solve a similar problem and using the convert point to screen swingutility - the script functions. However, the script fails if I have a second vision window open on another monitor. It will only function for the screen that is located at the top-left monitor position. For multi-monitor it fails and trys to open the pop-up offscreen. Any advice?
def setRelativeLocation(event, window, compRelX, compRelY):
windowX = window.getX()
windowY = window.getY()
screenRelX, screenRelY = system.gui.convertPointToScreen(compRelX, compRelY, event)
window.setLocation(screenRelX, screenRelY)
param1 = event.source.parent.MotorNumber
win = system.nav.openWindow('Popup Windows/PRP_Motor_FVNR', {'MotorNumber' : param1})
setRelativeLocation(event, win, event.x, event.y)
You don’t want screen coordinates. You want coordinates within the frame containing the parent window. Consider experimenting with the more generic convertPoint() method, where source
is your template and dest
is your parent window’s parent.
2 Likes
For posterity.. (i.e. for future me), you can use this:
from javax.swing import SwingUtilities
window = system.nav.openWindow('Popup Path', {})
newPoint = SwingUtilities.convertPoint(event.source, event.x, event.y, system.gui.getParentWindow(event).rootContainer)
window.setLocation(newPoint.x, newPoint.y)
Thanks Phil for the massive prompt
3 Likes
Pointtoscreen isn't helpful in most cases though. I tried it with my 3 monitors and my new point was off the page
it also doesn't help for clients that are not fullscreen if displayed on a single monitor system, since the point still references the top left of the monitor, not the client
3 Likes
You and Phil are the men! I tried using PointToScreen and it broke bc of multiple monitors - this worked excellently!
I implemented something similar to this with
from javax.swing import SwingUtilities
from com.inductiveautomation.factorypmi.application import VisionDesktop
appWindow = SwingUtilities.getAncestorOfClass(VisionDesktop, event.source)
window.setLocation(SwingUtilities.convertPoint(event.source, event.x, event.y, appWindow))
Seems to work well enough, but wondering if I should change it to what is shown here.