-- DISPLAY TEXT -- -- -- 1 Oct 1998: Written for the D7 Behaviors Palette by James Newton -- 28 Oct 1998: Descriptions improved. getPDL simplified, -- mGetTopLeft() added -- 7 Jan 2000: Added isOKToAttach and removed redundant error -- checking code - Karl Miller -- 10 Apr 2002: Support for OSstatictext added for Status Bar display. -- Handler names and properties standardized. -- NOTES FOR DEVELOPERS -- -- COMMUNICATING WITH THE SPRITE -- To set the text of the current sprite's member, use a line similar -- to one of the following: -- -- sendAllSprites(#DisplayText_SetText, aStringToDisplay) -- -- sendSprite(, #DisplayText_SetText, aStringToDisplay) -- -- call(#DisplayText_SetText, displayBehavior, aStringToDisplay) -- -- It is fastest to call the behavior directly. Use code similar to -- the following lines in any script that needs to communicate with -- this behavior often: -- -- property displayBehavior -- -- ... -- displayBehavior = [] -- sendAllSprites(#DisplayText_Enroll, displayBehavior) -- ... -- -- If your _Enroll call fails for some reason, displayBehavior will be -- an empty list. Calling an empty list will not produce an error -- (calling an invalid behavior reference will). It would, however, -- be wise to provide yourself with an authortime alert so that you -- can correct such a problem if necessary: -- -- if displayBehavior.count() = 0 then -- if the runMode = "Author" then -- alert "No 'Display Text' behavior found in frame "the frame -- end if -- end if -- -- Writing this sort of "defensive" code should ensure that any bugs -- that make it through to the finished product are relatively -- harmless. -- ADJUSTING THE WIDTH OF THE SPRITE -- The mBestRect() function is called if you choose the Tooltip -- display type. It modifies the width of the sprite to suit the -- longest line/paragraph of text (field lines and text paragraphs are -- delimited by the RETURN character). -- -- This function uses the charPosToLoc() function to determine the -- length of each line. CharPosToLoc returns the position of the -- bottom left corner of the tested character: if the character tested -- is the final RETURN of a line, then the value returned is -- equivalent to the bottom right of the last visible character in the -- line. -- -- I initially set the width of the member to an extravagantly large -- value, to ensure that no line-wrapping should occur. -- PROPERTY DECLARATIONS -- -- author-defined parameters property displayType -- private properties property spriteNum property mySprite property myMember property myType property myWidthAdjust property myHeightAdjust property myOffStageLoc -- SPRITE EVENTS -- on beginSprite me me.mInitialize() end beginSprite on endSprite me mySprite.visible = TRUE end endSprite -- PRIVATE METHODS -- on mInitialize(me) --------------------------------------------------- -- SENT BY beginSprite() -------------------------------------------------------------------- mySprite = sprite(me.spriteNum) myMember = mySprite.member myType = myMember.type if displayType = me.mGetLocalizedString(#statusBar) then displayType = #statusBar else displayType = #tooltip end if case myType of #field: myWidthAdjust = (myMember.margin + myMember.border) * 2 myHeightAdjust = myMember.margin + (myMember.border * 2) myMember.text = "" #text: myWidthAdjust = 0 myHeightAdjust = 0 myMember.text = "" #OSstatictext: displayType = #statusBar mySprite.text = "" end case if displayType = #tooltip then myMember.boxType = #fixed myOffStageLoc = point (9999, 9999) mySprite.loc = myOffStageLoc end if end mInitialize on mBestRect(me, aString) -------------------------------------------- -- SENT BY DisplayText_SetText() -- ACTION: Sets the rect of myMember to fit snugly round the string -- it displays ------------------------------------------------------------------- myMember.rect = rect (0, 0, 8000, 0) myMember.text = aString -- Needed to update myMember.rect tBestRect = myMember.rect tLine = aString.line.count tWidth = 0 tCheckedChars = 0 -- Determine the length of the longest line repeat while tLine tEndOfLine = offset(RETURN, aString) if not tEndOfLine then -- Only one line remaining tEndOfLine = (the number of chars of aString) + 1 myMember.text = myMember.text&RETURN end if tCheckedChars = tCheckedChars + tEndOfLine tEndPoint = charPosToLoc (myMember, tCheckedChars) tLineWidth = tEndPoint[1] if tLineWidth > tWidth then tWidth = tLineWidth end if delete aString.char[1..tEndOfLine] tLine = tLine - 1 end repeat -- Determine the height of the text tLastChar = myMember.char.count tLastCharLoc = charPosToLoc (myMember, tLastChar) theHeight = tLastCharLoc[2] -- tBestRect[3] = tWidth + 1 tBestRect[4] = theHeight + 1 return tBestRect end mBestRect on mGetTopLeft(me, aLoc, anAlignment, aRect) ------------------------- -- SENT BY DisplayText_SetText() -- INPUT: is a point -- is a symbol -- is the rect of the display member -------------------------------------------------------------------- case anAlignment of #bottomCenter: return aLoc - [aRect.width / 2, aRect.height] #bottomRight: return aLoc - [aRect.width, aRect.height] #bottomLeft: return aLoc - [0, aRect.height] #center: return aLoc - [aRect.width / 2, aRect.height / 2] #topCenter: return aLoc - [aRect.width / 2, 0] #topRight: return aLoc - [aRect.width, 0] otherwise -- treat as #topLeft return aLoc end case end mGetTopLeft -- INTER-SPRITE COMMUNICATION -- on DisplayText_Enroll(me, aList) ------------------------------------- -- CALLED by other objects which need to call this specific behavior -- INPUT: may be a linear list -------------------------------------------------------------------- if ilk (aList) <> #list then return me end if if not aList.count() then aList.append(me) else -- The calling behavior has already found a candidate end if return aList end DisplayText_Enroll on DisplayText_SetText(me, aString, aLoc, anAlignment) --------------- -- CALLED by other objects -- INPUT: should be a string -- should be a point or VOID -- should be of the following values: -- #bottomCenter | #bottomRight | #bottomLeft | #center | -- #topCenter | #topRight | #topLeft -- ACTION: Sets the text of myMember to . If displayType is -- #tooltip, mySprite is placed as near to as -- possible, while the value of determines -- which point of the current sprite is to appear at -------------------------------------------------------------------- -- Ensure parameters are valid if not stringP(aString) then aString = string(aString) end if case ilk(aLoc) of #void, #point: -- nothing otherwise: aLoc = point (0, 0) end case if myType = #OSstatictext then mySprite.text = aString else myMember.text = aString if aString = "" and displayType = #tooltip then -- Hide the empty tooltip mySprite.loc = myOffStageLoc exit else if displayType = #tooltip then tRect = me.mBestRect(aString) case myType of #field: myMember.rect = tRect #text: myMember.width = tRect.width + 5 myMember.height = tRect.height #OSstatictext: end case else tRect = myMember.rect end if tRect = tRect + [0, 0, myWidthAdjust, myHeightAdjust] if displayType = #tooltip then aLoc = me.mGetTopLeft(aLoc, anAlignment, tRect) -- Ensure sprite is fully visible on stage tWidth = (the activeWindow).rect tHeight = tWidth.bottom - tWidth.top tWidth = tWidth.right - tWidth.left tMaxH = tWidth - tRect.width tMaxV = tHeight - tRect.height aLoc[1] = max(0, min(aLoc[1], tMaxH)) aLoc[2] = max(0, min(aLoc[2], tMaxV)) aLoc = aLoc + myMember.regPoint mySprite.loc = aLoc else tLastChar = aString.char.count tTextHeight = myMember.charPosToLoc(tLastChar).locV if tTextHeight > mySprite.height then myMember.boxType = #scroll else myMember.boxType = #fixed end if end if end if end DisplayText_SetText -- UTILITY -- on mGetLocalizedString(me, aStringSymbol) ---------------------------- -- CALLED by getPropertyDescriptionList() and beginSprite() -- INPUT: should be #statusBar | #tooltip -- OUTPUT: returns a language-dependent string -------------------------------------------------------------------- case aStringSymbol of #statusBar: return "status bar (fixed size and position)" #tooltip: return "tooltip (dynamic size and position)" end case end mGetLocalizedString -- BEHAVIOR DESCRIPTION AND PARAMETERS -- on isOKToAttach (me, aSpriteType, aSpriteNum) if aSpriteType = #graphic then case sprite(aSpriteNum).member.type of #field, #text, #OSstatictext: return TRUE end case end if return FALSE end isOKToAttach on getPropertyDescriptionList me tPropertyList = [:] tDefault = me.mGetLocalizedString(#statusBar) if the currentSpriteNum then put sprite(the currentSpriteNum).member.type if sprite(the currentSpriteNum).member.type = #OSstatictext then tRange = [tDefault] else tRange = [tDefault, me.mGetLocalizedString(#tooltip)] end if else -- Director is simply compiling the script tRange = [tDefault] end if tPropertyList[ \ #displayType] = [ \ #comment: "Display Text sprite behaves as a", \ #format: #string, \ #range: tRange, \ #default: tDefault \ ] return tPropertyList end getPropertyDescriptionList on getBehaviorTooltip me return \ "Use with field, text or OSstatictext members."&RETURN&RETURN&\ "Waits for a message from another behavior or"&RETURN&\ "custom handler to display a character string."&RETURN&\ "This behavior is intended to be used with the"&RETURN&\ "Tooltip and Hypertext - Display Status behaviors"&RETURN&\ "to create a status bar or a tooltip under the cursor." end getBehaviorTooltip on getBehaviorDescription me return \ "DISPLAY TEXT"&RETURN&RETURN&\ "This behavior allows you to display a given string in a field or text member. Use it with the Tooltip and Hypertext - Display Status behaviors which need a field or text member in which to display their information. Or create your own custom Lingo to display runtime information, such as the position of the mouse."&RETURN&RETURN&\ "This behavior waits for Lingo commands to tell it what to do. It is not active by itself."&RETURN&RETURN&\ "You can choose between two display types: tooltip and status bar."&RETURN&RETURN&\ "The TOOLTIP type of display will make the field or text member resize itself to fit the text, and disappear when it is empty. You can set the tooltip type display to appear at any position on the stage, such as under the cursor. If no position is sent to the sprite, it will appear at the top left corner of the Stage. See the Tooltip behavior for more details."&RETURN&RETURN&\ "If you wish to display several lines of text, you must use RETURN characters to define the line breaks. An empty tooltip sprite will move off-stage to hide. It is recommended that you place it off-stage before it is used, in case it causes a brief flash on the screen."&RETURN&RETURN&\ "The STATUS BAR type of display will appear on Stage at all times. It will not resize or change position. Any positional information sent to this sprite will be ignored if it is set to act as a status bar. If the text is too long to appear in the member of the current sprite, a scrollbar will appear. You do not need to divide the text with RETURN characters. If you think that a scrollbar may be necessary, make sure that the field or text member is sufficiently tall for the scroll arrows to operate correctly."&RETURN&RETURN&\ "Set the font size and other characteristics of the field or text member to customize the appearance of the message."&RETURN&RETURN&\ "Be sure to give the field or text member a name. It may be emptied by this behavior. Director automatically erases nameless empty members."&RETURN&RETURN&\ "PERMITTED MEMBER TYPES:"&RETURN&\ "field, text and OSstatictext"&RETURN&RETURN&\ "PARAMETERS:"&RETURN&\ "* Display type:"&RETURN&\ " - Tooltip (appears near the cursor on rollover)"&RETURN&\ " - Status bar (appears in a fixed position at all times)"&RETURN&RETURN&\ "PUBLIC METHODS:"&RETURN&\ "* Set the text to display (and the position of the sprite)"&RETURN&RETURN&\ "ASSOCIATED BEHAVIORS:"&RETURN&\ "* Tooltip"&RETURN&\ "* Source Status"&RETURN&\ "* Hypertext - Display Status" end getBehaviorDescription