Unity运行模式用GUILayout实现ComboBox

public class ComboBox
    {

        public int index;//索引
        public string weight="";//权重

        private int labelWidth = 60;//标题的宽

        public float Weight
        {
            get { return float.Parse(weight); }
        }
        /// <summary>
        /// 复选框的宽度
        /// </summary>
        public const int WIDTH = 150;
        /// <summary>
        /// 复选框的高度
        /// </summary>
        public const int Height = 20;
        /// <summary>
        /// Lable
        /// </summary>
        public string label = "";

        public int viewAreaHeight = 200;


        public ComboBox(Dictionary<object, object> dataSource,int viewHeight = 200)
        {
            if (dataSource == null)
            {
                dataSource = new Dictionary<object, object>();
                for (int i = 0; i < 50; i++)
                {
                    dataSource.Add(i, string.Format("<color=#ff0000ff>请初始化数据 {0}</color>" ,i));
                }
            }
            viewAreaHeight = viewHeight;
            this.Init(dataSource,1);
        }
        private Dictionary<object, object> dataSource;
        private object currentValue;
        private object currentDisplayText;
        private int currentIndex;
       
        private bool showList;
        private Vector2 scrollPosition;
        private float showListTime;
        private int guiDepth;
        private bool alreadyInitGuiDepth;
        /// <summary>
        /// 选择项更改事件参数 
        /// </summary>
        public class SelectItemChangedArgs : EventArgs
        {
            private object itemValue;
            private object itemDisplayText;
            public object ItemValue
            {
                get
                {
                    return itemValue;
                }
            }
            public object ItemDisplayText
            {
                get
                {
                    return itemDisplayText;
                }
            }
            public SelectItemChangedArgs(object iValue, object iDisplayText)
            {
                itemValue = iValue;
                itemDisplayText = iDisplayText;
            }
        }
        /// <summary>
        /// 选择项更改事件 
        /// </summary>
        public event EventHandler<SelectItemChangedArgs> OnSelectItemChanged;
        public object SelectValue
        {
            get { return currentValue; }
        }
        public object SelectDisplayText
        {
            get { return currentDisplayText; }
        }
        public float ShowListTime
        {
            get { return showListTime; }
        }
        /// <summary>
        /// 数据源 
        /// </summary>
        public Dictionary<object, object> DataSource
        {
            set
            {
                dataSource = value;
                currentDisplayText = null;
                currentValue = null;
            }
            get
            {
                return dataSource;
            }
        }
        /// <summary>
        /// 初始化各项参数,控件应该只调用一次此方法,进行重置数据源直接使用DataSource属性即可 
        /// </summary>
        /// <param name="data">
        /// A <see cref="Dictionary<System.Object, System.Object>"/>
        /// </param>
        /// <param name="depth">
        /// A <see cref="System.Int32"/>
        /// </param>
        public void Init(Dictionary<object, object> data, int depth)
        {
            dataSource = data;
            currentIndex = -1;
            //将控件置于当前GUI元素之上,并且只在第一次调用初始化方法设置GUI深度,防止循环中重复调用
            if (!alreadyInitGuiDepth)
            {
                //guiDepth = GUI.depth - 1;
                alreadyInitGuiDepth = true;
            }
            currentDisplayText = null;
            currentValue = null;
        }
       
        /// <summary>
        /// 强行设置下拉列表是否是示 
        /// </summary>
        /// <param name="show">
        /// A <see cref="System.Boolean"/>
        /// </param>
        public void SetShowList(bool show)
        {
            if (showList)
            {
                showList = show;
            }
        }
        /// <summary>
        /// 绘制下拉列表框 
        /// </summary>
        public void Draw()
        {
            if (dataSource == null)
            {
                return;
            }
            if (currentDisplayText == null || currentValue == null)
            {
                if (dataSource.Count > 0)
                {
                    currentDisplayText = dataSource.Values.First();
                    currentValue = dataSource.Keys.First();
                    currentIndex = 0;
                }
                else
                {
                    currentDisplayText = "无";
                    currentValue = -1;
                    currentIndex = -1;
                }
            }
          
            GUILayout.BeginVertical(GUILayout.Width(WIDTH));
            GUILayout.BeginHorizontal();

            int spaceW = labelWidth;
            if (label == null || label.Equals(""))
            {
                spaceW = 0;
            }
            GUILayout.Label(label, GUILayout.Width(spaceW));

            string buttonName = "";
            if(currentDisplayText == null)
            {
                buttonName = "无";
            }else if(currentDisplayText is monster_model)
            {
                buttonName = ((monster_model)currentDisplayText).name;
            }else if(currentDisplayText is string)
            {
                buttonName = currentDisplayText.ToString();
            }
            buttonName += (showList ? "   <color=#f27272FF>></color>" : "   <color=#f27272FF>V</color>");

            if (GUILayout.Button(buttonName,GUILayout.Width(WIDTH + 20)))
            {
                showList = !showList;
                if (showList)
                {
                    showListTime = Time.time;
                }
                else
                {
                    showListTime = 0f;
                }
            }
            GUILayout.EndHorizontal();
            this.DrawList();
            GUILayout.EndVertical();
        }
        /// <summary>
        /// 绘制列表项
        /// </summary>
        public void DrawList()
        {
            if (showList == true)
            {
                //为了留出最方下的横线,这里高度减1
                GUILayout.BeginHorizontal();
                int spaceW = labelWidth;
                if (label == null || label.Equals(""))
                {
                    spaceW = 0;
                }
                GUILayout.Label("", GUILayout.Width(spaceW));

                scrollPosition = Vector2.Lerp(scrollPosition, GUILayout.BeginScrollView(scrollPosition, true, true,GUILayout.Width(WIDTH+20),GUILayout.Height(this.viewAreaHeight)), 0.5f);

                for (int i = 0; i < dataSource.Count; i++)
                {
                    drawItem(i);
                }
                GUILayout.EndScrollView();
                GUILayout.EndHorizontal();
            }
        }
        /// <summary>
        /// 绘制内容项,并响应事件 
        /// </summary>
        /// <param name="index">
        /// A <see cref="System.Int32"/>
        /// </param>
        private void drawItem(int index)
        {
            object value = dataSource.Values.ElementAt(index);
            string buttonName = value as string;
            if(value is monster_model)
            {
                buttonName = ((monster_model)value).name;
            }

            if (GUILayout.Button(buttonName,GUILayout.Width(WIDTH)))
            {
                if(value is monster_model)
                {
                    currentDisplayText = ((monster_model)value).name;
                    currentValue = dataSource.Keys.ElementAt(index);
                }
                else
                {
                    currentDisplayText = value;
                    currentValue = dataSource.Keys.ElementAt(index);
                }
                if (currentIndex != index)
                {
                    currentIndex = index;
                    if (OnSelectItemChanged != null)
                    {
                        if(value is monster_model)
                        {
                            OnSelectItemChanged(this, new SelectItemChangedArgs(currentValue, value));
                        }
                        else
                        {
                            OnSelectItemChanged(this, new SelectItemChangedArgs(currentValue, currentDisplayText));
                        }
                    }
                }
                showList = false;
            }
        }
        public void OnGUI()
        {
            GUI.depth = guiDepth;
            this.Draw();
        }
        /// <summary>
        /// 按时间比较各ComboBox控件的顺序,初衷是为了点击新的控件时,其它ComboBox控件下拉列表自动隐藏 
        /// </summary>
        public class ShowListComparer : IComparer<ComboBox>
        {
            #region IComparer[ComboBox] implementation
            int IComparer<ComboBox>.Compare(ComboBox x, ComboBox y)
            {
                return x.showListTime.CompareTo(y.showListTime) * -1;
            }
            #endregion
        }
    }

先说明一下:这个功能是在一位大神的GUI的代码基础上修改的,这样就可以自动排版了,不过已经忘了是哪位了。

posted @ 2017-03-30 20:44  yixuan1980  阅读(645)  评论(0编辑  收藏  举报