Is it possible to change label position in a vision template dynamically

Hi All.

What is the best way to position a label in a template?

We have some “standard” valve and motor templates where we would like to position the device name label (top/center/bottom, left/centre/right) - ideally this would be visible in the designer when dropping on a page but not essential.

I have seen use of system.gui.transform to move things around but that isn’t visible in the designer and I need an event to make that work (an event that fires only once on template loading - propertyChange?!).

I have my current (very horrible) solution of having multiple labels and setting visibility of the desired position but that makes the template object in the designer huge. not to mention it “appears” to really lag the page on first load.

Option 3, which is my least favorite, is to not have the label inside the template, meaning I have to add a label whenever I add a template and configure the text. - Since the label text is already part of the UDT parameters it makes more sense to me to be contained.

Anyway, any input greatly appreciated.

Regards
Dave

I opted for option 3 since it’s the most flexible. Sometimes the standard four compass positions just don’t suit some instances. I created a device label template with a subset of the params I have in the device templates (ie. deviceParentPath and deviceName) for consistency and so that I can just select both templates and set the props together.

Adding the label into the template also plays havoc with the template bounding box as well as its centre point.

I would go with option 3 as well. I dealt with a few projects where everything was in a template and it just didn’t work well, as you know you may need to move things around. I would rather make each component a template and then build up what you need. It doesn’t take any longer either, you can make a window that has an example, then simply copy that example and paste where you need it. Then select all components and you can change the tag reference for all at the same time.

Much more flexible and also gives you rapid deployment.

You can use the runScript expression function to call scripts in the designer even when not in preview mode. Perfect for this sort of adjustment. That is, I would keep it in the template.

I would not use any UDT parameters, though. Always pass a tag path instead of a UDT. Then everything works even if you pass a path that has a folder with the same structure as the original UDT. Or switch among multiple UDTs that can't be modeled by inheritance.

Thanks all for your answers.

My main issue with option 3 is that when my minions are bashing out pages, things like labels get overlooked.

I like Phil’s solution however, its more in line with my thinking, I can replace T/C/B L/C/R with offsetX and offsetY which should give me infinite placement.

Not to derail the topic, but, is there any downside to using the UDT other than flexibility?
I have started using indirect tags within templates and pop pages (as suggested in other threads by yourself and Nick) to access UDT parameters, so not totally against it.
We currently only have a single device UDT regardless of how many types of AOIs are in the PLC.
I also like the fact I can use the drop target to quickly add templates to the pages (which I assume wont work without a few extra mouse clicks when only passing a tag path?!)

Thanks again for you insights.

Regards
Dave

OK, so I have been bashing my head on this for way too long now.

  • I created a new template “Testing” which has 2 parameters “OffsetX” and “OffsetY”
  • In the template I added a label “ShortName_Lbl”
  • On the label I created custom properties “OffsetX” and “OffsetY”
  • In the binding for “OffsetX” I have the following expression
    • runScript(“system.gui.transform”,0,{Testing.ShortName_Lbl},{Testing.OffsetX},{Testing.OffsetX}).

but… I’m struggling to get the JComponent reference.

Error message I see is:
Exception: Error executing expression binding on
Testing.Testing.ShortName_Lbl.OffsetX
caused by ExpressionException: Error executing script for runScript() expression:system.gui.transform
caused by java.lang.RuntimeException: java.lang.RuntimeException: Component argument not found.

Am I heading in the right direction? or should I be calling a custom method which in turn calls the transform?!

Any pointers greatly appreciated…

Regards
Dave

This.

I’d make a property on the label called repositionTrigger, and bind an expression like

{Testing.OffsetX}+{Testing.OffsetY}+runScript(“self.reposition”)

that calls a custom method on the label that repositions itself (and returns a value to make the binding happy). By including both the offsetX and offsetY in the binding, the runScript(“self.reposition”) will be triggered when either value changes.

1 Like

Or switch to my objectScript. It can do complete one-liners with passed arguments. runScript can only pass arguments to a callable.

thanks @bmusson.

That worked a treat. That will definitely fix up my (horrible) multi label templates.
I will need to keep the current large template size however as the label can be placed outside of the template width and height but is not visible (changing the template width and height - doesn't look like I can use transform on self.parent?! and directly referencing self.parent.width and self.parent.height in the MoveMe method doesn't seem to work)

for completeness, the full solution

  • Template ("Testing")
    • Add custom parameters OffsetX, OffsetY
  • Label ("ShortName")
    • Add custom method ("MoveMe")

def MoveMe(self):
"""
Arguments:
self: A reference to the component instance this method is invoked on. This argument
is automatic and should not be specified when invoking this method.
"""
system.gui.transform(self,self.parent.OffsetX,self.parent.OffsetY)

    • Add custom parameter "OffsetChanged"
      • Expression Bind "OffsetChanged" - {Testing.OffsetX}+{Testing.OffsetY}+runScript("self.MoveMe",0)

Works like a charm.

@pturmel - I will have a play around with objectScript (now I found it in simulation Aids 3rd Party module)

Thanks all.

Regards
Dave

1 Like