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
Toggle Button
space crawling
Lingo MarkUp Xtra
CTRL+B, CTRL+I, CTRL+U
Encrypt/Decrypt a file
Drag and Droop
macromedia.director.lingo
Buddy Tray
Wait for DigitalVideo Cuepoint
Import from Access - Valentina
 

 

 

Behavior Start Menu(xml)

Added on 10/17/2002

 

Compatibilities:
behavior D8 D8_5 D9 Mac PC Shockwave

This item has not yet been rated

Author: Roti (website)

Start Menu(xml) This is a tree structured menu behavior. The whole menu itself comes from the makeList() function of the XMLParser xtra this will be the 'Start Menu' itself. Then the menu will be presented by field castmembers. The depth of the structure isn't limited, just the screensize does that. You don't need sprites, just field members. You can use the myParent property to track back the attributes of the tree. The return function will have the number of the clicked line, the attributes of the menuitem, the parent menuitem's attributes, and the whole submenu too. What will you need: - You have to make a cast named 'menu' and place field castmembers there, as many as you will need from number 1. - If you want a bitmap to be the background of the menus, name it 'background', and put it to the 'menu' cast, anywhere! - You must have a 'startmenu_element_clicked' global function, because it will be called, when a menuelem clicked. - A text or field castmember, that holds the menu structure. This member's text comes from the makeList() function of the XMLParser xtra. (So the simplest thing is to make the menu in xml, and use the XMLPArser Xtra to have the list.)

Download PC Source
-- Start menu ; 2004.01.x
-- Author: Roti ; roti@al.pmmf.hu
-- Copyright (C)

-- CHANGELOG:
-- 2004.01.
-- new property myMinwidth -- the minimum width of the menu and submenus
-- new property mySubmenuloc -- where should the submenu appears, at the top, or beside the selected row


on getBehaviorDescription me
  return "Start Menu"&RETURN&RETURN&"This is a tree structured menu behavior. The whole menu itself comes from the makeList() function of the XMLParser xtra this will be the 'Start Menu' itself. Then the menu will be presented by field castmembers. The depth of the structure isn't limited, just the screensize does that. You don't need sprites, just field members. You can use the myParent property to track back the attributes of the tree. The return function will have the number of the clicked line, the attributes of the menuitem, the parent menuitem's attributes, the whole submenu with just the QUOTEnameQUOTE attributes, the whole submenu, and the clicked linenumber in the xml." & RETURN & RETURN & "What will you need:"&RETURN&"- You have to make a cast named 'menu' and place field castmembers there, as many as you will need from number 1."&RETURN&"- If you want a bitmap to be the background of the menus, name it 'background', and put it to the 'menu' cast, anywhere!"&RETURN&"- You must have a 'startmenu_element_clicked' global function, because it will be called, when a menuelem clicked."&RETURN&"- A text or field castmember, that holds the menu structure. This member's text comes from the makeList() function of the XMLParser xtra."&RETURN&"    (So the simplest thing is to make the menu in xml, and use the XMLPArser Xtra to have the list.)"
end getBehaviorDescription

on getBehaviorTooltip me
  return "Use this behavior to make a Start Menu"
end getBehaviorTooltip


