drag & drop

42 views
Skip to first unread message

Steve Baker

unread,
Dec 10, 2025, 3:27:53 PM (4 days ago) Dec 10
to DroidScript
I've been trying to implement drag & drop on an image. (I have done this kind of thing many times in other languages/systems, so I won't start by posting a lot of code.) I think moving the image (img.SetPosition) from within the img.SetOnTouchMove event causes a runaway situation: the SetPosition seems to cause another call to SetOnTouchMove, hence the runaway. Especially since the triggered call has NEW coordinates for current pointer (touch) location since the image has moved since the last call.

Is this a reasonable description of what I'm seeing? Is there an accepted/correct way of implementing drag & drop?

Thank you

Symbroson

unread,
Dec 10, 2025, 5:22:30 PM (4 days ago) Dec 10
to DroidScript
Just saw this topic in my emails and thought it is worth posting an example here:
The recommended way is to use the TouchSpy option on the parent layout.

My implementation uses absolute deltas for moving instead of relative jumps to prevent drifting,
and also has update rate limiting for better control over performance

function OnStart() {
   lay = app.CreateLayout("Absolute", "FillXY,TouchSpy")
   lay.SetBackColor("#3300ff00")

   for(let i = 0; i < 3; i++) {
      txt = app.CreateText("Hello " + (i + 1))
      txt.SetTextSize(62)
      lay.AddChild(txt)
      txt.SetBackColor("#330000ff")
      txt.SetPosition(Math.random() * 0.8, Math.random() * 0.9)
      addDND(txt, lay, 25 * i);
   }

   app.AddLayout(lay)
}

function addDND(txt, lay, rate = 50) {
   txt.data._dragRate = rate;
   txt.SetOnTouchDown(I(function() {
      lay.data._d = txt;
      lay.data._x = txt.GetPosition().left
      lay.data._y = txt.GetPosition().top
   }))

   // add dnd callbacks only once
   if(lay.data._dragInited) return;
   lay.data._dragInited = true;

   lay.SetOnTouchDown(I(ev => { lx = ev.X, ly = ev.Y; }));
   lay.SetOnTouchUp(I(ev => { lay.data._d = undefined; }));

   var nextUpdate = 0, lx = 0, ly = 0;

   lay.SetOnTouchMove(I(ev => {
      if(!lay.data._d) return;

      const t = Date.now();
      if(t < nextUpdate) return;
      nextUpdate = t + (lay.data._d.data._dragRate || rate);

      var dx = ev.X - lx, dy = ev.Y - ly;
      lay.data._d.SetPosition(lay.data._x + dx, lay.data._y + dy);
   }))
}

Steve Baker

unread,
Dec 10, 2025, 6:05:59 PM (4 days ago) Dec 10
to DroidScript
Thanks Symbroson,

Yeah, I had a version of this working, where the trace on the background/parent/lay is applied to the control to be moved. It works fine. I even have it working for multiple controls. I just felt it was weaker/more dependent than I would like, rather than self-contained in the control to be moved. Oh well, at least I wasn't way off base. Thanks, again,

Steve

Alan Hendry

unread,
Dec 11, 2025, 8:01:58 AM (3 days ago) Dec 11
to DroidScript
HI,
There's a previous post about moving controls
Regards, Alan H
Reply all
Reply to author
Forward
0 new messages