4 Replies Latest reply on Jun 16, 2006 6:59 AM by Applied CD

    Navigation Menu Tree

    Applied CD Level 1
      I need a vertical navigation tree that works just like bookmarks in a PDF file (ie: topic headings can expand or collapse to reveal more or less detail). In my case the menu entries are all text members but bitmaps would work just as well. I know there’s a Flash component for this but it stands out like a sore thumb (the “look” is not very flexible) and I’m not crazy about using Flash in Director when Director can handle the job. What I’ve got works quite well but I’ve had to hard code lists of sprite numbers that describe the tree structure … I’d like to remove this dependence on hard coding and get the sprites to build the required lists themselves. My code assumes the order of sprites in the score channels matches the display order of the fully expanded tree, I’m comfortable with this condition. In the end I should be able to move the menu up and down the channels as a unit and also insert additional menu items, without having to go back and change all of the sprite list properties.

      In the following menu example I’m using underscores to denote indenting (the forum removes extra spaces), the number is the sprite number.

      22 Menu Item 1
      23 Menu Item 2
      24 Menu Item 3 Tab
      25 __ Menu Item 3, Submenu Item 1
      26 __ Menu Item 3. Submenu Item 2
      27 __ Menu Item 3, Submenu Item 3 Tab
      28 ____ Menu Item 3, Submenu Item 3, Subsubmenu Item 1
      29 ____ Menu Item 3, Submenu Item 3, Subsubmenu Item 1
      30 __ Menu Item 3. Submenu Item 4
      31 Menu Item 4

      Here’s how it works, then I’ll provide the code. I built the menu off stage below the space it needs to occupy. I maintain two lists, a sorted list of sprites to show on stage and a sorted list of sprites to hide offstage. Tab items each have two property lists, a list of subordinate sprites they should reveal and a list of subordinate sprites they should remove when clicked. When a tab item is clicked to expand the sprites on its reveal list are added to the show on stage list and removed from the hide offstage list, when clicked to collapse I do the reverse operation but using the remove list instead. The menu is then redrawn by looping through the show on stage sprite list, setting each sprite’s locV below the previous sprite, sprites on the hide offstage list are moved to a locV just below the stage.

      Here’s the tab behavior, in the example above it would be attached to sprites 24 and 27. Following with the example, the behavior parameters for sprite 24 would be “collapsed”,[25,26,27,30],[25,26,27,28,29,30] while sprite 27 would be “collapsed”,[28,29],[ 28,29]
      ------------------------------------------------------------------------------------------ ------------------------------------
      property myTabState
      property myShowSubs
      property myHideSubs

      on mouseUp me
      global glMenuItemsShown
      global glMenuItemsHidden

      case myTabState of
      "collapsed":
      repeat with mySpriteNum in myShowSubs
      glMenuItemsShown.add(mySpriteNum)
      glMenuItemsHidden.deleteOne(mySpriteNum)
      end repeat
      myTabState = "expanded"
      "expanded":
      repeat with mySpriteNum in myHideSubs
      glMenuItemsShown.deleteOne(mySpriteNum)
      glMenuItemsHidden.add(mySpriteNum)
      end repeat
      myTabState = "collapsed"
      otherwise: alert "Unknown tab state in menu."
      end case
      refreshMenuTree
      end

      on getPropertyDescriptionList
      if _player.currentSpriteNum = 0 then exit
      return\
      [#myTabState:\
      [#comment: "Enter initial tab state",\
      #format:#string,#default:"collapsed"],\
      #myShowSubs:\
      [#comment: "Enter subordenant sprites to reveal (as list)",\
      #format:#list,#default:""],\
      #myHideSubs:\
      [#comment: "Enter subordenant sprites to hide (as list)",\
      #format:#list,#default:""]]
      end getPropertyDescriptionList

      Here’s the frame script that sets everything up (gMenuLineSpacing is the pixel spacing between menu items, gMenuTopLine is the locV for the first item):
      ------------------------------------------------------------------------------------------ ------------------------------------
      on enterFrame me
      global gMenuLineSpacing
      global gMenuTopLine
      global glMenuItemsShown
      global glMenuItemsHidden

      gMenuLineSpacing = 5
      gMenuTopLine = 172
      glMenuItemsShown = [22,23,24,31]
      glMenuItemsHidden = [25,27,27,28,29,30]
      glMenuItemsShown.sort()
      glMenuItemsHidden.sort()
      refreshMenuTree
      end

      And this is the movie script that does the real work:
      ------------------------------------------------------------------------------------------ ------------------------------------
      on refreshMenuTree
      global gMenuLineSpacing
      global gMenuTopLine
      global glMenuItemsShown
      global glMenuItemsHidden

      myVPos = gMenuTopLine
      repeat with mySpriteNum in glMenuItemsShown
      sprite(mySpriteNum).locV = myVPos
      myVPos = myVPos + sprite(mySpriteNum).member.height + gMenuLineSpacing
      end repeat
      repeat with mySpriteNum in glMenuItemsHidden
      sprite(mySpriteNum).locV = 750
      end repeat
      updateStage
      end