小小菜鸟的web菜园子

web开发学习。好记性不如烂笔头。每天进步一点点!

导航

ActionScript 3.0 实现树形菜单。

转自:http://www.cppblog.com/twzheng/archive/2007/10/19/34598.aspx
主要2个类:给了我不少启发.打算修改成xml,并加上拖动节点,添加删除节点,更名节点的功能.

Flash ActionScript 3.0 实现的树形菜单

这是我初学ActionScript 3.0时实现的treeMenu类, 贴出来分享,或许对ActionScript 3.0的初学者有一定的帮助,但不建议在应用程序开发中使用。

各位博友可以就此发表自己的观点,谢谢各位指教。

下面是treeMenu类的定义:

/**
 *    treeMenu类
 *     
 *    构造一个树形菜单
 *    
 *    @author    twzheng (http://www.ugocn.com)
 *    @date    20070903
 *    @version    1.0.070903
 *    
 
*/


////////////////////////////////////////////////////////////////////////////////////////////
//
    在这里添加修改说明:
//
//
//
//////////////////////////////////////////////////////////////////////////////////////////

package com.components
{
    import flash.display.MovieClip;
    
    public class treeMenu extends MovieClip
    
{
        public 
var rootMenu:menuItem;
        
        
function treeMenu()
        
{
        }

        
        public 
function newTreeMenu()
        
{
            
if(rootMenu != null)
            
{
                trace(
" 错误:根菜单已存在,根菜单只能有一个!");
                
return;
            }

            rootMenu 
= new menuItem("rootMenu","rootMenu");
            
if(rootMenu == null)
            
{
                trace(
" 创建根菜单失败!");
                
return;
            }

            rootMenu.removeChild(rootMenu.menuLabel);
            rootMenu.childMenu.x 
= 0;
            rootMenu.childMenu.y 
= 0;
            
this.addChild(rootMenu);
        }

        
        public 
function addChildMenu(bMenu:menuItem, mName:String, mLabel:String)
        
{
            
var mItem = new menuItem(mName,mLabel);
            
if(mItem == nullreturn;
            
var index:int = bMenu.childItem.length;
            
            mItem.y 
= menuItemLocalizer(bMenu.childItem);
            
            bMenu.childItem[index] 
= mItem;
            
            bMenu.childMenu.addChild(mItem);
        }

        
        private 
function menuItemLocalizer(bMenu:Array):int
        
{
            
var num:int = 0;
            
for each (var item in bMenu)
                num 
= num + item.getHeight();
            
return num;
        }

    }

}


/**
 * 菜单项节点类
 * 
 * @author    twzheng (http://www.ugocn.com)
 * @date    20070903
 * @version    1.0.070903
 
*/
    

import flash.display.DisplayObjectContainer;
import flash.display.MovieClip;
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.ui.Mouse;

internal class menuItem extends MovieClip
{
    public 
var menuName:String;            // 菜单项名称
    public var menuLabel:TextField;        // 菜单项标签(即显示给用户的菜单标签)
    public var childMenu:DisplayObjectContainer; // 子菜单项容器
    public var childItem:Array;            // 子菜单项数组
    
    private 
var h:Number;        // 菜单项高度属性,记录的是实际高度(包含隐藏菜单高度)
    
    
function menuItem(mName:String, mLabel:String)
    
{
        
if(mName == "" || mName == null || mLabel == null)
        
{
            trace(
" 菜单名或者菜单标签为空,添加菜单项失败!");
            
return;
        }

        menuName 
= mName;
        
        menuLabel 
= new TextField();
        menuLabel.text 
= mLabel;
        menuLabel.height 
= 22;
        menuLabel.textColor 
= 0x000000;
        menuLabel.background 
= false;
        menuLabel.addEventListener(MouseEvent.MOUSE_MOVE,itemMouseMove);
        menuLabel.addEventListener(MouseEvent.MOUSE_OUT,itemMouseOut);
        
this.addChild(menuLabel);
        
        childMenu 
= new MovieClip();
        childMenu.addEventListener(Event.ADDED,mcAddedEvent);
        childMenu.addEventListener(Event.REMOVED,mcRemovedEvent);
        
this.childMenu.x = this.menuLabel.x + 8;
        
this.childMenu.y = this.menuLabel.y + this.menuLabel.height;
        
this.addChild(childMenu);
        
        childItem 
= new Array();
        
        
this.h = menuLabel.height;
        
// 菜单项单击事件应留给外部使用者实现
        //this.menuLabel.addEventListener(MouseEvent.CLICK,itemClick);
    }

    
    
// 返回菜单项显示的真实高度,即菜单项的实际高度减去隐藏菜单项的高度
    public function getHeight():Number
    
{
        
return h - getHideMenu(this);
    }

    
    
/**
    * 获取item的childMenu中所有隐藏子菜单项的高度和
    *
    * @item                主菜单项,此函数即计算它的子菜单中隐藏菜单的高度
    * @return            返回item的childMenu中visible属性为false的子菜单高度和
    * 
    * 注:如果item.childMenu的visible属性为false即返回childMenu的高度,如果item.childMenu为空则返回0。
    
*/

    private 
function getHideMenu(item:menuItem):Number
    
{
        
var sumHeight = 0;
        
if(item.childMenu.visible)
        
{
            
if(item.childItem == null)
                
return 0;
            
for(var i = 0; i < item.childItem.length; i++)
            
{
                
// 对每个子菜单项递归
                sumHeight = sumHeight + getHideMenu(item.childItem[i]);
            }

            
return sumHeight;
        }

        
else
            
return item.childMenu.height;
    }

    
    
/**
    * 获取名字为mName菜单项的对象
    *
    * @mName            菜单项名字字符串
    * @return            返回调用此函数的菜单项的子菜单中名字为mName的子菜单项对象
    
*/

    public 
function getMenu(mName:String):menuItem
    
{
        
for each(var item in childItem)
        
{
            
if(item.menuName == mName)
                
return item;
        }

        trace(
" 错误:不存在名为 " + mName + " 的子菜单项!");
        
return null;
    }

    
    
/**
    * 接收TextField的单击事件,更改TextField对应item的子菜单显示状态
    *
    * @item            接收到单击事件的menuLabel对应的菜单项(menuItem)
    
*/

    public 
function chgChildItemVisible(item:menuItem)
    
{
        
var chgHeight = 0;
        
if(item.childMenu.visible)
        
{
            chgHeight 
= item.getHeight() - item.menuLabel.height;
            item.childMenu.visible 
= false;
            updateMenu(item,
0 - chgHeight);
        }

        
else
        
{
            item.childMenu.visible 
= true;
            chgHeight 
= item.childMenu.height - getHideMenu(item);
            updateMenu(item,chgHeight);
        }

    }

    
    
/**
    * 更新各菜单项位置
    * 注:由于参数item的子菜单容器childMenu高度发生变化而需要改变其同级别的菜单项以及所有的父菜单项的y坐标
    *
    * @item            引发调用此函数的菜单项(即由于item的childMenu高度改变而需要调用此函数)
    * @chgHeight    需要改变的y坐标高度,正值即增加y坐标值,负值减小y坐标值
    
*/

    private 
function updateMenu(item:menuItem, chgHeight:Number)
    
{
        
if(item == nullreturn;
        
// item.parent为父菜单的子菜单容器,item.parent.paren才是对应的父菜单项
        var parentItem = item.parent.parent;

        
var i,index:int = 0;
        
        
if(parentItem == null || ! (parentItem is menuItem))
            
return;
        
        
// 搜索item在父菜单的子菜单数组childItem中的索引
        index = parentItem.childItem.indexOf(item);
        
        
// 改变item同级别的并且位于其后的菜单项的显示位置
        for(i = index + 1; i < parentItem.childItem.length; i++)
        
{
            parentItem.childItem[i].y 
= parentItem.childItem[i].y + chgHeight;
        }

        
        
// 对父菜单项递归
        updateMenu(parentItem,chgHeight);
    }

    
//    private function itemClick(e:MouseEvent)
//
    {
//
        var item = e.currentTarget;
//
        chgChildItemVisible(item.parent);
//
    }
    
    private 
function itemMouseMove(e:MouseEvent)
    
{
        
var item = e.currentTarget;
        item.background 
= true;
        item.backgroundColor 
= 0x66ccFF;
        item.textColor 
= 0x0000FF;
    }

    
    private 
function itemMouseOut(e:MouseEvent)
    
{
        
var item = e.currentTarget;
        item.background 
= false;
        item.backgroundColor 
= 0xFFFFFF;
        item.textColor 
= 0x000000;
    }

    
    
// 向子菜单容器加入子菜单项事件,增加当前菜单的高度
    private function mcAddedEvent(e:Event)
    
{// 此事件响应函数还需要更改。。。
        var mc = e.currentTarget;
        h 
= h + 22;//mc.height;///2
    }

    
    
// 从子菜单容器移除子菜单项事件,减小当前菜单的高度
    private function mcRemovedEvent(e:Event)
    
{// 此事件响应函数还需要更改。。。
        var mc = e.currentTarget;
        h 
= h - 22;//mc.height/2;
    }

}



treeMenu类简单应用

package 
{
    import flash.display.MovieClip;    
    import flash.events.
*;

    import com.library.treeMenu;
    
    public class menu extends MovieClip
    
{
        
function menu()
        
{
            
var tm = new treeMenu();
            tm.newTreeMenu();            
// 创建根菜单
            
            tm.addChildMenu(tm.rootMenu,
"基菜单-01","基菜单-01");
            tm.rootMenu.getMenu(
"基菜单-01").menuLabel.addEventListener(MouseEvent.CLICK,eventClick);
            
            tm.addChildMenu(tm.rootMenu.getMenu(
"基菜单-01"),"一级菜单-011","一级菜单-011");
            
            tm.addChildMenu(tm.rootMenu,
"基菜单-02","基菜单-02");
            tm.rootMenu.getMenu(
"基菜单-02").menuLabel.addEventListener(MouseEvent.CLICK,eventClick);
            
            tm.addChildMenu(tm.rootMenu.getMenu(
"基菜单-02"),"一级菜单-021","一级菜单-021");
            tm.rootMenu.getMenu(
"基菜单-02").getMenu("一级菜单-021").menuLabel.addEventListener(MouseEvent.CLICK,eventClick);
            
            tm.addChildMenu(tm.rootMenu.getMenu(
"基菜单-02").getMenu("一级菜单-021"),"二级菜单-0211","二级菜单-0211");
            tm.rootMenu.getMenu(
"基菜单-02").getMenu("一级菜单-021").getMenu("二级菜单-0211").menuLabel.addEventListener(MouseEvent.CLICK,eventClick);
            
            tm.addChildMenu(tm.rootMenu.getMenu(
"基菜单-02").getMenu("一级菜单-021").getMenu("二级菜单-0211"),"三级菜单-02111","三级菜单-02111");
            tm.addChildMenu(tm.rootMenu,
"基菜单-03","基菜单-03");
            
            
// 菜单坐标 默认坐标(0,0)
            //tm.x = 50;
            //tm.y = 50;
            this.addChild(tm);
        }

        
        private 
function eventClick(e:MouseEvent)
        
{
            
var item = e.currentTarget;
            item.parent.chgChildItemVisible(item.parent);    
// 隐藏或显示子菜单项
        }

    }

}

posted on 2008-02-26 21:39  『小小菜鸟』  阅读(1497)  评论(1编辑  收藏  举报