Page 1 of 2

Here's how to drag-reorder lines in a list field

Posted: Sun Oct 27, 2019 8:47 am
by MichaelBluejay
As usual, I'm updating this original post with tweaks to make it useful as a complete solution without readers having to scour the whole thread.

Seems like no one's published a simple way to drag-reorder lines in a list field (at least not that I could easily find with a cursory search), so I thought I'd publish my version here. Here's how it can be done with only 14 lines of code:

Code: Select all

local lineText, lastPosition

on mousedown
   put the value of the mouseline into lineText
   put the mouseline into lastPosition
 end mousedown

on mousemove
   if the mouse is down and the mouseline is not lastPosition and the mouseline is not empty and word 2 of the mouseLine <= the number of lines of me then
      delete lastPosition
      if word 2 of the mouseline is the number of lines of me and the last char of me is not cr then put cr after me
      put lineText & cr before the mouseline
      put the mouseline into lastPosition
      select the mouseline
   end if
end mousemove
I did a similar thing in HyperCard decades ago, but I painstakingly calculated the line under the mouse by using the mouseloc and the number of pixels for the height of each line. LiveCode additions like the mouseline make the code a lot cleaner and shorter.

About that, can anyone improve on this and make the code even shorter than mine? Here's what I suggest as criteria for submissions:

(1) Must show either the line of text being moved, or a marker between the lines where the dropped line will go when the mouse is released.
(2) Must not use repeat while the mouse is down, which is a no-no as it ties up the CPU.
(3) Must not ever mangle the text.
(4) Must not malfunction if the user moves the mouse pointer out of the list field (and possibly then back into the field) while the mouse is still down.
(5) Acceptable to drag a line to an unpopulated blank area (as in my example).
(6) Handler on and end count as lines, blank lines don't.

Re: Here's how to drag-reorder lines in a list field

Posted: Sun Oct 27, 2019 10:55 am
by jmburnod
Hi,
Thanks for sharing
Clever way. I'm afraid i can't do better
Best regards
Jean-Marc

Re: Here's how to drag-reorder lines in a list field

Posted: Sun Oct 27, 2019 2:11 pm
by [-hh]
Sadly it's not that simple.
This doesn't work if the list field has more lines than the visible lines:
when the cursor leaves the field at bottom while the mouse is down this mangles the field's contents.

Re: Here's how to drag-reorder lines in a list field

Posted: Sun Oct 27, 2019 2:46 pm
by kaveh1000
Hi Michael

Firstly, thank you for your generosity in sharing your tips and tricks. It is very much appreciated! I will go through your code later, but I just thought I would point to Scott Rossi's great stack in case you have not seen it:

http://www.google.com/url?q=http%3A%2F% ... EzPec-H5Wg

I have modified it and it works nicely. It is a bit too complex for my needs so I have taken out some of the flashy gizmos, but very nice interface.

Regards
Kaveh

Re: Here's how to drag-reorder lines in a list field

Posted: Sun Oct 27, 2019 7:13 pm
by MichaelBluejay
Yes, kaveh, I saw Rossi's "Get in Line", but like I said, seems like no one's published a *simple* way to reorder lines. Get in Line is pretty convoluted. Also, even with all that code, the dragged line isn't limited to the y axis, it goes left and right with the mouse.

I fixed a bug in the original code I posted. My test field had invisible CR's at the end so I didn't see that it mangled the text if those CR's weren't there. I fixed that, at the expense of adding a few more lines of code.

Re: Here's how to drag-reorder lines in a list field

Posted: Sun Oct 27, 2019 7:39 pm
by MichaelBluejay
BTW, here's what I'd really like to see in LiveCode:

.....set the dragReorder of fld "myListField" to true

.....(along with dragStartingLine and dragEndingLine, returning integers).

Thirty-two years of XTalk, that's long enough to wait for such basic functionality, I think.

Re: Here's how to drag-reorder lines in a list field

Posted: Sun Oct 27, 2019 9:23 pm
by [-hh]
We all like it to see you making progress with your code.
Sadly it still doesn't work when the field has vscroll>0 and the mouse moves below the field while down:

Make a list field of height 200. Put 20 lines of size > 10 pt in it.
field_before_dragging.png
field_before_dragging.png (6.84 KiB) Viewed 8305 times
Drag line 7 down, hold the mouse down and move it beyond the bottom of the field. This is the result with your script above (version 2 of your edited original post). [Or use the scrollbar ...]
field_after_dragging.png
field_after_dragging.png (21.11 KiB) Viewed 8305 times
Moreover you could think about NOT using mousemove which is ALWAYS in action while the cursor is over the field, not only while dragging?

As you ask for other approaches: Here is an example for that. It still uses your idea of working with the mouseLine.
As your problems above show, the not-so-simple part is to handle the dragging past the last line. This is solved here by using the smaller of formattedRect of the text and the rect of the field.

Code: Select all

on mouseDown b
  if b=3 then -- right mouseButton
    set the hilitedLine of me to word 2 of the mouseLine
    if the formattedHeight of me < the height of me then
      put the formattedRect of line 1 to -1 of me into fR
      put item 3 of the rect of me into item 3 of fR
    else put the rect of me into fR
    reorder the hilitedText, the hilitedLine of me,fR
  end if
end mouseDown

