This blog post is a step by step how to tutorial for creating a custom bullet masked password field in LiveCode that may be used in your own projects. All the necessary password field script handlers and functions are included. LiveCode already has a quick and easy built-in method to get an asterisk masked password with this simple command.
ask password “Please enter your password:”
Which creates the following password entry modal dialog with the password field’s text entry masked by asterisks. When the dialog is dismissed with the (OK) button the password is returned in the default variable “it.”
The ask password command works fine for a simple password dialog but sometimes it’s useful to have a password field that may be used for more custom or more complicated applications. For example, I’m currently in the process of building a brand new version of our DreamLight network rendering utility, DLI_SNUB-Launcher™ from scratch in LiveCode. This will allow us to bring Drag-and-drop-dead-easy™ network rendering setup to Windows users in addition to our current Macintosh users. I had programmed the previous versions of DLI_SNUB-Launcher in Apple’s Xcode, which limits it to Mac users. DLI_SNUB-Launcher has a custom user registration panel that includes a clear text user name field paired with a bullet masked password field. LiveCode doesn’t have a standalone password text field as Xcode does, so I created a custom password field that’s masked with bullets and that is robust enough to handle selection, editing, deleting and pasting into the password field. I thought this custom bullet masked password field would make a good blog post that I could share with other LiveCode developers.
UPDATE (5/31/15): I’ve revised this post with additional information for a simple hack fix to allow pasting from the clipboard despite a bug in LiveCode where implementing a standard Edit menu with a Paste menu item using command-V or (control-V on Windows) blocks the pasteKey message from reaching the password field. This is done by creating a global list of any objects that need to receive pasteKey messages and then manually dispatching the message to those objects when needed.
Scripts for Creating a Custom Bullet Masked Password Field in LiveCode
I started by creating a basic LiveCode text field, in this case I named it UserPass. Then on the Property Inspector for the field I created a Custom Property named cpClearText. This property field will hold the clear text password while the field contents will be filled with bullet characters to mask the content. I then used the following handlers in the password field’s script, starting with declaring local variables.
-- Password Field with bullet masked text by DreamLight.com -- The cpClearText custom property contains the clear text password -- Bullets are placed in the field contents for viewing -- full editing including selection, deletion and pasting is supported global gPasteKeyList -- list of object names with PasteKey handlers local pBulletCodeMac = 165 local pBulletCodeWin = 149 local pBulletChar local pSelectStart, pSelectEnd
The first handler, initializeField, is manually sent to the password field by the stack’s preOpenStack handler. It sets the field script’s local variables to choose the appropriate bullet character based on the current platform the stack is running on.
on initializeField initialPassword --manually sent to the field from the preOpenStack -- choose the platform specific bullet character if the platform = "MacOS" then put numToChar( pBulletCodeMac ) into pBulletChar else -- win put numToChar( pBulletCodeWin ) into pBulletChar end if set the cpClearText of me to initialPassword bulletIt -- check object name in to receive pasteKey messages put the short name of me after the last line of gPasteKeyList end initializeField
The next few handlers take care of basic typing into the password field, handling cases where there may be selected characters before a key is pressed.
-- Handle basic typing into the field on keydown tKey put the cpClearText of me into tEditText updateSelection if pSelectEnd >= pSelectStart then -- some text is selected, delete to replace delete char pSelectStart to pSelectEnd of me delete char pSelectStart to pSelectEnd of tEditText end if updateSelection put pBulletChar after char pSelectEnd of me put tKey after char pSelectEnd of tEditText updateClearText tEditText end keyDown on updateSelection put word 2 of the selectedChunk of me into pSelectStart put word 4 of the selectedChunk of me into pSelectEnd end updateSelection on updateClearText tPassword set the cpClearText of me to tPassword textChanged end updateClearText
The next few handlers take care of deleting and pasting into the password field.
-- Handle deleting and pasting on backspaceKey put the cpClearText of me into tEditText updateSelection if pSelectEnd >= pSelectStart then -- some text is selected to delete delete char pSelectStart to pSelectEnd of me delete char pSelectStart to pSelectEnd of tEditText else delete char pSelectEnd of me delete char pSelectEnd of tEditText end if updateClearText tEditText end backspaceKey on deleteKey -- forward delete key put the cpClearText of me into tEditText updateSelection if pSelectEnd >= pSelectStart then -- some text is selected to delete delete char pSelectStart to pSelectEnd of me delete char pSelectStart to pSelectEnd of tEditText else delete char pSelectStart of me delete char pSelectStart of tEditText end if updateClearText tEditText end deleteKey on pasteKey put the clipboardData["text"] into tPasteText if tPasteText is not empty then put the cpClearText of me into tEditText -- replace returns with spaces on the tPasteText put replaceText(tPasteText,return,space) into tPasteText put makeBullets( the length of tPasteText ) into tBullets updateSelection if pSelectEnd >= pSelectStart then -- some text is selected, delete to replace delete char pSelectStart to pSelectEnd of me delete char pSelectStart to pSelectEnd of tEditText end if updateSelection put tBullets after char pSelectEnd of me put tPasteText after char pSelectEnd of tEditText updateClearText tEditText end if end pasteKey function makeBullets howMany put empty into tBullets repeat howMany times put pBulletChar after tBullets end repeat return tBullets end makeBullets
The next few handlers deal with dragging and dropping text onto the password field.
-- Handle dragging and dropping text onto the field on dragEnter set the dragAction to "copy" end dragEnter on dragDrop put the dragData["text"] into tPasteText if tPasteText is not empty then -- replace returns with spaces on the tPasteText put replaceText(tPasteText,return,space) into tPasteText setPassword tPasteText end if end dragDrop
The final few handlers take care of internal and external communications to set and get the password. Other scripts can send the setPassword command to set the password and can call the getPassword function, using value( “getPassword()”, field “UserPass”), to get the current password.
-- Handlers and functions to set and get the password on setPassword tPassword -- set the password such as when loading a pre-saved password updateClearText tPassword bulletIt end setPassword function getPassword -- return the password saved in the cpClearText custom property return the cpClearText of me end getPassword on bulletIt -- process the custom property cpClearText -- and put the bulleted version in the field for show put empty into tBullets -- empty visible field repeat for each character tChar in the cpClearText of me put pBulletChar after tBullets end repeat put tBullets into me end bulletIt
UPDATE NOTE: There’s an issue in LiveCode where if you are implementing a standard Edit menu with a Paste item it will block the pasteKey messages from reaching the password field. In order for the paste functionality to work you’ll need to add the following code to your Edit menu button to manually dispatch a pasteKey message to the password field object.
global gPasteKeyList -- list of object names with PasteKey handlers --The following menuPick handler was generated by the Menu Builder. on menuPick pWhich switch pWhich case "Cut" cut break case "Copy" copy break case "Paste" -- Paste menu blocks pasteKey messages so manually dispatch -- pasteKey if focused object has a pasteKey handler put the focusedObject into tObject if gPasteKeyList contains the short name of tObject then dispatch "pasteKey" to tObject else paste end if break case "Clear" clear break case "Preferences" -- do preferences handling here break end switch end menuPick
In the above pasteKey hack fix I’m using a manual global list of object names that need to receive pasteKey messages. This method works in the IDE, with Suspend LiveCode UI, as well as in standalone apps, even if the scripts are encrypted in password protected stacks. Other more automatic methods such as searching “the script” property for “on pasteKey” or querying the revAvailableHandlers or get revAvailableHandlers() for “pasteKey” fail in standalone apps in password protected stacks because the handlers are encrypted.
If any other LiveCode developers find this custom bullet masked password field useful, feel free to use it in your own projects. -ENJOY!
At this point I’ve ported the entire DLI_SNUB-Launcher from Apple’s XCode to LiveCode. It’s up and running, including a pretty robust custom built implementation of a drawer window because that’s another feature of XCode that LiveCode lacks. Stay tuned, I may make a future blog post sharing my custom drawer window implementation. I’m currently in the process of adding a few new features to DLI_SNUB-Launcher as well as adding cross-platform functionality to allow it to run on Windows as well. Once the new features are ready I’ll release the new version DLI_SNUB-Launcher 2.0 on our DLI_SNUB-Launcher WebShop page.
Here’s the current 2.0 GUI in LiveCode under development as it looks on Mac OS X Snow Leopard with the custom-built drop down drawer open at the bottom. It’ll look different on different versions of the OS and different platforms. Stay tuned!
DLI_SNUB-Launcher 2 – First Test Launch on Windows with LiveCode
[Update 5/13/15] Wow. I’m impressed with LiveCode so far. While still beta testing DLI_SNUB-Launcher 2 on Mac OS X I figured I’d have LiveCode generate a build for Windows. That way I could give it a quick spin to see how much work it will take to release the Windows version. I expected to be greeted with a bunch of error messages but it was up and running within minutes, without any errors. Everything worked right off the bat from the exact same code base, from the user panel dialog with my custom bullet masked password field to my custom built slide out drawer on the bottom. Looks like all I’ll have to adjust is to flip the path delimiter from the Mac OS X / Unix / LiveCode forward slash to the Windows backslash, change some defaults and clean up some of the text placement on some of the buttons. Cool!