property mySprite -- my spritenumber
property myList -- The list, which comes from the makeList() function of the XMLParser xtra
-- it can be set from script, or can come from a text member; if it is empty, than nothing happens
property myAttrib -- which property of the list contains the names of the menuitems
-- if it is empty, than nothing happens, because the handler needs to know the attribute name,
-- which holds the name of the menuitem
property myDefbg -- the background color of the unselected menu
property myDeffg -- the color of the unselected text
property myFontsize -- the size of the text (should be an odd number because of Director's bug)
property myWidth  -- the width of the menutiems
property myLocz -- the locz of the menu
property myFreesprite -- this is the sprite which presents the next menu
property myParent -- the parent sprite number
property mySub -- this is the deep
property myLine_ -- store the hilited line, to send mousedown if needed
property myDelay -- this is the delay to show the menu
property MyXmlLine -- store the clciked xml line
property myBlend -- this is the blend of the background of the menuitem, is exist
property myHilite -- is the hilite enabled? Yes=Void

-- 2004.01.
property myMinwidth -- the minimum width of the menu and submenus
property mySubmenuloc -- where should the submenu appears, at the top, or beside the selected row


on beginsprite me
  -- Handle the tree type
  case ilk(myList) of
    #string:-- if it is a string
      myList=value(myList)
    #member:-- if it is the member, which holds the string
      myList=value(member(myList).text)
  end case
  
  -- Handle, if we put the behavior by hand
  if mySprite=Void then
    mySprite = me.spriteNum
  end if
  
end


on mouseWithin me
  if mySub<2 then
    abort
  end if
  
  myLine=the mouseline
  
  if myLine<>-1 and mySprite<>Void and myHilite=Void then -- hiliting the appropriate line
    chars=0
    repeat with i = 1 to myLine-1-- It is needed to hilite the lines properly
      chars=chars+sprite(mySprite).member.text.line[i].char.count
    end repeat
    sprite(mySprite).member.char[chars+myLine..chars+sprite(mySprite).member.text.line[myLine].char.count+myLine].hilite()
  end if
  
  if myLine_<>myLine and mySub then -- if we change the hilited line with the mouse
    -- Use a delay if we aren't at the end
    starttimer
  else
    
    if the timer>myDelay-5 and the timer      the timer=myDelay+5
      
      -- First check whether to hide submenus
      closemenu()
      
      if myLine=-1 then
        myLine_=myLine -- store the hilited line
        --        abort
      end if
      
      mousedown(me,the mouseline) -- open the menus
      
    end if
  end if
  
  myLine_=myLine -- store the hilited line
  
end mouseWithin


on rightmousedown me
  mousedown(me,the mouseline)
end


on mousedown me,myLine
  
  -- close my submenu, if it is visible
  if myFreesprite<>Void then
    if sprite(myFreesprite).visible=true then
      closemenu()
      abort
    end if
  end if
  
  -- store the mousecharacter
  mc=the mousechar
  
  -- The menu, which opened the menus, can close all
  if mySub=1 or mySub=Void then -- if we have children
    closemenu()
  end if
  
  -- Prevent quick mouse motions
  if myLine=Void then
    myLine=the mouseline
  end if
  
  -- Prevent, if we have another field behind the menu
  if sprite(mySprite).member.type=#field then
    if the number of lines in sprite(mySprite).member.text      abort
    end if
  end if
  
  myMousedown=the mousedown
  if myMousedown=0 then
    myMousedown=the rightMouseDown
  end if
  
  -- Check the mouse
  if myLine<1 or mySub=Void then
    if mySub>2 then
      exit -- if the mouse ran away on some submenu
    else
      myLine=0 -- if this is the first menu, we will use the whole tree
    end if
  end if
  
  -- Check the unwanted mouse triggers
  if myList=Void then -- if we caught some mouse trigger, but we don't have the list, exit
    exit
  end if
  
  -- Check if we reached the end of the submenus
  if myList.count>1 and myLine+1<=myList.count then
    if myList[myLine+1].count =1 then -- if there aren't any submenu, then return the attributes
      -- The attributes of the menuitem, and the parent's attributes
      if myMousedown then
        -- tempmylist is a list, where only the myAttrib attributes presented
        tempmylist=(myList).duplicate()
        repeat with i=2 to tempmylist.count
          if tempmylist[i][1][myAttrib]=Void then
            tempmylist.deleteAt(i)
            i=i-1
          end if
        end repeat
        -- Here you can add further variables to pass ..........
        startmenu_element_clicked(myLine,myList[myLine+1][1],myList[1],myList,tempmylist,sprite(myParent).MyXmlLine[myLine],the rightMouseDown)
      end if
      exit
    end if
  end if
  
  -- Search for the next free sprite for the submenu, if needed
  if myFreesprite=Void then -- search for the first free sprite from the given locz to +50
    repeat with myFreesprite = myLocz to myLocz+50
      if sprite(myFreesprite).type=0 then
        exit repeat
      end if
    end repeat
    -- if there aren't any free sprite
    if myFreesprite=myLocz+50 then
      alert "I can't find an empty sprite! from "&myLocz&" to "&myLocz+50&"!"
      exit
    end if
  end if
  
  if sprite(myFreesprite).visible=true and sprite(myFreesprite).type<>0 and sprite(myFreesprite).member<>member(0,0) then
    exit
  end if
  
  -- Check, which part of the menu should we use
  if myParent then
    thelist=myList[myLine+1]
  else
    thelist=myList[1][2] -- if it is the first submenu
  end if
  
  -- Check if this is the first menu
  if mySub=Void then
    mySub=1
  end if
  
  -- myFreesprite holds the first free sprite
  sprite(myFreesprite).type=16 -- set the type of the sprite
  sprite(myFreesprite).forecolor=255 -- set the forecolor of the sprite
  MyXmlLine=[]
  repeat with i = 1 to thelist.count-1 -- fill the member with the text
    if thelist[i+1][1][myAttrib]<>Void then
      MenuText=MenuText&thelist[i+1][1][myAttrib]&RETURN
      myXmlLine.add(i) -- store the clicked xml line
    end if
  end repeat
  delete the last char of MenuText
  if member(mySub,"menu").type=#empty then
    alert "You don't have enough field members in the QUOTEmenuQUOTE cast!"
    exit
  end if
  member(mySub,"menu").text=MenuText -- use the next submenu's member
  
  if MenuText="" then
    abort
  end if
  
  sprite(myFreesprite).member=member(mySub,"menu")
  
  
  -- Check if it hasn't got this behavior
  if sprite(myFreesprite).scriptInstanceList.getone("StartMenu")=0 then
    sprite(myFreesprite).scriptInstanceList.add(script("StartMenu").new())
  end if
  
  -- the submenus inherit the main properties
  sprite(myFreesprite).myList=thelist
  sprite(myFreesprite).myLocz=myLocz+1
  sprite(myFreesprite).myParent=mySprite
  sprite(myFreesprite).myAttrib=myAttrib
  sprite(myFreesprite).myDefbg=myDefbg
  sprite(myFreesprite).myDeffg=myDeffg
  sprite(myFreesprite).myFontsize=myFontsize
  sprite(myFreesprite).mySub=mySub+1
  sprite(myFreesprite).myWidth=myWidth
  sprite(myFreesprite).myDelay=myDelay
  sprite(myFreesprite).myBlend=myBlend
  
  sprite(myFreesprite).myMinwidth=myMinwidth
  sprite(myFreesprite).mySubmenuloc=mySubmenuloc
  
  -- Set the width of the field
  sprite(myFreesprite).member.rect=rect(0,0,8000,0)
  
  -- calculate the new width, using picture object on the fly
  repeat with ciklus = 1 to 100
    if member(ciklus).type=#empty then
      exit repeat
    end if
  end repeat
  new(#text, member(ciklus))
  member(ciklus).font=member(mySub,"menu").font
  myStyle=member(mySub,"menu").fontStyle
  the itemdelimiter=","
  myNewStyle="["
  repeat with i=1 to the number of items in myStyle
    myNewStyle=myNewStyle&"#"&(item i of myStyle)&","
  end repeat
  delete the last item of myNewStyle
  myNewStyle=myNewStyle&"]"
  myNewStyle=value(myNewStyle)
  member(ciklus).fontStyle=myNewStyle
  member(ciklus).fontsize=member(mySub,"menu").fontsize
  member(ciklus).text=MenuText
  pict=member(ciklus).picture
  member(ciklus).erase()
  new(#bitmap, member(ciklus))
  member(ciklus).picture=pict
  newwidth=member(ciklus).width+member(mySub,"menu").border+member(mySub,"menu").margin -- this is the width
  member(ciklus).erase()
  
  if newwidth    
    if myMinwidth=Void then
      myMinwidth=10
    end if
    
    if newwidth      sprite(myFreesprite).member.rect=rect(0,0,myMinwidth,0)
    else
      sprite(myFreesprite).member.rect=rect(0,0,newwidth,0)
    end if
  else
    sprite(myFreesprite).member.rect=rect(0,0,myWidth,0)
  end if
  
  
  -- Check, where to set the menuitem
  t=the number of lines in MenuText
  sprite(myFreesprite).visible=false
  if mySub=1 then -- if it is the first menu
    sprite(myFreesprite).loc=point(sprite(mySprite).left,sprite(mySprite).top-sprite(myFreesprite).member.height-5)
  else
    if mySubmenuloc="beside" then -- put it beside
      sprite(myFreesprite).loc=point(sprite(mySprite).right+1,sprite(mySprite).top+sprite(mySprite).member.charPosToLoc(mc)[2]-20)
    else -- put it to the top
      sprite(myFreesprite).loc=point(sprite(mySprite).right+1,sprite(mySprite).top-20)
    end if
  end if
  
  updateStage
  -- Check if the submenu hits the bottom
  if sprite(myFreesprite).bottom>(the stageBottom-the stagetop)-20 then
    sprite(myFreesprite).loc=point(sprite(mySprite).right+2,((the stageBottom-the stagetop)-sprite(myFreesprite).member.height)-10)
  end if  
  
  -- Check if the submenu hits the left side
  if sprite(myFreesprite).left<0 then
    sprite(myFreesprite).loch=2
  end if    
  
  
  
  
  sprite(myFreesprite).member.backcolor=myDefbg
  sprite(myFreesprite).member.forecolor=myDeffg
  sprite(myFreesprite).member.fontsize=myFontsize
  
  -- Use background if we have
  if member("background","menu").type<>#empty then
    updatestage
    sprite(myFreesprite+1).visible=false
    sprite(myFreesprite).ink=36
    sprite(myFreesprite+1).type=16
    sprite(myFreesprite+1).forecolor=255
    sprite(myFreesprite+1).member=member("background","menu")
    sprite(myFreesprite+1).locz=myFreesprite-1
    sprite(myFreesprite+1).rect=sprite(myFreesprite).rect
    sprite(myFreesprite+1).blend=myBlend
    updatestage
    sprite(myFreesprite+1).visible=true
  end if
  
  sprite(myFreesprite).visible=true
  myHilite=1
  
  if myParent<>Void then
    chars=0
    repeat with i = 1 to myLine-1-- It is needed to hilite the lines properly
      chars=chars+sprite(mySprite).member.text.line[i].char.count
    end repeat
    sprite(mySprite).member.char[chars+myLine..chars+sprite(mySprite).member.text.line[myLine].char.count+myLine].hilite()
  end if
  
  -- Clear the unwanted selections
  numofchars=the number of chars in MenuText
  sprite(myFreesprite).member.char[numofchars+1].hilite()
  sprite(myFreesprite).visible=true
  sendsprite(myFreesprite,#beginsprite)
end


on closemenu -- close the submenus
  if myFreesprite then
    if sprite(myFreesprite).visible=true and string(sprite(myFreesprite).scriptinstancelist) contains "StartMenu" then -- and sprite(myFreesprite).member<>member(0,0) then -- sprite(myFreesprite).type<>0
      sprite(myFreesprite).myLine_=Void
      sprite(myFreesprite).visible=false
      if sprite(myFreesprite+1).member.type=#bitmap then
        sprite(myFreesprite+1).visible=false
      end if
      sendsprite(myFreesprite,#closemenu)
      myHilite=Void
      exit
    end if
  end if
end


on isOKToAttach (me, aSpriteType)
  case aSpriteType of
    #script:
      return FALSE
    otherwise:
      RETURN TRUE
  end case
end

on getPropertyDescriptionList
  if the currentSpriteNum = 0 then exit
  
  return [ #myList: [#comment: "Display which member's structure on rollover?",  #format:  #text,  #default:  ""],  #myAttrib: [#comment: "which property of the list contains the name of the menuitem",  #format:  #string,  #default:"name" ],  #myDefbg:  [#comment: "the default background color of the menu",   #format:  #integer,   #default: 255 ],  #myDeffg : [#comment: "the default color of the text",  #format:  #integer,  #default: 0 ], #myLocz: [#comment: "the locz of the menu",  #format:  #integer,  #default: 50 ],  #myWidth: [#comment: "the width of the menuitems", #format:  #integer,   #default: 150 ],  #myDelay: [#comment: "the delay to show the menu",  #format:  #integer,  #default: 20 ], #myFontsize: [#comment: "the size of the text",  #format:  #integer,  #default: 17], #myBlend: [#comment: "the blend of the menuitems backgruond image",  #format:  #integer, #range: [#min:0, #max:100]] , #myMinwidth: [#comment: "the minimum width of the menu and submenus",  #format:  #integer, #range: [#min:10, #max:800], default:10] , #mySubmenuloc: [#comment: "where should the submenu appears, at the top, or beside the selected row",  #format:  #string, #range: ["top", "beside"], default:"top"]]
  
end getPropertyDescriptionList


 


Contact

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

Send e-mail