on reorder hT,hL,fR
  if the mouseloc is within fR then 
    lock screen; delete line hL of me; put cr after me
    put word 2 of the mouseLine into hL
    put hT & cr before line hL of me
    delete char -1 of me
  end if
  set the hilitedLine of me to hL
  if the mouse is down then send "reorder hT,hL,fR" to me in 1 tick
end reorder
(The script uses rightClick for dragging so that you have the ordinary mouseDown also available.)

Re: Here's how to drag-reorder lines in a list field

Posted: Mon Oct 28, 2019 3:38 am
by FourthWorld
MichaelBluejay wrote:
Sun Oct 27, 2019 7:39 pm
BTW, here's what I'd really like to see in LiveCode:

.....set the dragReorder of fld "myListField" to true

.....(along with dragStartingLine and dragEndingLine, returning integers).

Thirty-two years of XTalk, that's long enough to wait for such basic functionality, I think.
It would be difficult to do in other xTalks. But it LC it could be done with a behavior script rather easily.

Re: Here's how to drag-reorder lines in a list field

Posted: Mon Oct 28, 2019 3:43 am
by [-hh]
FourthWorld wrote:It would be difficult to do in other xTalks. But it LC it could be done with a behavior script rather easily.
Why don't you show us then?

Re: Here's how to drag-reorder lines in a list field

Posted: Mon Oct 28, 2019 4:12 am
by FourthWorld
[-hh] wrote:
Mon Oct 28, 2019 3:43 am
FourthWorld wrote:It would be difficult to do in other xTalks. But it LC it could be done with a behavior script rather easily.
Why don't you show us then?
This evening I'm coding to pay my bills. When I have more volunteer time to devote to writing free code I'll jump at the chance.

Re: Here's how to drag-reorder lines in a list field

Posted: Mon Oct 28, 2019 5:18 am
by [-hh]
Here is a function and based on that a demo stack that lets you also drag-reorder contiguous or non-contiguous blocks of lines in a list field: listUtility_100

Re: Here's how to drag-reorder lines in a list field

Posted: Mon Nov 11, 2019 12:40 pm
by MichaelBluejay
In using my script in my own project, I realized that we usually won't want to add new blank lines to the field when the user keeps dragging below the existing list. Usually if the user drags a line to the bottom of a list, then that's as far as we want that line to go. In editing the script to limit a dragged line to be the last line in the script, I saw that I could do that with *less* code. So, the new, improved code is a mere 14 lines long. I posted the updated version in the first post of this thread.

Re: Here's how to drag-reorder lines in a list field

Posted: Tue Nov 12, 2019 9:52 pm
by bn
If you want to preserve styles (like bold, underline, italic etc) when reordering then this script might be helpful

Code: Select all

local sClicked, sArray, sMovingText, sLastLineNum

on mousedown
   put word 2 of the mouseLine into sClicked
   put the styledText  of me into sArray
   put sArray[sClicked] into sMovingText
   put empty into sLastLineNum
end mousedown

on mouseMove
   put word 2 of the mouseLine into tLineNum
   if tLineNum is empty or the mouse is not down then exit mouseMove
   
   ## don't do swapping if the lineNumber has not changed
   if tLineNum = sLastLineNum then exit mouseMove
   
   put tLineNum into sLastLineNum
   
   ## swap here
   put sArray[tLineNum] into sArray[sClicked]
   put sMovingText into sArray[tLineNum]
   
   lock screen
   put the vScroll of me into tScroll
   set the styledText of me  to sArray
   set the scroll of me to tScroll
   select line tLineNum of me
   unlock screen
   put tLineNum into sClicked
end mouseMove
Kind regards
Bernd

Re: Here's how to drag-reorder lines in a list field

Posted: Wed Nov 13, 2019 8:29 am
by bn
This is a version of drag-reorder that also keeps formatting of textStyles this time using htmlText
It is functionally equivalent to the version above that uses styledText.

Code: Select all

local sClicked, sMovingText, sLastLineNum

on mousedown
   put word 2 of the mouseLine into sClicked
   put the  htmlText of line sClicked of me into sMovingText
   put empty into sLastLineNum
end mousedown

on mouseMove
   put word 2 of the mouseLine into tLineNum
   if tLineNum is empty or the mouse is not down then exit mouseMove
   
   ## don't swapp unless lineNumber has changed
   if tLineNum = sLastLineNum then exit mouseMove
   
   put tLineNum into sLastLineNum
   
   lock screen
   put the vScroll of me into tScroll
   # swapping
   set the htmlText of line sClicked of me to the htmlText of line tLineNum of me 
   set the htmlText of line tLineNum of me to sMovingText
   # end swapping
   set the vScroll of me to tScroll
   select line tLineNum of me
   put tLineNum into sClicked
   unlock screen
end mouseMove

Kind regards
Bernd

Re: Here's how to drag-reorder lines in a list field

Posted: Mon Feb 01, 2021 5:54 am
by dalkin
I came across this code the other day (see the first post in this thread) and while it works on a Mac in a scrolling list field, it's throwing an error in a Windows standalone, stalling as per the screenshot. Any ideas would be most welcome. None of the terms eg. 'lastPosition' are in the dictionary so I don't have the knowledge to sort it.
Screen Shot 2021-02-01 at 12.32.02 pm.png
.