Dragging & moving object in window

Hi,
I want to move a template object in run-time. I use mouseDragged event with following code on template:
x = event.x
y = event.y
system.gui.transform(event.source,x,y)

what happens is the template moves (even blinking while moved) in the middle position between the original position and the mouse position randomly, that is not on the current mouse position.
Note: that this behavior is not present if the script is put on a simple drawing object like rectangle.
I even test different setting for object layout relative & anchored but nothing changed.
what is wrong with my code?

thanks.

1 Like

The x,y location in the event is relative to the origin of the component. The x,y location needed for transform() must be relative to the component’s container. For smooth motion, you will also need to capture and adjust for the x,y offset from the beginning of the drag.

Hi Phil
I use these code, this time it move smoothly but with some constant offset. When I press and hold click, the template jump an offset from mouse pointer and when I move mouse it move accordingly with constant offset.
point = system.gui.convertPointToScreen(event.x, event.y, event)
system.gui.transform(event.source, point[0], point[1])
Do I miss anything? I guess it is because of screen scaling.
I also change layout to anchor but nothing is change.

You don’t want to convert to screen coordinates, but to the container’s coordinates.

could you please tell me how?
the event.x, event.y is coordinate related to the container which the template here.
I use mouseDragged event on the container so it’s container’s coordinates.

Ah, reverse of what I thought. So you need to compute and save the offset from the startDrag/mousePress x,y location to the origin of the template you are moving. Then subtract that from event x,y in mouseDragged to get the new origin of the template you are moving.

no luck
I get back to my first state which indicate there is bug here.
I even use event.source.getBounds().bounds.getX() to get correct location with no luck.
I print event.x and event.y and I get negative value even my mouse is within the screen!!!

I just add constant offset with try and error and it’'s work the problem is in run time, the window is scaling so this offset get wrong again and add new offset.

point = system.gui.convertPointToScreen(event.x, event.y, event)
system.gui.transform(event.source, point[0]-400, point[1]-95)

it seems easy but nothing works correct and I’m sure there is bug.

Show the complete scripts for mousePressed, mouseReleased, and mouseDragged. Please use triple-backquote above and below each script so they format nicely.

I upload the window with its script for you to see the problem in action. Just try to dragged and move the component in designer and client view.

Nader_About_2018-11-20_0932.proj (5.1 KB)

I use system.gui.getParentWindow(event).mousePosition.getX()instead of using event.x method and now it’s working.
The only issue left is why mouse pointer jump to left top corner of the object?
I want mouse stay where I click and dragged on object for the first time and stay fix related to object.
I attach a video to show what I want. I did it on other SCADA software and I want to do it in ignition.

https:/uploads/iatesting/original/2X/4/4b05ba66da699b72e7690d8f0b892671a283ad8a.mp4

Your component needs two offset custom properties. I added on your example component this two x_offset, y_offset.

Then in the mousePressed event script:

event.source.x_offset = event.x
event.source.y_offset = event.y

and in the mouseDragged:

x = system.gui.getParentWindow(event).mousePosition.getX()
y = system.gui.getParentWindow(event).mousePosition.getY()
system.gui.transform(event.source, x - event.source.x_offset, y - event.source.y_offset, coorSpace=system.gui.COORD_DESIGNER)
1 Like

Thanks Jasko
It works perfectly.
The mouseDragged event has event.x event.y which show the current position of mouse.
Could you explain to me why event.x event.y doesn’t work in mouseDragged and I should use system.gui.getParentWindow(event).mousePosition.getX() instead?

As far as I know.
The event.x and event.y in mouseDragged are the same as in mousePressed, but this is just the offset (mouse position on the component). It is not the position of the component itself. That would be event.source.x and event.source.y

But if you use this two for your transform function, it also won’t work, because you would be adding the offset to the actual position of the component in x and y-direction.

Lets assume the x and y position are at start 100, and the x_offset = 61 and y_offset = 17. If you now drag your mouse, so the function executes 3 times, then the position of the template would be on each iteration:
start: 100 100
it1: 161 117
it2: 222 134
it3: 283 151

But this is dragging the component only to the right and down, so it doesn’t matter where you dragging.

So the only way to drag the component to where the mouse is is to make the position of the component dependent on the position of the mouse. Because of that, you have to use those functions.

1 Like

Now I try to limit user movement between x axis between -150 and 0 according the object.(top left corner coordinate)
I use many different if else statement which check object x position (event.source.getBounds().getX()).
The problem is like before there may random jump. I cant fiqure it out how to fix this.
Could you please modify the code so it limit x position between -150 to 0 like slider?

I will give you this. A way to bound the drag of the component to a specific area. For this you need the star x position (x_pos) start y position (y_pos). You also need the positive and negative limits of x and y (x_pos_limit, x_neg_limit, y_pos_limit and y_neg_limit) All this should be properties on your component.

Example:
x_pos = 300
y_pos = 300
x_pos_limit = 150
x_neg_limit = 150
y_pos_limit = 150
y_neg_limit = 150

the script in mousedragged:

x = system.gui.getParentWindow(event).mousePosition.getX()-event.source.x_offset
y = system.gui.getParentWindow(event).mousePosition.getY()-event.source.y_offset
if event.source.x_pos - event.source.x_neg_limit < x < event.source.x_pos + event.source.x_pos_limit:
    if event.source.y_pos - event.source.y_neg_limit < y < event.source.y_pos + event.source.y_pos_limit:
        system.gui.transform(event.source, x, y, coorSpace=system.gui.COORD_DESIGNER)

Whit this the component can only be moved from 150 to 450 on the x-axis, and also on the y-axis

1 Like