I figured that it wouldn't too difficult to script this, but I've encountered an interesting result. the mouse event handlers on the actual template don't fire. It's as if the listeners aren't there. The mouse event handlers with the template work fine though. Is this part of the problem?
My initial understanding of your question was that a nonclickable component, that just happened to be a template, was overlapping another component in some way, and you were wanting the mouse cursor to change to hand indicating that a clickable component was underneath. Is this correct, or have I misunderstood the question?
Messing around with this, I developed this script that can detect overlap and respond with a mouse cursor change:
Prototype Script
from java.awt import Cursor, MouseInfo
from javax.swing import SwingUtilities
from com.inductiveautomation.factorypmi.application.components import PMIButton
from com.inductiveautomation.factorypmi.application.components import BasicContainer
def getCoordinates(component):
x1 = component.x
y1 = component.y
x2 = component.x + component.width
y2 = component.y + component.height
return [x1, y1, x2, y2]
def isOverlapped(selfCoordinates, componentCoordinates):
left = selfCoordinates[2] < componentCoordinates[0]
right = selfCoordinates[0] > componentCoordinates[2]
above = selfCoordinates[1] > componentCoordinates[3]
below = selfCoordinates[3] < componentCoordinates[1]
return not (left or right or above or below)
def getOverlapCoordinates(selfCoordinates, componentCoordinates):
x1 = max(selfCoordinates[0], componentCoordinates[0])
y1 = max(selfCoordinates[1], componentCoordinates[1])
x2 = min(selfCoordinates[2], componentCoordinates[2])
y2 = min(selfCoordinates[3], componentCoordinates[3])
return [x1, y1, x2, y2]
selfCoordinates = getCoordinates(event.source)
container = SwingUtilities.getAncestorOfClass(BasicContainer, event.source)
for component in container.getComponents():
if component != event.source and isinstance(component, PMIButton):
componentCoordinates = getCoordinates(component)
if isOverlapped(selfCoordinates, componentCoordinates):
overLapCoordinates = getOverlapCoordinates(selfCoordinates, componentCoordinates)
mousePosition = SwingUtilities. convertPoint(event.source, event.x, event.y, container)
if mousePosition.x >= overLapCoordinates[0] and mousePosition.x <= overLapCoordinates[2] and mousePosition.y >= overLapCoordinates[1] and mousePosition.y <= overLapCoordinates[3]:
event.source.setCursorCode(Cursor.HAND_CURSOR)
else:
event.source.setCursorCode(Cursor.DEFAULT_CURSOR)
However, it only works with standard components, and I've had no luck getting this to work from a template. I've tried the mouseMoved event handler; I've added my own custom listener, and I've attempted to get the components by calling them from the root container instead of using ancestorOfClass.
What kinda worked was putting a transparent label over the template instance and firing the script from the mouseMoved event handler of label, but the label blocked access to some of the template functions, so additional scripting would have been needed.
Perhaps somebody else will have a better idea.