Moving objects

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
kdjanz
Posts: 300
Joined: Fri Dec 09, 2011 12:12 pm
Location: Fort Saskatchewan, AB Canada

Moving objects

Post by kdjanz » Sat Apr 03, 2021 9:48 pm

Hi All

I'm working on creating a stack to analyze text files with the scripts of other stacks to show their flow and how the scripts are connected.
The image shows the output so far, and I want the user to be able to drag the graphic objects to create a more pleasing layout. When the user lets go of a graphic, the doLines function stretches all the connecting lines to the new position and then saves the location of the 20 graphics to a custom property. I originally had the doLines code in the mouseMove handler, but separated it out because I thought that was the cause of the slowdown.

The code shown is set as a behaviour for the 20 graphic objects shown. With the connecting lines, there are about 50 graphics on the card. The issue is that the code is responsive and works fine on the first graphic, but then things slow down drastically and it is hard to choose or move another object. I borrowed the code setting the gDragging flag and using the Deltas from an old website - Is it outdated now?

I tried using "grab me" but I couldn't figure out how to let go of the object once I started dragging it. The flush events calls were another attempt to speed up the second call.

Summary - need help to find out why it works poorly the second time it is called. Any suggestions?

Image

Code: Select all

local tName,gDeltaX,gDeltaY
global gDragging,tList

on mouseDown
   put the short name of the target into tName
   if char 1 of tName is not "G" then exit mouseDown
   put true into gDragging
   put item 1 of the loc of the target - the mouseH into gDeltaX
   put item 2 of the loc of the target - the mouseV into gDeltaY
end mouseDown

on mousemove x,y
   put flushEvents("all")
      if gDragging = true then
      add gDeltaX to x
      add gDeltaY to y
      set the loc of the target to x,y
   end if
end mousemove

on mouseUp
   put false into gDragging
   put flushEvents("all")
   recordLoc
end mouseUp

on recordLoc
   put empty into tList
   repeat with x = 1 to the number of graphics
      put the short name of grc x into tName
      if char 1 of tName is not "G" then next repeat
      delete char 1 of tName
      put the loc of grc x into line tName of tList
   end repeat
   set the cLocList of button "Chart" to tList
   send "doLines" to button "Chart"
end recordLoc
Attachments
FlowChart.jpg

richmond62
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 9358
Joined: Fri Feb 19, 2010 10:17 am
Location: Bulgaria

Re: Moving objects

Post by richmond62 » Sun Apr 04, 2021 8:18 am

grab me has to be in the right place so that it can subsequently drop the object being dragged.

As far as I can tell from your description you wish to click on one of the labelled rectangles and drag it somewhere, and then,
having dragged it, to release it.

Therefore have your grab me code in a mouseDown,
therefore when your mouse button is released the grab me will finish.

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7228
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Moving objects

Post by jacque » Sun Apr 04, 2021 5:28 pm

Try locking messages and the screen before updating the lines.

But it seems like you could update only the connecting lines of the repositioned graphic instead of all of them, since the user can only move one at a time.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

SparkOut
Posts: 2852
Joined: Sun Sep 23, 2007 4:58 pm

Re: Moving objects

Post by SparkOut » Sun Apr 04, 2021 6:41 pm

I don't know if this is useful or relevant to the problem you're having but this old thread has a stack which does some drag/stop/link drawing which might be useful to pick apart, compare, or explore and expand.
viewtopic.php?p=133097#p133097

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9647
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Moving objects

Post by dunbarx » Sun Apr 04, 2021 8:11 pm

Here is a sample stack that might be a start. The action is in the card script, and it contains stuff left over from fooling around.

Right now, you have to first click on one of the "F" fields, then press and hold the optionKey. If you then move the mouse, the field and all its line graphics will track its movements.

It is not hard to break this, if for example you click another field while the optionKey is still down. Anyway, it was just an experiment to address one part of the OP's issue.
LineDragger.livecode.zip
(1.95 KiB) Downloaded 134 times
Craig

kdjanz
Posts: 300
Joined: Fri Dec 09, 2011 12:12 pm
Location: Fort Saskatchewan, AB Canada

Re: Moving objects

Post by kdjanz » Sun Apr 04, 2021 8:41 pm

Thanks to all of you. I have followed up and the scripts now look like this:

Code: Select all

local tName,gDeltaX,gDeltaY
global gDragging,trgt,tList

//on mouseEnter
#   put false into gDragging
//end mouseEnter

