Im trying to adjust the width some rectangles based on a PLC tag in Vision.
The problem is: When I tie a tag to the width property, the rectangle grows and shrinks, but the anchor point is to the top left. Is there a way to make it understand the center is the anchor point?
I tried to tie an expression to the x position to move the rectangle over based on width, so that it still sits "center" of where I need it to be. However, it seems to only update when it feels like it. During testing, I'm not even using a tag. Just an expression on the X property based on the width property and typing in the width manually. It seems to execute on the 2nd or 3rd change only, and when tied to a tag, doesn't move.
Customer is adamant we replicate their existing animations from a Wonderware project.
If i change my width to 50, the property expression doesnt execute
But now if i enter, say 50.1, it exectues
What is the trick to controlling the trigger on an expression? In the end my width will be tag driven. But for testing and positioning, I'm starting off just fat fingering numbers in.
Events coming from shapes don't work that well. So, I feel ya.
I would make two custom properties at the container level. One to hole the centerline absolute x position and one for the width. bind properties and expressions to those, instead.
I tried your method of using custom properties at the container level. It seemed promising during development, but once I roll the screen out, the same problem persists.
Had a bit of free time today, so I whipped this up. To show how this would work with a paintable canvas. Obviously I've used sliders here, but tag values can easily be used in place of those. I created three custom properties on the paintable canvas component and bound them to the sliders. Doing that the canvas will automatically repaint when the properties change.
Here is the script in the repaint event on the canvas.
from java.awt import Color
from java.awt.geom import Rectangle2D as Rect
from java.awt.geom import Point2D as Point
#save the graphics object, really so you can type less
g = event.graphics
#all graphics are drawn with an assumption of 100 x 100 px size
#scalling is applied later prior to painting
#base rectangle
#graphics are drawn with 0,0 being at the top left corner
#Postive y direction is down
#base rectangle position
baseRectLoc = Point.Float(event.source.baseXPosition,80)
#base rectangle
baseRect = Rect.Float(baseRectLoc.x,baseRectLoc.y, event.source.baseWidth, 20)
#carried rectangle
#calculate x position of rect
#because we want the centers of the rectangles to always be aligned then we need to account for
#the width of the carried rectangle.
carriedLoc = Point.Float()
carriedWidth = event.source.carriedWidth
carriedLoc.setLocation((baseRect.centerX - (carriedWidth / 2.0)), 10)
carriedRect = Rect.Float(carriedLoc.x, carriedLoc.y, carriedWidth, 70)
# Scale graphics to actual component size
dX = (event.width-0.01)/100.0
dY = (event.height-0.01)/100.0
g.scale(dX,dY)
#paint the rectangles
g.setPaint(Color.GRAY)
g.fill(baseRect)
g.setPaint(Color.GREEN)
g.fill(carriedRect)