8 Replies Latest reply on Jun 25, 2011 9:29 AM by jchunick

    Drag In A Text Member...

    GRAMOPHONE Level 1

      Hi,

      I don't lnow if this can be possible.

      Is there a way or an Xtra that you can use so that you can reposition lines in a text or input field by clicking

      and dragging it up or down?

       

      Any light on this will be appreciated.

       

      Thanks

        • 1. Re: Drag In A Text Member...
          jchunick Level 2

          quite possible. Really late here so I will look at this tomorrow again when I have more time.

          • 2. Re: Drag In A Text Member...
            GRAMOPHONE Level 1

            Hi Jchunick,

            I'll wait for your help...

             

            Thanks

            • 3. Re: Drag In A Text Member...
              Production Monkey Level 3

              I threw some code together last weekend. It's about 90% complete - just needs some tweaking, additions, testing.  I generally don't post code I'm not happy with but I don't feel like working on this anymore and what I have completed should be helpful.

               

              For what it is worth, the following is a behavior that should be attached to a Text member (not a field) that will enable selecting and dragging of text. I wrote this in D10. I have not tested in D11

               

              --  Text Drag Behavior-----

               

              property  pMe  -- this sprite
              property  pMem  -- this sprite's member
              property  pState   --  #NotSelected, #Selected, #Selecting, #Dragging
              property  pLastRange  -- range of chars that were selected before a drag operation
              property  pSelectedText  -- text string from selection before a drag operation
              property  pInsertCursor  -- sprite for flashing insertion point
              property  pOffset  --  offset of pInsertCursor from mouse cursor
              property  pBlinkTimer  -- timeout object to flash pInsertCursor on and off.

               


              on beginSprite me
                pMe = sprite(me.spriteNum)
                pMem = pMe.member
                pLastSelection = Void
                pOffset = point(20,20)
               
                if me.haveSelection(pMem.selection) then
                  pState = #Selected
                else
                  pState = #NotSelected
                end if
              end beginSprite

               


              on mouseDown me
                case pState of
                  #NotSelected:
                    pState = #Selecting
                   
                  #Selected:
                    if me.inSelectionRange(pMem.selectedText.range) then  -- starting drag operation
                      pState = #Dragging
                      pLastRange = pMem.selectedText.range
                      pSelectedText = pMem.selectedText.text
                      me.addInsertCursor()
                      exit  -- stops "pass" and thus the text stays selected
                     
                    else
                      pState = #NotSelected
                    end if
                end case
               
                pass  -- send event to text sprite so it can do its thing
              end mouseDown

               


              on mouseUp me
                case pState of
                  #Selecting:
                    if me.haveSelection(pMem.selection) then
                      pState = #Selected
                    else
                      pState = #NotSelected
                    end if
                   
                  #Dragging:
                    me.removeInsertCursor()
                    CurCharPos = pMe.pointToChar(_mouse.mouseLoc - pOffset + point(0,5))
                   
                    if CurCharPos = -1 then  -- outside the text member
                      pState = #Selected
                      exit
                    end if
                   
                    if me.inSelectionRange(pLastRange) then -- this is a deselect operation
                     
                      pMem.Selection = [CurCharPos,CurCharPos]
                      pState = #NotSelected
                     
                    else  -- delete selected text and paste it into its new position
                      delete pMem.char[pLastRange[1]..pLastRange[2]]
                     
                      if CurCharPos < pLastRange[1] then
                        put pSelectedText after pMem.Char[CurCharPos]
                        pMem.Selection = [CurCharPos , CurCharPos + pSelectedText.char.count]
                      else
                        put pSelectedText after pMem.Char[CurCharPos - pSelectedText.char.count]
                        pMem.Selection = [CurCharPos - pSelectedText.char.count, CurCharPos ]
                      end if
                      pState = #Selected
                    end if
                end case
              end mouseUp

               


              on enterFrame me
                -- ** Debug Code
                --  put pMem.member.selection
                --  put pMem.selectedText.text
                --  put pMem.selectedText.range
               
                case pState of
                  #NotSelected:
                    if me.haveSelection(pMem.selection) then pState = #Selected
                   
                  #Dragging:
                    pInsertCursor.loc = _mouse.mouseLoc - point(20,20)  -- insertion cursor tracks mouse cursor
                end case
              end enterFrame

               


              on haveSelection me, Selection
                if Selection[1] = Selection[2] then return False
                return True
              end haveSelection

               


              on inSelectionRange me, Range
                CurCharPos = pMe.pointToChar(_mouse.mouseLoc )
                if CurCharPos >= Range[1] and CurCharPos <= Range[2] then return True
                return False
              end inSelectionRange

               


              on addInsertCursor me
                pInsertCursor = sprite(me.getOpenChannel())
                if pInsertCursor = sprite(0) then exit
               
                pInsertCursor.puppet = true
                pInsertCursor.member = new(#Text)
                pInsertCursor.member.text = "|"
                pInsertCursor.loc = _mouse.mouseLoc - pOffset
                pInsertCursor.locZ = 10000
                pInsertCursor.ink = 36
               
                pBlinkTimer = timeout().new("BlinkTimer", 300, #toggleBlink, me)
              end addInsertCursor

               


              on removeInsertCursor me
                pInsertCursor.member.erase()
                pInsertCursor.visible = true
                pInsertCursor.puppet = false
                pInsertCursor = void
               
                if pBlinkTimer.objectP then
                  pBlinkTimer.forget()
                  pBlinkTimer = void
                end if
              end removeInsertCursor

               


              on endSprite me
                if pInsertCursor.objectP then me.removeInsertCursor()
              end endSprite

               


              on toggleBlink me, Timeob
                pInsertCursor.visible = not pInsertCursor.visible
              end toggleBlink

               


              -- returns first unused sprite channel
              on getOpenChannel me
                repeat with SpriteChannel = 1 to _movie.lastChannel
                  if sprite(SpriteChannel).member = (member 0 of castLib 0) then
                    return SpriteChannel
                  end if
                end repeat
                return 0
              end getOpenChannel
              --------------------------------------------------------------------------

              • 4. Re: Drag In A Text Member...
                GRAMOPHONE Level 1

                Sorry, but it doesn't do anything. I tested it

                on Director 10.1.

                • 5. Re: Drag In A Text Member...
                  Production Monkey Level 3

                  I wrote the code on D10.1.1  so if it works on my system, it should work on yours.

                  • 6. Re: Drag In A Text Member...
                    jchunick Level 2

                    try this code:

                     

                     

                    property pSp

                    property pMem

                    property pDragMem

                    property pDragSp

                    property pLine

                    property pDrag

                    property pMod

                     

                    on beginSprite me

                      pSp = sprite(me.spriteNum)

                      pMem = pSp.member

                      pMem.fontStyle = [#plain]

                      -- create a new text member

                      pDragMem = new(#text)

                      pDragMem.media = pMem.media

                      pDragMem.color = color(200,200,200)

                      pDragMem.text = ""

                      pDrag = FALSE

                      pMod = pMem.line[1].fontSize / 2

                    end

                     

                    on mouseDown me

                      -- get the line of text clicked on

                      pLine = pSp.pointToLine(_mouse.mouseLoc)

                      if pLine > 0 then

                        pDrag = TRUE

                        -- add text to draggable text member

                        pDragMem.text = pMem.line[pLine]

                        -- create a sprite

                        _lastChannel = _movie.lastChannel

                        repeat with i = _lastChannel down to 1

                          if sprite(_lastChannel).member = (member 0 of castLib 0) then

                            pDragSp = channel(_movie.lastChannel).makeScriptedSprite(pDragMem, _mouse.mouseLoc)

                            exit repeat

                          end if

                        end repeat

                      end if

                    end

                     

                    on enterFrame me

                      if pDrag then

                        pDragSp.loc = _mouse.mouseLoc

                        currLine = pSp.pointToLine(_mouse.mouseLoc)

                        if currLine > 0 then

                          pMem.fontStyle = [#plain]

                          pMem.line[currLine].fontStyle = [#underline]

                        end if

                        if (currLine = 1) and  (_mouse.mouseLoc[2] < (pSp.top + pMod)) then

                          pMem.line[1].fontStyle = [#Overline]

                        end if

                      end if

                    end

                     

                    on mouseUp me

                      pDrag = FALSE

                      newLine = pSp.pointToLine(_mouse.mouseLoc)

                      -- get old line text

                      strNewLine = pMem.line[pLine]

                     

                      if newLine = 1 then

                        -- delete old line

                        pMem.line[pLine].delete()

                        -- add the line were the mouseUp happened

                        pMem.line[newLine] = strNewLine & RETURN & pMem.line[newLine]

                      end if

                      if newLine > 1 and pLine > newLine then

                        pMem.line[pLine].delete()

                        pMem.line[newLine] = pMem.line[newLine] & RETURN & strNewLine

                      end if

                      if newLine > 0 and pLine < newLine then

                        pMem.line[pLine].delete()

                        pMem.line[newLine] = strNewLine & RETURN & pMem.line[newLine]

                      end if

                      -- set fontStyle to clear the underline

                      pMem.fontStyle = [#plain]

                      -- remove sprite

                      channel(pDragSp.spriteNum).removeScriptedSprite()

                    end

                     

                    on destroyObjects me

                      if objectP(pDragMem) then

                        pDragMem.erase()

                      end if

                    end

                     

                    on stopMovie me

                      me.destroyObjects()

                    end

                     

                    on endSprite me

                      me.destroyObjects()

                    end

                     

                    -----------------------------------------

                    Edit: this is a tested and fully working example.

                    • 7. Re: Drag In A Text Member...
                      GRAMOPHONE Level 1

                      Hey, It sure works, and it should be perfect if the square with the line could be constrained to the txt member, but I don't know how this can be accomplished.

                       

                      Thanks a lot!

                      • 8. Re: Drag In A Text Member...
                        jchunick Level 2

                        you could certainly constrain it. I will, however, leave that up to you (hint: add code in the same handler where the mouse loc is set to the drag sprite; also check out the constrain methods and constraint sprite property).