|
|
|
Copy My Text
Added on 11/29/1999
|
I am setting up a Director project and I want to be able to copy text from it to the user's clipboard so that it can be used in other applications. I have tried the copy and paste behavior in the behavior database, but this required the fields to be editable. I need to "lock" my text, but I want users to be able to copy it out if they want to. Can you help?
Get the source
With editable text we can easily use the selStart, selEnd and selection calls in Director to grab the section of text that is currently selected by the user. With non-editable fields, however, clicking on the sprite will do nothing. That's where we use a little lingo. While we can not use the same selection keywords, we can track this with properties and fake this using the "hilite" command.
The hilite command does exactly what one would expect. You can call it to hilite a word, line, set of chars, etc. So how do we know what to hilite? One very helpful property of field members is the mouseChar property. Like the mouseLine or mouseWord property, it can be used to get the number of the char closest to the mouse's current location. So how to we set the selection? Well, the field will need 2 properties. 1 for the starting character and another for the ending character. When the mouse is pressed we record the character closest to the mouse click. Then as we move the mouse we constantly are updating the end character and hiliting all characters in between.
One thing we need to consider is to be sure that the smaller number is always put first. By simply comparing the two values we can set which ever is smaller in the command and hilite accordingly. To allow the user to clear the selection we can add a condition that states that if the start and end characters are the same then the selection is removed. Also, we need to accommodate multiple fields. On the mouseDown of the behavior we can set a global for the current sprite. This way we can pull the value of the last used sprite and send the message accordingly.
The copy command is set up as a send sprite call. To copy the currently selected text we read the global that tells us where the current selection sprite is and then send a message to it telling it to copy its current selection to the clipboard. The sprite then makes a temporary field member, drops in the text, uses the copyToClipboard command and then removes the extra member. The beauty of this method is that it works in projectors as well as in Shockwave!
To dress it up a little more we can add a line that sets the cursor to a standard text I-Beam and add a method to clear the selections of all other fields when a new one is clicked. Below is the code.
--Copyright 1999 Chuck Neal
--chuck@mediamacros.com
--If you find this code helpful, send me an e-mail and let me know. :-)
property spriteNum, startChar, endChar
global currentField
on mouseDown me
sendAllSprites(#clearSelection)
cursor 1
currentField = spriteNum
startChar = the mouseChar
endChar = the mouseChar
(the actorList).add(me)
end
on stepFrame me
if endChar <> the mouseChar then
endchar = the mouseChar
if endChar > startChar then
sprite(spriteNum).member.char[startChar..endChar].hilite()
else if endChar < startChar then
sprite(spriteNum).member.char[endChar..startChar].hilite()
else
theLines = sprite(spriteNum).member.line.count
sprite(spriteNum).member.line[theLines + 1].hilite()
end if
end if
end
on mouseUp me
cursor -1
if endChar > startChar then
sprite(spriteNum).member.char[startChar..endChar].hilite()
else if endChar < startChar then
sprite(spriteNum).member.char[endChar..startChar].hilite()
else
theLines = sprite(spriteNum).member.line.count
sprite(spriteNum).member.line[theLines + 1].hilite()
end if
if (the actorList).getOne(me) <> 0 then
(the actorList).deleteOne(me)
end if
end
on mouseUpOutside me
cursor -1
if endChar > startChar then
sprite(spriteNum).member.char[startChar..endChar].hilite()
else if endChar < startChar then
sprite(spriteNum).member.char[endChar..startChar].hilite()
else
theLines = sprite(spriteNum).member.line.count
sprite(spriteNum).member.line[theLines + 1].hilite()
end if
if (the actorList).getOne(me) <> 0 then
(the actorList).deleteOne(me)
end if
end
on copySelected me
if startChar < endChar then
theSelection = sprite(spriteNum).member.char[startChar..endChar]
else
theSelection = sprite(spriteNum).member.char[endChar..startChar]
end if
--create temp member
tempMember = new(#field)
tempmember.text = theSelection & " "
copyToClipboard tempMember
erase tempMember
end
on clearSelection me
theLines = sprite(spriteNum).member.line.count
sprite(spriteNum).member.line[theLines + 1].hilite()
end
on endSprite me
if (the actorList).getOne(me) <> 0 then
(the actorList).deleteOne(me)
end if
end
on getBehaviorDescription me
describe = "This behavior alows non-editable field members to copy text to the clipboard. This is not a variable, it actually writes to the Mac/Windows clipboard so the data is available to other fields as well as other programs." & return
describe = describe & "Note- this will only work with field members, not text members. Also note that using command/Ctrl + C in authoring mode will not work, as Director will intercept these events."
describe = describe & return & "Call the copy function using... sendSprite(x, #copySelected)"
return describe
end
So what now? Well, try adding a feature to drag and drop text. What about adding a recorder to track what users copy, etc. Play with it and see what you come up with.
|
|