on mouseDown
   put the short name of the target into tName
   if char 1 of tName is not "G" then exit to top
   put the long name of the target into trgt
   grab the target
   //put true into gDragging
   //put item 1 of the loc of the target - the mouseH into gDeltaX
   //put item 2 of the loc of the target - the mouseV into gDeltaY
end mouseDown

#on mousemove x,y
#   if the mouse is not down then exit to top
#   //put flushEvents("all")
#   //if gDragging = true then
#   //add gDeltaX to x
#   //add gDeltaY to y
#   set the loc of trgt to x,y
#   //end if
#end mousemove

#on mouseRelease
#   put false into gDragging
#   //put flushEvents("mousemove")
#   //recordLoc
#end mouseRelease

on mouseUp
   //put false into gDragging
   //put flushEvents("all")
   recordLoc trgt
end mouseUp

on recordLoc trgt
   lock screen
   lock messages
   put empty into tList
   repeat with x = 1 to the number of graphics
      put the short name of grc x into tName
      if char 1 of tName is not "G" then next repeat
      delete char 1 of tName
      put the loc of grc x into line tName of tList
   end repeat
   set the cLocList of button "Chart" to tList
   unlock messages
   send "doLines" to button "Chart"
end recordLoc
I have incorporated some of the suggestions from each of you:

The mouseDown is essentially "grab the target" (once we are sure it is the right target)

There is no mouseMove since the drag is taking care of it.

There is no mouseEnter or mouseRelease since they are not needed.

I am now locking the screen and messages before I do the processing. I have not yet reduced the processing to just the lines attached to the target, but I will do that, in the hopes of reducing the much smaller lag I still have when choosing a second or third object.

Summary, it works reasonably and I will polish it a bit more, so Thanks again!

I did look at LineDragger and LinkNodes, but the other suggestions got me far enough along with the code that I had. I have another project that LineDragger might work well for though.

Next question?
Does anyone know of an algorithm to arrange objects with minimal overlaps? This is what I get manually, but I want to do it automatically.
FlowChart2.png
Thanks again.

kdjanz
Posts: 300
Joined: Fri Dec 09, 2011 12:12 pm
Location: Fort Saskatchewan, AB Canada

Re: Moving objects [Solved]

Post by kdjanz » Mon Apr 05, 2021 2:54 am

Update to close the topic:

This code

Code: Select all

global gTrgt

on mouseDown
   put the short name of the target into gTrgt
   if char 1 of gTrgt is not "G" then exit to top
   delete char 1 of gTrgt -- this is now the ID that identifies the graphic object moving
   grab the target
end mouseDown

on mouseStillDown pButtonNumber
   linz --rubber bands the lines
end mouseStillDown

on mouseUp
   recordLoc -- records the locs of everything on completion
end mouseUp

on linz
   local tLz,tLine
   if gTrgt is empty then exit to top
   put fld "List" into tLz
   filter lines of tLz with "*" & gTrgt & "*" into tLz -- this finds all objects that refer to the moving target (5 max so far)
   repeat with x = 1 to the number of lines of tLz -- now a short list instead of everything
      put line x of tLz into tLine
      makeLine tLine -- makeLine is a function in the main stack that draws lines between 2 locs
   end repeat
end Linz
is fast enough to give me rubber banding of the lines connecting to the moving object. I updated the lines function to only deal with the affected lines and trimmed everything else I could to streamline operations so that I am now satisfied with the results.

Thanks for the help from the forum, and I hope this will help someone else in the future.

Thank You!

kdjanz
Posts: 300
Joined: Fri Dec 09, 2011 12:12 pm
Location: Fort Saskatchewan, AB Canada

Re: Moving objects

Post by kdjanz » Tue Apr 06, 2021 3:21 am

Last post on this I promise, but I'm pleased enough that I have to show this off:
FlowChart2.png
I've had to stretch my boundaries on this by having to use a bit of Regex and even had to dust off the trig to use the atan2 function (after translating a bit of javascript from stack overflow. Thanks to Brian Milby since I am using his main script from ScriptTracker as my example in this diagram.

Now I want to expand the canvas to add all the scripts of all the objects in the whole stack! :D Wish me luck, I'm diving deep.

stam
Posts: 2679
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Moving objects

Post by stam » Tue Apr 06, 2021 7:48 am

Well done! looks very cool ;)

Post Reply

Return to “Getting Started with LiveCode - Complete Beginners”