Contents
Articles
Behaviors
Books
Director News
Director Web Sites
FAQ
Games
Mailing Lists
News Groups
Project Examples
Reviews
Software
Tools
Useful Web Sites
Utilities
Xtras

Don't miss these
Dean's Director Resources
Halo around images
Relative Links
Jump Sprite - Move a sprite along a parabolic arc so it
Lingofish
Set ViewScale Property of a Flash Sprite
Double Char Fix - D 7.0
Open a window from inside shockwave
Gallery navigator
EXE Screen Saver
 

 

 

Behavior Text Outliner

Added on 6/10/1999

 

Compatibilities:
behavior D6_5 Mac PC

This item has not yet been rated

Author: JohnDowdell

Will create an expanding and collapsing outline structure for a TAB-indented field in standard outline form.

property spriteNum, myField
property myFullText
property myDelim, myDoubleClickSpeed



--  =============  PUBLIC METHODS  =========================

--  BeginSprite: "myDelim" and "myDoubleClickSpeed" can be changed
--  if you wish. The default delimiter here is a 4-space TAB.
--  If you set the click speed to 1 tick then the field display
--  will change quickly, but doubleclicks will not send events
--  out to other behaviors on the sprite.

on beginSprite me
  set myDelim to "    "
  set myDoubleClickSpeed to 10
  set myField to the member of sprite spriteNum
  if the type of myField <> #field then
    alert "The Outliner behavior in channel " & spriteNum & " works with system textfields only. Please remove it or reassign it."
    halt
  end if
  CheckToSaveFieldContents me
  set myFullText to GetOriginalText(script myField)
  set the text of myField to GetCollapsedText (me)
end

on mouseUp me
  set clicked to the mouseLine
  if clicked < 1 then exit
  CheckForDoubleClick me, clicked
  case (word 1 of line clicked of the text of myField) of
    "+": Expand me, clicked
    "-": Collapse me, clicked
    otherwise: put "Error clicking: " & line clicked of the text of myField
  end case
end



--  =============  BROADCAST METHODS  =========================


--  Send this optional message to the sprite to put the original
--  text for editing back into the field. Plus and minus signs
--  will not be included.
on Outliner_RestoreFullText me
  set the text of myField to GetOriginalText(script myField)
end


--  Send this optional message to the sprite to display only the
--  topmost level of the outline in the field. Plus signs
--  will be included.
on Outliner_CollapseAllText me
  set the text of myField to GetCollapsedText (me)
end


--  Send this optional message to the sprite to display all text
--  in expanded outline form. All plus and minus signs will
--  be included.
on Outliner_ExpandAllText me
  set rawSource to GetOriginalText(script myField)
  set dest to ""
  set numLines to the number of lines in rawSource
  repeat with i = 1 to numLines
    set thisLine to line 1 of rawSource
    put "- " before word 1 of thisLine
    put thisLine & RETURN after dest
    delete line 1 of rawSource
  end repeat
  delete the last char of dest
  set the text of myField to dest
end


--  SENDING MESSAGES WHEN THE DISPLAY CHANGES:
--
--  This behavior will send an event named "Outliner_DoubleClick"
--  to the field sprite if you doubleclick an entry. This event
--  will be safely ignored if you do not choose to handle it in
--  another behavior on this sprite.
--
--  But if you do wish to capture a doubleclicked line in the
--  outliner and do something with it, then make a new behavior
--  for this sprite similar to the following, but doing what
--  you wish instead of this example:
--
--property spriteNum
--
--on Outliner_DoubleClick me, chosenText
--  case (chosenText) of
--    "Introduction": tell the stage to go "intro"
--    "Chapter 1": tell the stage to go movie "chpt1"
--    "Chapter 2": tell the stage to go movie "chpt2"
--    otherwise: put chosenText
--  end case
--end




--  =============  PRIVATE METHODS  =========================



