-- USAGE/DESCRIPTION:
-- Automatic Tabbing (and shift-tabbing) between editable text-sprites
-- also includes some other text "eating" functions
-- REQUIRES:
-- nothing
-- CAST CONVENTIONS:
-- none
-- SCORE CONVENTIONS:
-- none
-- USEFUL MESSAGES:
-- none
-- PARAMETERS:
-- parameter: explanation
-- OWNER: roymeo
-- HISTORY/NOTES:
-- 20011218-roymeo v1.0 created
-- 20020425-roymeo v1.1 added AutoTabResetFocus method
-- 20020425-roymeo v2.0 added ReturnAs, and Block/RestrictTo on characters
-- 20020425-roymeo v2.1 added BACKSPACE & Delete Key as a pass
-- 20020912-roymeo v2.2 added arrow key passthrough
-- 20021213-roymeo v2.3 added Maximum number of characters restriction (changed the position of the arrowkey detection)
-- 20030514-roymeo v2.4 block Insert Key (numtochar(5))
-- 20040503-roymeo v2.5 added thisKey to hold 'the key' (though if we're too slow, this may not work...be passing the wrong value)
-- Note: on 20020720 tests determined that ONLY the following characters:
-- "(),:;<>[ SPACE
-- found on the standard keyboard are not valid in email addresses (all other stardard keys were OK)
-- Note: was also found that the following characters are not allowed in filenames
-- /:;*?<>|~_.,"
property spriteNum -- spritenumber
property ploSibs -- list of other AutoTabbing Script objects
-- SCORE HELPER METHODS
on getBehaviorDescription me
return( "Editable Field/Text AutoTabbing" )
end
on getBehaviorTooltip me
return ( getBehaviorDescription(me) )
end
on getPropertyDescriptionList me
set pL = [:]
addProp pL, #psReturnAs, [#comment: "Handle RETURN as:",
#format: #symbol,
#default: #Tab,
#range: [#Tab,#Block,#Return] ]
addProp pL, #pbBlockCharacters, [#comment: "Handle other characters how:",
#format: #symbol,
#default: #Block,
#range: [#Block,#RestrictTo] ]
addProp pL, #ptCharacters, [#comment: "Characters to Block/RestrictTo:",
#format: #string,
#default: "" ]
pL.addProp(#piMaxChars, [#comment: "Maximum number of characters to allow: (0 = unrestricted)",
#format: #integer,
#default: 0] )
return(pL)
end
on isOKToAttach (me, aSpriteType, aSpriteNum)
-- cannot be attached to script channel
if (aSpriteType = #graphic) then
-- must be text or field
case (sprite(aSpriteNum).member.type) of
#text, #field:
isOK = TRUE
otherwise
isOK = FALSE
end case
else
isOK = FALSE
end if
return isOK
end isOKToAttach
-- BEHAVIORS
on new me
return me
end
on endSprite me
destroy(me)
end
on destroy me
-- destructor. void out all properties here (especially objects)
psReturnAs = VOID
pbBlockCharacters = VOID
ptCharacters = VOID
ploSibs.DeleteOne(me)
ploSibs = VOID
end
on beginSprite me
-- be careful you don't try to reference sprite properties that
-- don't exist yet here such as the rect, etc.
pbBlockCharacters = (pbBlockCharacters = #Block)
passList = []
SendAllSprites(#xRegisterAutoTabbingSiblings, passList)
me.SetEditableState(TRUE)
me.AutoTabResetFocus()
end
on xRegisterAutoTabbingSiblings me, passList
me.ploSibs = passList
me.ploSibs.append(me)
end
on SetEditableState me, bState
sprite(me.spriteNum).member.editable = bState
end
on xAutoTab me
iNextPos = me.xGetNextPos()
me.ploSibs[iNextPos].xFocus()
end
on xGetNextPos me
iPos = me.ploSibs.getOne(me)
iCount = me.ploSibs.count
-- funky function to get the position of the next one in either direction.
iNextPos = ( (iPos + the shiftDown * (iCount - 2)) mod iCount) + 1
return iNextPos
end
on xFocus me
the keyboardFocusSprite = me.spriteNum
end
on keyDown me
thisKey = the key
case thiskey of
TAB:
me.xAutoTab()
BACKSPACE, (numToChar(127)):
-- backspace (numToChar(8)) and PC Delete key NumToChar(127)
pass
(numToChar(5)):
-- the INSert key
stopEvent
-- Home = 1, End = 4, PageUp = 11, PageDown = 12
RETURN:
case psReturnAs of
#Tab:
me.xAutoTab()
#Block:
stopevent
#Return:
if me.isThereStillSpaceForThisChar() then
pass -- fits
else
stopevent -- does not fit
end if
end case
otherwise
if (charToNum(thiskey) > 27) AND (charToNum(thiskey) < 32) then
pass --allow the arrow keys through! (28,29,30,31)
else
if pbBlockCharacters then
-- we're blocking the characters in the list.
if (ptCharacters contains thiskey) then
stopevent -- character in list
else
-- char not in list. does it fit the max size?
if me.isThereStillSpaceForThisChar() then
pass -- fits
else
stopevent -- does not fit
end if
end if
else
-- we're allowing only the characters in the list
if (ptCharacters contains thiskey) then
-- is in the list. does it fit the max size?
if me.isThereStillSpaceForThisChar() then
pass -- fits
else
stopevent -- does not fit
end if
else
stopevent -- not in the list
end if
end if
end if
end case
end
on AutoTabResetFocus me
if (me.ploSibs[1] = me) then
me.xFocus()
end if
end
on isThereStillSpaceForThisChar me
if me.piMaxChars then
-- we do need to restrict
lSel = sprite(spriteNum).member.selection -- [SelStart, SelEnd]
-- checking the selection in case the box is full but they'll be replacing a character(s)
-- if the box isn't full -OR- we've got at least one character selected, TRUE/pass
return (sprite(spriteNum).member.text.length < me.piMaxChars) OR NOT(lSel[1] = lSel[2])
else
-- unlimited characters, no restriction
return TRUE
end if
end
Contact
MMI
36 South Court Sq
Suite 300
Newnan, GA 30263
USA