I have several templates for device presentation. Nothing fancy, passing a single Path String that's disseminates into UDT elements for showing status. Part of the UDT is a device ID string. I usually bind this UDT string to the mouseover text, so that if someone hovers over a device, they can see the P&ID Device identification.
That worked fine until I put a mouse script on a template instance. The mouse event would never execute (simple open up a popup window).
As soon as I removed the mouseover binding AND the residual text left in the Mouseover setting inside the template, the mouse script on the template instance works fine. Add the Mouseover binding back in the template, the mouse event stops working. If I add the mouseover to the Template INSTANCE, it also works as expected, both the mouseover and the script to open the popup window.
So what about adding mouseover inside the template, kills external mouse events? I experimented with moving the mouseover binding to other widgets inside the template (a rectangle, a label, etc) and it also kills the mouse event.
The workaround for now is to add the mouseover to the Template Instance and not inside the Template, but is this a known issue or am I doing something wrong?
Standard java swing behavior. Events are consumed by the innermost component that has a handler. Tooltips are driven by a handler, so will stop propagation to enclosing components.
I've got something you can use to rebroadcast the event up to the template.
from java.awt.event import MouseEvent
from com.inductiveautomation.ignition.client.util.gui import IgnitionSwingUtilities
from com.inductiveautomation.vision.api.client.components.model import TopLevelContainer
def mouseEventToTop(event,startSource = None):
"""Sends a mouse event to the top-level component in a template
This is used for embedded templates and object that have mouse over text. If an object has a mouse over text, then the moues event is bound to that object.
So if the user clicks on that object, then there is no mouse even associated.
This allows a single main mouseEvent script on the template root (typically) and then this function is called in the sub objects.
Args:
event (java.awt.event.MouseEvent): Mouse event to pass along
startSource (object,optional): The starting source object to start traversing from. If this is a template embedded in another template, it might be required
to get the outer, or parent, template rather than the child template. So this would be the child template. This isn't typical.
Returns:
Nothing
"""
relX = 0
relY = 0
#If no start source is provided, then set the startsource to the event.source
startSource = event.source if startSource is None else startSource
parent = IgnitionSwingUtilities.getAncestorOfClass(TopLevelContainer, startSource.parent)
while parent == startSource:
#Offset the relativeX and Y to this object
relX += startSource.parent.x
relY += startSource.parent.y
#Traverse up starting at this startSource parent
parent = IgnitionSwingUtilities.getAncestorOfClass(TopLevelContainer,startSource.parent)
#Set the x and y for the event
evtX = relX + event.x + event.source.x
evtY = relY + event.y + event.source.y
#Create the MouseEvent
evt = MouseEvent(
parent,
event.getID(),
event.getWhen(),
event.getModifiers(),
evtX,
evtY,
event.clickCount,
event.popupTrigger,
event.button
)
#Send the mouse event up to the the parent that was found
parent.dispatchEvent(evt)
Use case is when you have a template that has a mouse event attached to it. Like a mouseClicked, mouseEntered etc.. and then you have another object in the template that has a mouseover text assigned. You would call this in the embedded object mouse event that has the corresponding mouse event on the template.
So if you have a mouseClicked event in the template that shows a popup, in the embedded object you would call this function in the mouseClicked event in the embedded object.