--  Called by beginSprite to initialize the field's display.
--  Returns only the top level of text.
on GetCollapsedText me
  set source to myFullText
  set displayText to ""
  set numLines to the number of lines of source
  repeat with i = 1 to numLines
    set thisLine to line 1 of source
    delete line 1 of source
    if GetDepth(thisLine) = 0 then
      if GetDepth(line 1 of source) = 0 then put "- " before thisLine
      else put "+ " before thisLine
      put thisLine & RETURN after displayText
    end if
  end repeat
  delete the last char of displayText
  return displayText
end



--  Called by mouseUp handler. Will delay execution of a click until
--  the doubleClickSpeed has been exceeded. If a single click, then
--  execution reverts to the mouseUp handler. If a doubleclick, then
--  list will not be expanded or collapsed, but an "Outliner_DoubleClick"
--  event will be sent to any behaviors on the sprite which wish to
--  handle a doubleclicked line. (For a simple outliner that does not
--  change the environment you'd not need to handle that event.)

on CheckForDoubleClick me, clicked
  if the doubleClick then abort
  startTimer
  repeat while the timer < myDoubleClickSpeed
    if the mouseDown then
      set theChoice to line clicked of the text of myField
      delete char 1 to offset(word 2 of theChoice, theChoice) - 1 of theChoice
      sendSprite(spriteNum, #Outliner_DoubleClick, theChoice)
      abort
    end if
  end repeat
end


--  Called from Collapse and Expand routines. Given a line of
--  text, it will return an integer from zero up of how many
--  TAB units the line is indented.

on GetDepth whatText
  return (offset(word 1 of whatText, whatText) - 1) / length(myDelim)
end


on Expand me, clicked
  set oldDisplay to the text of myField
  set chosenText to line clicked of oldDisplay
  
  delete word 1 of chosenText
  
  --  Set "rawSource" to be all raw text which follows the chosen line:
  set rawSource to myFullText
  delete char 1 to offset(chosenText, rawSource) of rawSource
  delete line 1 of rawSource
  
  put "- " before word 1 of chosenText
  if clicked > 1 then
    set displayText to line 1 to (clicked - 1) of the text of myField
    put RETURN & chosenText after displayText
  else set displayText to chosenText
  
  set parentDepth to GetDepth(chosenText)
  set childDepth to GetDepth(rawSource)
  
  --  Show any nested lines one layer below the clicked line:
  repeat while childDepth > parentDepth
    if childDepth = parentDepth + 1 then
      set nextChildDepth to GetDepth(line 2 of rawSource)
      if nextChildDepth > childDepth then put "+ " before word 1 of rawSource
      else put "- " before word 1 of rawSource
      put RETURN & line 1 of rawSource after displayText
    end if
    delete line 1 of rawSource
    set childDepth to GetDepth(rawSource)
  end repeat
  
  --  And then add the rest of the old display to the end of the new display:
  set totalLines to the number of lines in oldDisplay
  set remainingLines to line (clicked + 1) to totalLines of oldDisplay
  put RETURN & remainingLines after displayText
  set the text of myField to displayText
end




on Collapse me, clicked
  set oldDisplay to the text of myField
  set chosenText to line clicked of oldDisplay
  
  set parentDepth to GetDepth(chosenText)
  
  if GetDepth(line clicked + 1 of oldDisplay) > parentDepth then
    delete word 1 of chosenText
    put "+ " before word 1 of chosenText
  end if
  
  if clicked > 1 then
    set displayText to line 1 to (clicked - 1) of oldDisplay
    put RETURN & chosenText after displayText
  else set displayText to chosenText
  
  delete line 1 to clicked of oldDisplay
  
  set childDepth to GetDepth(oldDisplay)
  
  repeat while childDepth > parentDepth
    delete line 1 of oldDisplay
    set childDepth to GetDepth(oldDisplay)
  end repeat
  
  put RETURN & oldDisplay after displayText
  set the text of myField to displayText
end



--  This handler determines whether the field contents need to be
--  saved or not. If there is no stored text, or if there are more
--  lines of text in the field than are stored, then the
--  ContentsToScript handler will be called to stuff the field text
--  into the member script of the field itself.

on CheckToSaveFieldContents me
  if the scriptText of myField = "" then ContentsToScript me
  set storedLines to the number of lines in GetOriginalText(script myField)
  set newLines to the number of lines in the text of myField
  if newLines > storedLines then ContentsToScript me
end




--  ContentsToScript will store the regular text within the script of
--  the field itself. Called by CheckToSaveFieldContents, subject
--  to its conditions. This is a tricky handler to read, because it
--  evaluates a field and constructs another script which returns the
--  RETURN-delimited text... a script which turns text to script to text.
--  Only the one line "if '+-' contains..." is unique to this behavior,
--  and this handler as a whole can be used in other behaviors too.

on ContentsToScript me
  set source to the text of myField
  set theScript to "on GetOriginalText" & RETURN
  put "set theString to EMPTY" & RETURN after theScript
  set numLines to the number of lines in source
  repeat with i = 1 to numLines
    --  If field is in outline form, turn it to plain text:
    if "+-" contains word 1 of source then delete word 1 of source
    put ("put RETURN & " "E& line 1 of source "E& " after theString" & RETURN) after theScript
    delete line 1 of source
  end repeat
  put "delete char 1 of theString" & RETURN after theScript
  put "return theString" & RETURN after theScript
  put "end" & RETURN & RETURN after theScript
  set the scriptText of member myField to theScript
end



--  =============  STANDARD METHODS  =========================

on getBehaviorDescription me
  set line1 to "Drop this behavior on a field that has a consecutive lines in a TAB-indented outline structure, to display a collapsing and expanding outline of the contents. "
  set line2 to "Click on the plus sign to expand a topic; click on a minus sign to collapse a topic." & RETURN & RETURN
  
  set line3 to "The first time this behavior is run it will store a copy of the full text within the castmember script of the field itself. "
  set line4 to "The castmember script will be regenerated if you delete the castmember script, or if the field contains more lines than that originally held in the script." & RETURN & RETURN
  
  set line5 to "Doubleclicking on any item will send an 'Outliner_DoubleClick' message, along with the chosen text, to other behaviors on that field sprite for navigational uses."
  set line6 to "You do not need to handle this event if you do not wish doubleclicks to trigger actions elsewhere on screen." & RETURN & RETURN
  
  set line7 to "To edit the outline: " & RETURN
  set line8 to "   1)  If you kept a copy of the source text in a dummy field, then copy this source back into the field. (You can also type in the Message Window 'sendAllSprites(#Outliner_RestoreFullText)' while the movie is running to restore the source text too.) " & RETURN
  set line9 to "   2)  Edit the text, making sure it remains TAB-indented to maintain your outline structure." & RETURN
  set line10 to "   3)  If the edited text is shorter than the original text, then open the field's castmember script, select-all, and delete." &RETURN
  set line11 to "   4)  Run the movie again. The edited text will be safely stored in the field's castmember script, and you will again see the top  level of the outline." & RETURN & RETURN
  
  set line12 to "Note that all text in the field will use the same font, style, and size... different formats for different characters are not  remembered by this behavior." & RETURN & RETURN
  
  set line13 to "The text should be in consecutive lines... blank lines will be marked as empty lines, with a minus sign. "
  set line14 to "(When typing a field it's often common to put an extra RETURN after all text -- this will produce the 'solitary minus' symptom.)"
  & RETURN & RETURN
  
  return line1 & line2 & line3 & line4 & line5 & line6 & line7 & line8 & line9 & line10 & line11 & line12 & line13 & line14
end  

 


Contact

MMI
36 South Court Sq
Suite 300
Newnan, GA 30263
USA

Send e-mail