Ejemplo n.º 1
0
        /// <summary>
        /// Creates a dropdown bound to a field or property. You need to supply a collection of dropdown choices.
        /// </summary>
        public GameObject Dropdown <T>(Expression <Func <T> > memberAccessExpr,
                                       IEnumerable <IEDropdownChoice> choices,
                                       int width, int labelWidth,
                                       string label   = null,
                                       string tooltip = null
                                       )
        {
            #region Old code

            /*
             * //+ FOR REFERENCE:
             * const int nerfedXPTableWidth = 515;
             * UIDropdownMenu drop;
             * nerfedXPTableDropdown.transform.GetChild(1).GetChild(0).localScale = new Vector3(nerfedXPTableWidth, 32, 1); // width of combobox
             * nerfedXPTableDropdown.transform.GetChild(1).GetChild(3).localPosition = new Vector3(nerfedXPTableWidth - 27, 10, 0); // position of down arrow
             * nerfedXPTableDropdown.transform.GetChild(1).GetChild(2).GetChild(0).localScale = new Vector3(nerfedXPTableWidth, 37, 0); // width of dropdown
             * nerfedXPTableDropdown.transform.GetChild(1).Component<UIDropdownMenu>().OptionRootText.lineWidth = nerfedXPTableWidth;
             * nerfedXPTableDropdown.transform.GetChild(1).Component<UIDropdownMenu>().SelectedText.lineWidth = nerfedXPTableWidth;
             * nerfedXPTableDropdown.transform.GetChild(1).Component<UIDropdownMenu>().OptionGrid.cellWidth = nerfedXPTableWidth;
             * nerfedXPTableDropdown.transform.GetChild(1).Component<UIDropdownMenu>().Options = nerfedXPTableChoices;
             * //nerfedXPTableDropdown.transform.GetChild(1).Component<UIDropdownMenu>().SelectedItem = nerfedXPTableChoices[PlayerPrefs.GetInt("NerfedXPTableSetting")];
             * //nerfedXPTableDropdown.transform.GetChild(1).Component<UIDropdownMenu>().OnDropdownOptionChangedEvent += new UIDropdownMenu.DropdownOptionChanged(OnNerfedXPTableSettingChanged);
             * nerfedXPTableDropdown.transform.GetChild(0).Component<UILabel>().lineWidth = 300;
             * nerfedXPTableDropdown.transform.GetChild(0).Component<UILabel>().shrinkToFit = false;
             * nerfedXPTableDropdown.transform.GetChild(0).Component<GUIStringLabel>().DatabaseString = new GUIDatabaseString(++StringId);
             * nerfedXPTableDropdown.Component<UIOptionsTag>().TooltipString = new GUIDatabaseString(++StringId);
             * // end of adding dropdown
             */

            #endregion

            if (ExampleDropdown == null)
            {
                throw IEDebug.Exception(null, "You must initialize the ExampleDropdown to create a dropdown.", null);
            }
            var pos          = new Vector3(0, 0, 0);
            var getter       = ReflectHelper.CreateGetter(memberAccessExpr);
            var setter       = ReflectHelper.CreateSetter(memberAccessExpr);
            var asMemberExpr = (MemberExpression)memberAccessExpr.Body;
            var comboBox     = (UIOptionsTag)Object.Instantiate(ExampleDropdown);
            comboBox.transform.parent = CurrentParent;
            //+ Basic setup

            comboBox.name = asMemberExpr.Member.Name;
            //! You have to explicitly set localPosition and localScale to something after Instantiate!!!
            //! Otherwise, the UI will broken, but no exception will be reported.
            comboBox.transform.localPosition = pos;
            comboBox.transform.localScale    = new Vector3(1, 1, 1);

            var dropdown = comboBox.transform.ComponentsInDescendants <UIDropdownMenu>(true).Single();
            label   = label ?? ReflectHelper.GetLabelInfo(asMemberExpr.Member);
            tooltip = tooltip ?? ReflectHelper.GetDescriptionInfo(asMemberExpr.Member);

            //+ Set the labels
            //There are multiple things called Label in this visual tree, but only one with a GUIStringLabel component.
            var guiLabel = comboBox.transform.ComponentsInDescendants <GUIStringLabel>(true).Single();
            if (labelWidth > 0)
            {
                guiLabel.DatabaseString = IEModString.Register(label);
                var uiLabel = guiLabel.gameObject.Component <UILabel>();
                uiLabel.lineWidth = labelWidth;
            }
            else
            {
                guiLabel.DatabaseString = IEModString.Register("");
                var uiLabel = guiLabel.gameObject.Component <UILabel>();
                uiLabel.lineWidth = labelWidth;
            }

            var uiTag = comboBox.Component <UIOptionsTag>();
            uiTag.TooltipString = IEModString.Register(tooltip);

            //+ set the choices and SelectedItem
            var choicesArr = choices.ToArray();
            dropdown.Options      = choicesArr.ToArray();
            dropdown.SelectedItem = choicesArr.SingleOrDefault(x => object.Equals(x.Value, getter())) ?? dropdown.Options[0];

            //+ Set position and scale
            //To get the names, I used the GetChild calls as reference, and dumped the comboBox to the log using UnityObjectDumper.
            var comboBoxBackground = comboBox.Descendant("Background");
            comboBoxBackground.transform.localScale = new Vector3(width, 32, 1);             //this is the width of the combobox

            var arrowThing = comboBox.Descendant("ArrowPivot");
            arrowThing.transform.localPosition = new Vector3(width - 27, 10, 0);
            dropdown.OptionRootText.lineWidth  = width;
            dropdown.SelectedText.lineWidth    = width;
            dropdown.OptionGrid.cellWidth      = width;
            var optGrid = dropdown.OptionGrid;
            //+ Set the default handler that binds the control to the member
            dropdown.OnDropdownOptionChangedEvent += option => {
                var asChoice = (IEDropdownChoice)option;
                setter((T)asChoice.Value);
            };

            return(comboBox.gameObject);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a new dropdown/combo box bound to an enum-valued field or property. The enum part is important, as this is how the dropdown's options are generated. Labels are taken from attributes.
        /// </summary>
        /// <typeparam name="T">The type of the field/property. MUST be an enum type.</typeparam>
        /// <param name="enumMemberAccessExpr">A simple member access expression for accessing the property/field you want to bind this control to. For example, <c>() => IEModOptions.YourProperty</c></param>
        /// <param name="width">The width of the dropdown. You have to specify it now because setting it is complicated.</param>
        /// <param name="labelWidth">The width of the GUI label attached to the dropdown. If you set it to 0, there will be no label.</param>
        /// <param name="localPos">The transform.localPosition of the dropdown. You can set this later.</param>
        /// <returns></returns>
        public GameObject EnumBoundDropdown <T>(Expression <Func <T> > enumMemberAccessExpr, int width, int labelWidth)
            where T : struct, IConvertible, IFormattable, IComparable
        {
            /*
             *
             * //+ FOR REFERENCE:
             * const int nerfedXPTableWidth = 515;
             * UIDropdownMenu drop;
             * nerfedXPTableDropdown.transform.GetChild(1).GetChild(0).localScale = new Vector3(nerfedXPTableWidth, 32, 1); // width of combobox
             * nerfedXPTableDropdown.transform.GetChild(1).GetChild(3).localPosition = new Vector3(nerfedXPTableWidth - 27, 10, 0); // position of down arrow
             * nerfedXPTableDropdown.transform.GetChild(1).GetChild(2).GetChild(0).localScale = new Vector3(nerfedXPTableWidth, 37, 0); // width of dropdown
             * nerfedXPTableDropdown.transform.GetChild(1).GetComponent<UIDropdownMenu>().OptionRootText.lineWidth = nerfedXPTableWidth;
             * nerfedXPTableDropdown.transform.GetChild(1).GetComponent<UIDropdownMenu>().SelectedText.lineWidth = nerfedXPTableWidth;
             * nerfedXPTableDropdown.transform.GetChild(1).GetComponent<UIDropdownMenu>().OptionGrid.cellWidth = nerfedXPTableWidth;
             * nerfedXPTableDropdown.transform.GetChild(1).GetComponent<UIDropdownMenu>().Options = nerfedXPTableChoices;
             * //nerfedXPTableDropdown.transform.GetChild(1).GetComponent<UIDropdownMenu>().SelectedItem = nerfedXPTableChoices[PlayerPrefs.GetInt("NerfedXPTableSetting")];
             * //nerfedXPTableDropdown.transform.GetChild(1).GetComponent<UIDropdownMenu>().OnDropdownOptionChangedEvent += new UIDropdownMenu.DropdownOptionChanged(OnNerfedXPTableSettingChanged);
             * nerfedXPTableDropdown.transform.GetChild(0).GetComponent<UILabel>().lineWidth = 300;
             * nerfedXPTableDropdown.transform.GetChild(0).GetComponent<UILabel>().shrinkToFit = false;
             * nerfedXPTableDropdown.transform.GetChild(0).GetComponent<GUIStringLabel>().DatabaseString = new GUIDatabaseString(++StringId);
             * nerfedXPTableDropdown.GetComponent<UIOptionsTag>().TooltipString = new GUIDatabaseString(++StringId);
             * // end of adding dropdown
             */
            if (!typeof(T).IsEnum)
            {
                IEDebug.Exception(null, "Expected an enum type, but got {0}", typeof(T));
            }
            if (ExampleComboBox == null)
            {
                IEDebug.Exception(null, "You must initialize the ExampleComboBox to create a combo box.", null);
            }
            var pos          = new Vector3(0, 0, 0);
            var getter       = ReflectHelper.CreateGetter(enumMemberAccessExpr);
            var setter       = ReflectHelper.CreateSetter(enumMemberAccessExpr);
            var asMemberExpr = (MemberExpression)enumMemberAccessExpr.Body;
            var comboBox     = (GameObject)GameObject.Instantiate(ExampleComboBox);

            comboBox.transform.parent = CurrentParent;
            //+ Basic setup

            comboBox.name = asMemberExpr.Member.Name;
            //! You have to explicitly set localPosition and localScale to something after Instantiate!!!
            //! Otherwise, the UI will broken, but no exception will be reported.
            comboBox.transform.localPosition = pos;
            comboBox.transform.localScale    = new Vector3(1, 1, 1);

            var dropdown = comboBox.transform.GetComponentsInChildren <UIDropdownMenu>(true).Single();
            var label    = GetLabel(asMemberExpr.Member);
            var desc     = GetDesc(asMemberExpr.Member);

            //+ Set the labels
            //There are multiple things called Label in this visual tree, but only one with a GUIStringLabel component.
            var guiLabel = comboBox.transform.GetComponentsInChildren <GUIStringLabel>(true).Single();

            if (labelWidth > 0)
            {
                guiLabel.DatabaseString = IEModString.Register(label);
                var uiLabel = guiLabel.gameObject.GetComponent <UILabel>();
                uiLabel.lineWidth = labelWidth;
            }
            else
            {
                guiLabel.DatabaseString = IEModString.Register("");
                var uiLabel = guiLabel.gameObject.GetComponent <UILabel>();
                uiLabel.lineWidth = labelWidth;
            }

            var uiTag = comboBox.GetComponent <UIOptionsTag>();

            uiTag.TooltipString = IEModString.Register(desc);

            //+ set the choices and SelectedItem
            var choices = EnumToChoices(typeof(T));

            dropdown.Options      = choices.Cast <object>().ToArray();
            dropdown.SelectedItem = choices.SingleOrDefault(x => x.Value.Equals(getter())) ?? dropdown.Options[0];

            //+ Set position and scale
            //To get the names, I used the GetChild calls as reference, and dumped the comboBox to the log using UnityObjectDumper.
            var comboBoxBackground = comboBox.GetDescendant("Background");
            var oldWidth           = comboBoxBackground.transform.localScale.x;

            comboBoxBackground.transform.localScale = new Vector3(width, 32, 1);             //this is the width of the combobox

            var arrowThing = comboBox.GetDescendant("ArrowPivot");

            arrowThing.transform.localPosition = new Vector3(width - 27, 10, 0);

            dropdown.OptionRootText.lineWidth = width;
            dropdown.SelectedText.lineWidth   = width;
            dropdown.OptionGrid.cellWidth     = width;
            var optGrid = dropdown.OptionGrid;

            //+ Set the default handler that binds the control to the member
            dropdown.OnDropdownOptionChangedEvent += option => {
                var asChoice = (IEComboBoxChoice)option;
                setter((T)asChoice.Value);
            };

            return(comboBox);
        }